【Solidity】Payable 支付

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

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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// 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{ //官方不推荐 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{
    
    //官方不推荐
    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");
    }
}

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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// 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");
}
}
// 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"); } }
// 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评论