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;
}
}
部署ReceiveETH合约后,运行getBalance()函数,可以看到当前合约的ETH余额为0。
我们将实现三种方法向ReceiveETH合约发送ETH。首先,先在发送 ETH 合约SendETH中实现payable的构造函数和receive(),让我们能够在部署时和部署后向合约转账。
contract SendETH {
// 构造函数,payable使得部署的时候可以转eth进去
constructor() payable{}
// receive方法,接收eth时被触发
receive() external payable{}
}
代码样例,注意里面的**_to填ReceiveETH合约的地址,amount是ETH**转账金额:
// 用transfer()发送ETH
function transferETH(address payable _to, uint256 amount) external payable{
_to.transfer(amount);
}
部署SendETH合约后,对ReceiveETH合约发送 ETH,此时amount为 10,value为 0,amount>value,转账失败,发生revert。
此时amount为 10,value为 10,amount<=value,转账成功。
在ReceiveETH合约中,运行getBalance()函数,可以看到当前合约的ETH余额为10。
代码样例:
// send()发送ETH
function sendETH(address payable _to, uint256 amount) external payable{
// 处理下send的返回值,如果失败,revert交易并发送error
bool success = _to.send(amount);
if(!success){
revert SendFailed();
}
}
对ReceiveETH合约发送 ETH,此时amount为 10,value为 0,amount>value,转账失败,因为经过处理,所以发生revert。
此时amount为 10,value为 11,amount<=value,转账成功。
代码样例:
// 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,此时amount为 10,value为 0,amount>value,转账失败,因为经过处理,所以发生revert。
此时amount为 10,value为 11,amount<=value,转账成功。
运行三种方法,可以看到,他们都可以成功地向ReceiveETH合约发送ETH。
这一讲,我们介绍solidity三种发送ETH的方法:transfer,send和call。