Skip to content

Latest commit

 

History

History
91 lines (71 loc) · 2.83 KB

File metadata and controls

91 lines (71 loc) · 2.83 KB

20. 發送 ETH

Solidity有三種方法向其他合約發送ETH,他們是

  • transfer()
  • send()
  • call(),(被鼓勵的用法)

接收ETH

  • 先部署一個接收ETH合約ReceiveETH。
  • ReceiveETH合約裡有一個事件Log,記錄收到的ETH數量和gas剩餘。
  • 還有兩個函數,一個是receive()函數,收到ETH被觸發,並發送Log事件;另一個是查詢合約ETH餘額的getBalance()函數。
send
  • 用法是接收方地址.send(发送ETH数额)。
  • send()的gas限制是2300,足夠用於轉賬,但對方合約的fallback()或receive()函數不能實現太複雜的邏輯。
  • send()如果轉帳失敗,不會revert。
  • send()的回傳值是bool,代表著轉帳成功或失敗,需要額外程式碼處理一下。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.21;

// 3种方法发送ETH
// transfer: 2300 gas, revert
// send: 2300 gas, return bool
// call: all gas, return (bool, data)

error SendFailed(); // 用send发送ETH失败error
error CallFailed(); // 用call发送ETH失败error

contract SendETH {
    // 构造函数,payable使得部署的时候可以转eth进去
    constructor() payable{}
    // receive方法,接收eth时被触发
    receive() external payable{}

    // 用transfer()发送ETH
    function transferETH(address payable _to, uint256 amount) external payable{
        _to.transfer(amount);
    }

    // send()发送ETH
    function sendETH(address payable _to, uint256 amount) external payable{
        // 处理下send的返回值,如果失败,revert交易并发送error
        bool success = _to.send(amount);
        if(!success){
            revert SendFailed();
        }
    }

    // call()发送ETH
    function callETH(address payable _to, uint256 amount) external payable{
        // 处理下call的返回值,如果失败,revert交易并发送error
        (bool success,) = _to.call{value: amount}("");
        if(!success){
            revert CallFailed();
        }
    }
    // 新增函数来检查指定地址的以太币余额
    function checkBalance(address _addr) external view returns (uint256) {
        return _addr.balance;
    }
}

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;
    }
}
總結:
  • call沒有gas限制,最靈活,是最提倡的方法;
  • transfer有2300 gas限制,但是發送失敗會自動revert交易,是次優選擇;
  • send有2300 gas限制,而且發送失敗不會自動revert交易,幾乎沒有人使用它。
  • 不管成功或失敗都會有 gas消耗,所以要小心使用。