发送以太币(transfer、send、call)

发送以太币(transfer、send、call)

在以太坊中send, transfer, call都可以进行转账操作,那么他们究竟有什么区别呢?

那么如何发送以太币呢?

  • transfer(2300gas,如果失败则throw)

  • send(2300gas,如果失败则返回false)

  • call(默认情况下将所有可用的gas传输过去,gas传输量可调,如果失败则返回false)

如何接收以太币?

接收以太币的合约必须至少具有以下功能之一:

  • receieve() external payable

  • fallback() external payable

如果发送方的msg.data为空,那么将调用receive(),否则调用fallback()。

send与transfer对比简析

相同之处

  1. 均是向目标地址发送以太币(以Wei为单位)

  2. 发送以太币,都需要消耗固定的2300gas(gas数量少,只允许接收方合约执行最简单的操作)

不同之处

  1. 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");
    }
}

参考资料

Solidity by Example v 0.8.10

细究以太坊中send/transfer/call/delegatecall