Bernau
川
7.15-8.24学习记录日记
几个方向
ABI
(Address)
插槽(Slot)
Gas 交易费用
数据结构
事件(Event)
升级合约
签名/钱包
ERC-6551
跨链 | ChainLink
EVM
IPFS
DEFI
ERC-20/ERC-721
功能模块
项目与应用
MetaMask
ChatGPT 实践
7.15日记录
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract A {
event Message(uint256 num, string message);
event Response(bool success, bytes data);
function getBFunctionBytes4() public pure returns (bytes4) {
return bytes4(keccak256("bFunction(uint256,string)"));
}
function getParamsBytes(uint256 _num, string calldata _message)
public
pure
returns (bytes memory)
{
return abi.encode(_num, _message);
}
function callBFuncton(address _bAddress, bytes calldata _data)
public
returns (bool)
{
(bool success, ) = _bAddress.call(_data);
return success;
}
function callBFuncton(
address _bAddress,
uint256 _num,
string memory _message
) public returns (bool) {
bytes4 sig = bytes4(keccak256("bFunction(uint256,string)"));
/**
//1、encodeWithSignature
(bool success, ) = _bAddress.call(
abi.encodeWithSignature("bFunction(uint256,string)", _num,_message)
);
*/
/*
//2、encodePacked
bytes memory _bNum = abi.encode(_num);
bytes memory _bMessage = abi.encode(_message);
(bool success, ) = _bAddress.call(
abi.encodePacked(sig, _bNum,_bMessage)
);
*/
//3、encodeWithSelector
(bool success, bytes memory data) = _bAddress.call(
abi.encodeWithSelector(sig, _num, _message)
);
emit Response(success, data);
/*
//4、instance.callfunction
B bContract = B(_bAddress);
(uint256 num ,string memory message) = bContract.bFunction(_num,_message);
emit Message(num ,message);
*/
return true;
}
}
contract B {
uint256 public num;
string public message;
function bFunction(uint256 _num, string memory _message)
public
returns (uint256, string memory)
{
num = _num;
message = _message;
return (num, message);
}
fallback() external {}
}
7.16日记录
【Solidity进阶系列】 | ABI | 使用Encodepacked方法注意事项
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract A {
function callBFuncton(address _bAddress, uint256 _num,address _message) public returns(bool){
//2、encodePacked
bytes4 sig = bytes4(keccak256("bFunction(uint256,address)"));
bytes memory _bNum = abi.encode(_num);
bytes memory _bMessage = abi.encode(_message);
(bool success, ) = _bAddress.call(
abi.encodePacked(sig, _bNum,_bMessage)
);
return success;
}
function encode(string memory _message) public pure returns(bytes memory message){
return abi.encode(uint256(1), _message,"world");
}
function encodePacked(string memory _message) public pure returns(bytes memory message){
return abi.encodePacked(uint256(1),abi.encode(_message),abi.encode("world"));
}
function encodePacked() public pure returns(bytes memory message){
return abi.encodePacked(uint256(1),"hellow","orld");
}
}
contract B {
uint256 public num;
address public message;
event ReceiveMessage(uint256 num,address message);
function bFunction(uint256 _num, address _message) public returns(uint256 ,address ){
emit ReceiveMessage(_num,_message);
num = _num;
message = _message;
return (num, message);
}
}
使用abi.encodepacked 不要传两个字符串,(字符串 数组 字节),否则会出现穿的字符串不一样但是输出结果一样,可以传整型+字符串
传入整型+地址 可以完成A合约调用B合约方法
传入的字符串就会导致A调用B合约 但是输出的是空的
7.17日记
今天测试同区块自定义金额开盘买入脚本
7.18日记录
Address | Call 方法
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import "hardhat/console.sol";
contract CallExample {
//address payable 拥有transfer方法
function transfer(address payable _to) public payable {
_to.transfer(msg.value);
}
//address payable 拥有send方法
function send(address payable _to) public payable {
bool isSend = _to.send(msg.value);
require(isSend, "Send fail");
}
//address不需要payable修改,都可以调用Call方法
//_to如果是合约地址,必须在_to合约里面添加 receive或fallback方法。
//为什么要这么做呢?如果把ETH转到不能提现的合约,那么该ETH就永久消失
function call(address _to) public payable {
(bool sent, ) = _to.call{value: msg.value}("");
require(sent, "Send fail");
}
//_to是EOA钱包地址,("") calldata将被忽略掉
function callWithData(address _to) public payable {
(bool sent, ) = _to.call{value: msg.value}(abi.encodeWithSignature("increaseNumber(uint256)", 10));
require(sent, "Send fail");
}
}
contract ReceiveEther {
receive() external payable {}
fallback() external payable{}
function increaseNumber(uint256 num) public pure returns (uint256) {
return ++num;
}
}
由合约contract CallExample 中调用call方法传入1ether传到合约contract ReceiveEther中可以成功,因为该合约中写了receive()或者fallback() 方法,不写的话 用call方法不可传入,下图是传入成功案例和失败案例
其次用tranfer方法给钱包地址或者合约地址转账时,要给地址address 加payable修饰符,不然没办法调用此功能