【Solidity】Payable 支付

使用支付有3种function可以用,分别是send / transfer / call。由于为了防止reentrancy攻击所以send和tranfer限制在2300 gas。所以有些合约如果使用超过2300gas就会造成交易失败,非常不方便。所以官方在2019年开始推荐大家使用call function来操作支付。

– send 就是支付,返回bool来得知成功或失败
– transfer就是支付,如果失败的话就会直接revert报错

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

contract test{
    
    //官方不推荐
    function sendMoney(address payable _to) public payable {

        // 传进来的_to不是发送地址,而且接收地址
        // msg.value是合约调用者所输入的转账数额
        bool isSend = _to.send(msg.value);
        require(isSend,"send failed");//转账失败的话将会报错send failed信息
    }

    //官方不推荐
    function transferMoney(address payable _to) public payable {
        _to.transfer(msg.value);// 无需另加判断,有错误的话就直接throw了
    }

    //官方推荐使用
    function callMoney(address payable _to) public payable {
        (bool isSend,) =_to.call{value: msg.value}("");
        require(isSend,"send failed");
    }
}

以下的代码范例,让你更了解转账的使用方式

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

contract test{
    address payable public immutable payableOwnerAddress;

    constructor(){
        //初始化合约,把作者的地址给declare
        payableOwnerAddress = payable(msg.sender);
    }

    function depositMoney()public payable{
        //让外部允许把钱存入本合约
    }

    function getContactBalance() public view returns(uint){
        //查看本合约的余额
        return address(this).balance;
    }

    function getAllMoneyFromContactToOwner() public payable {
        //把合约内的余额全都赚去给合约的作者
        (bool isSend,) = payableOwnerAddress.call{value: getContactBalance()}("");
        require(isSend,"send failed");
    }

    function depositMoneyToOwner()public payable{
        //让外部允许把钱,通过本合约直接转账给作者
        (bool isSend,) = payableOwnerAddress.call{value: msg.value}("");
        require(isSend,"send failed");
    }
}

Loading

Facebook评论