在以太坊中send, transfer, call都可以进行转账操作,那么他们究竟有什么区别呢?
transfer(2300gas,如果失败则throw)
send(2300gas,如果失败则返回false)
call(默认情况下将所有可用的gas传输过去,gas传输量可调,如果失败则返回false)
接收以太币的合约必须至少具有以下功能之一:
receieve() external payable
fallback() external payable
如果发送方的msg.data为空,那么将调用receive(),否则调用fallback()。
相同之处
均是向目标地址发送以太币(以Wei为单位)
发送以太币,都需要消耗固定的2300gas(gas数量少,只允许接收方合约执行最简单的操作)
不同之处
send执行失败会返回false,不阻碍程序的运行。transfer执行失败后会抛出异常。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
contract ReceiveEther {
/*
Which function is called, fallback() or receive()?
send Ether
|
msg.data is empty?
/ \
yes no
/ \
receive() exists? fallback()
/ \
yes no
/ \
receive() fallback()
*/
// Function to receive Ether. msg.data must be empty
receive() external payable {}
// Fallback function is called when msg.data is not empty
fallback() external payable {}
function getBalance() public view returns (uint) {
return address(this).balance;
}
}
contract SendEther {
function sendViaTransfer(address payable _to) public payable {
// This function is no longer recommended for sending Ether.
_to.transfer(msg.value);
}
function sendViaSend(address payable _to) public payable {
// Send returns a boolean value indicating success or failure.
// This function is not recommended for sending Ether.
bool sent = _to.send(msg.value);
require(sent, "Failed to send Ether");
}
function sendViaCall(address payable _to) public payable {
// Call returns a boolean value indicating success or failure.
// This is the current recommended method to use.
(bool sent, bytes memory data) = _to.call{value: msg.value}("");
require(sent, "Failed to send Ether");
}
}
参考资料
