• Solidity 小白教程:20. 发送 ETH


    Solidity 小白教程:20. 发送 ETH

    Solidity有三种方法向其他合约发送ETH,他们是:transfer()send()call(),其中**call()**是被鼓励的用法。

    接收 ETH 合约

    我们先部署一个接收ETH合约ReceiveETHReceiveETH合约里有一个事件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;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    部署ReceiveETH合约后,运行getBalance()函数,可以看到当前合约的ETH余额为0
    image.png

    发送 ETH 合约

    我们将实现三种方法向ReceiveETH合约发送ETH。首先,先在发送 ETH 合约SendETH中实现payable构造函数receive(),让我们能够在部署时和部署后向合约转账。

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

    transfer

    • 用法是接收方地址.transfer(发送 ETH 数额)
    • transfer()gas限制是2300,足够用于转账,但对方合约的**fallback()receive()**函数不能实现太复杂的逻辑。
    • transfer()如果转账失败,会自动revert(回滚交易)。

    代码样例,注意里面的**_toReceiveETH合约的地址,amountETH**转账金额:

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

    部署SendETH合约后,对ReceiveETH合约发送 ETH,此时amount为 10,value为 0,amount>value,转账失败,发生revert
    image.png
    此时amount为 10,value为 10,amount<=value,转账成功。
    image.png
    ReceiveETH合约中,运行getBalance()函数,可以看到当前合约的ETH余额为10
    image.png

    send

    • 用法是接收方地址.send(发送 ETH 数额)
    • send()gas限制是2300,足够用于转账,但对方合约的**fallback()receive()**函数不能实现太复杂的逻辑。
    • send()如果转账失败,不会revert
    • send()的返回值是bool,代表着转账成功或失败,需要额外代码处理一下。

    代码样例:

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

    ReceiveETH合约发送 ETH,此时amount为 10,value为 0,amount>value,转账失败,因为经过处理,所以发生revert
    image.png
    此时amount为 10,value为 11,amount<=value,转账成功。
    image.png

    call

    • 用法是接收方地址.call{value: 发送 ETH 数额}(“”)
    • call()没有gas限制,可以支持对方合约**fallback()receive()**函数实现复杂逻辑。
    • call()如果转账失败,不会revert
    • call()的返回值是(bool, data),其中bool代表着转账成功或失败,需要额外代码处理一下。

    代码样例:

    // call()发送ETH
    function callETH(address payable _to, uint256 amount) external payable{
        // 处理下call的返回值,如果失败,revert交易并发送error
        (bool success,) = _to.call{value: amount}("");
        if(!success){
            revert CallFailed();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    ReceiveETH合约发送 ETH,此时amount为 10,value为 0,amount>value,转账失败,因为经过处理,所以发生revert
    image.png
    此时amount为 10,value为 11,amount<=value,转账成功。
    image.png
    运行三种方法,可以看到,他们都可以成功地向ReceiveETH合约发送ETH

    总结

    这一讲,我们介绍solidity三种发送ETH的方法:transfersendcall

    • call没有gas限制,最为灵活,是最提倡的方法;
    • transfer2300 gas限制,但是发送失败会自动revert交易,是次优选择;
    • send2300 gas限制,而且发送失败不会自动revert交易,几乎没有人用它。
  • 相关阅读:
    uniapp微信登陆
    Ai语音机器人系统语音识别达到了什么水准
    基于GA遗传优化的新能源充电桩最优布局matlab仿真
    1000 + Java 面试题,26,Javaweb基础知识点
    LabVIEW如何获取波形图上游标所在位置的数值
    Ubuntu16.04 完整版 Gym 安装及说明
    java计算机毕业设计web扶贫产品物资管理平台MyBatis+系统+LW文档+源码+调试部署
    python基本知识-第一周
    Maya制作骑自行车的女孩模型
    Linux文件权限解析:从入门到实践
  • 原文地址:https://blog.csdn.net/weixin_52148451/article/details/132849628