我最近在重新学solidity,巩固一下细节,也写一个“Solidity极简入门”,供小白们使用(编程大佬可以另找教程),每周更新1-3讲。
欢迎关注我的推特:@0xAA_Science
WTF技术社群discord,内有加微信群方法:链接
所有代码和教程开源在github(1024个star发课程认证,2048个star发社群NFT): github.com/AmazingAng/WTFSolidity
Solidity
有三种方法向其他合约发送ETH
,他们是:transfer()
,send()
和call()
,其中call()
是被鼓励的用法。
我们先部署一个接收ETH
合约ReceiveETH
。ReceiveETH
合约里有一个事件Log
,记录收到的ETH
数量和gas
剩余。还有两个函数,一个是receive()
,收到ETH
被触发,并发送Log
事件;另一个是查询合约ETH
余额的getBalance()
.
contract ReceiveETH {
// 收到eth事件,记录amount和gas
event Log(uint amount, uint gas);
// receive方法,接收eth时被触发
receive() external payable{
emit Log(msg.value, gasleft());
}
// 返回合约ETH余额
function getBalance() view public returns(uint) {
return address(this).balance;
}
}
部署好合约后,运行getBalance()
函数,可以看到当前合约的ETH
余额为0
.
我们将实现三种方法向ReceiveETH
合约发送ETH
。首先,先在发送ETH合约SendETH
中实现payable
的构造函数
和receive()
,让我们能够在部署时和部署后向合约转账。
contract SendETH {
// 构造函数,payable使得部署的时候可以转eth进去
constructor() payable{}
// receive方法,接收eth时被触发
receive() external payable{}
transfer(发送ETH数额)
。transfer()
的gas
限制是2300
,足够用于转账,但对方合约的fallback()
或receive()
函数不能实现太复杂的逻辑。transfer()
如果转账失败,会自动revert
(回滚交易)。代码样例,注意参数中的_to
填ReceiveETH
合约的地址,amount
是ETH
转账金额:
// 用transfer()发送ETH
function transferETH(address payable _to, uint256 amount) external payable{
_to.transfer(amount);
}
send(发送ETH数额)
。send()
的gas
限制是2300
,足够用于转账,但对方合约的fallback()
或receive()
函数不能实现太复杂的逻辑。send()
如果转账失败,不会revert
。send()
的返回值是bool
,代表着转账成功或失败,需要额外代码处理一下。代码样例:
// send()发送ETH
function sendETH(address payable _to, uint256 amount) external payable{
// 处理下send的返回值,如果失败,revert交易并发送error
bool success = _to.send(amount);
if(!success){
revert SendFailed();
}
}
call{value: 发送ETH数额}("")
。call()
没有gas
限制,可以支持对方合约fallback()
或receive()
函数实现复杂逻辑。call()
如果转账失败,不会revert
。call()
的返回值是(bool, data)
,其中bool
代表着转账成功或失败,需要额外代码处理一下。代码样例:
// call()发送ETH
function callETH(address payable _to, uint256 amount) external payable{
// 处理下call的返回值,如果失败,revert交易并发送error
(bool success,) = _to.call{value: amount}("");
if(!success){
revert CallFailed();
}
}
运行三种方法,可以看到,他们都可以成功的向ReceiveETH
合约发送ETH
。
这一讲,我们介绍solidity
三种发送ETH
的方法:transfer
,send
和call
。
call
没有gas
限制,最为灵活,是最提倡的方法;transfer
有2300 gas
限制,但是发送失败会自动revert
交易,是次优选择;send
有2300 gas
限制,而且发送失败不会自动revert
交易,几乎没有人用它。