发送ETH 3 种方式
transfer
- 如果异常会转账失败,抛出异常
- 有gas限制,最大2300
send
- 如果异常会转账失败,仅会返回false,不会终止执行
- 有gas限制,最大2300
call
- 如果异常会转账失败,仅会返回false,不会终止执行
- 没有gas限制
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract TestAddress {
event Log(string func, uint gas);
// 回退函数必须声明为外部函数。
fallback() external payable {
// send / transfer ( 超出 2300 gas)会进入这里
// call 用光所有 gas 会进入这里
emit Log("fallback", gasleft());
}
// msg.data 为空时进入这里
receive() external payable {
emit Log("receive", gasleft());
}
// Helper function to check the balance of this contract
function getBalance() public view returns (uint) {
return address(this).balance;
}
//与其他机器语言相区别的类型就是这个address 类型,160-bit/20byte
address public addr = 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4;
//合约自己的地址
address myAddress = address(this);
//跟普通的地址类型一样,但多了两个方法 transfer/send
address payable sender =
payable(0x5B38Da6a701c568545dCfcB03FcB875f56beddC4);
//可以使用 balance 属性来查询一个地址的余额
function getBalance(address _sender) public view returns(uint) {
return _sender.balance;
}
// transfer 无返回值
function testTransfer(address payable _to) public payable {
_to.transfer(msg.value);
}
// send 是 transfer 的低级版本。如果执行失败,当前的合约不会因为异常而终止,
// 但 send 会返回 false。
function testSend(address payable _to) public payable returns (bool) {
return _to.send(msg.value);
}
// 返回一个bool 和一个 bytes
function testCall(address payable _to) public payable returns (bytes memory) {
(bool sent, bytes memory data) = _to.call{value: msg.value}("");
return data;
}
}
Solidity receive和fallback的执行逻辑
这一讲,我们介绍solidity三种发送ETH的方法:transfer,send和call。
- call没有gas限制,最为灵活,是最提倡的方法;
- transfer有2300 gas限制,但是发送失败会自动revert交易,是次优选择;
- send有2300 gas限制,而且发送失败不会自动revert交易,几乎没有人用它。