solidity中的receive()函数和fallback()函数

1、Receive Ether Function---以太币收发函数

声明方式如下:

receive() external payable {
  
}

功能:通过合约接收和转发以太币

 特点:

(1) 一个合约至多含有一个receive()函数

(2) 没有function关键字

(3) 必须含有payable关键字

(4) 没有参数,没有返回值

(5) 可见性必须声明为external

(6) 允许使用modifier修改器

(7) 该函数通过.send()和.transfer()转发以太币

(8) 若想要让你的contract(即合约账户)接收以太币,在未定义fallback() external payable{}函数时,需实现receive()函数

(9) 在gasLimit允许范围内可执行复杂操作

solidity代码示例如下:

pragma solidity >=0.6.0 <0.9.0;

contract Sink {
    event Received(address, uint);
    receive() external payable {
        emit Received(msg.sender, msg.value);
    }
}

 

2、Fallback Function---回退函数

声明方式如下:

fallback () external [payable]{

}
//或
fallback (bytes calldata input) external [payable] returns (bytes memory output){

}

 功能:当合约中没有任何匹配的函数可调用时,调用fallback()函数

特点:

(1) 一个合约至多含有一个fallback()函数

(2) 没有function关键字

(3) payable关键字是可选项,取决于该函数是否需要接收以太币

(4) 该函数可代替receive()函数以实现合约接受转发以太币的功能

(5) 可见性必须声明为external

(6) 允许使用modifier修改器

(7) 在gasLimit允许范围内可执行复杂操作

solidity代码示例如下:

pragma solidity >=0.6.2 <0.9.0;

contract Test {
    uint x;
    //该合约的fallback函数未定义为payable类型,当遇到转账操作时会发生异常
    fallback() external { 
        x = 1; 
    }
}

contract TestPayable {
    uint x;
    uint y;

    //回退函数
    fallback() external payable { 
        x = 1; 
        y = msg.value; 
    }

    //以太币收发函数
    receive() external payable { 
        x = 2; 
        y = msg.value; 
    }
}

contract Caller {
    function callTest(Test test) public returns (bool) {
        (bool success,) = address(test).call(abi.encodeWithSignature("nonExistingFunction()"));
        require(success);
        //结果为:test.x = 1.

        // address(test)无法调用.send()函数发送以太币
        //因为Test合约中不含有payable类型的fallback函数
        address payable testPayable = payable(address(test));

        return testPayable.send(2 ether);//此处返回值为false
    }

    function callTestPayable(TestPayable test) public returns (bool) {
        (bool success,) = address(test).call(abi.encodeWithSignature("nonExistingFunction()"));
        require(success);
        //结果为:test.x = 1 , test.y = 0.
        (success,) = address(test).call{value: 1}(abi.encodeWithSignature("nonExistingFunction()"));
        require(success);
        //结果为:test.x = 1 , test.y = 1.

        //此处address(test)可以调用.send()函数和.transfer()函数
        //因为TestPayable合约中有payable类型的receive()和fallback()函数
        (success,) = address(test).call{value: 2 ether}("");
        require(success);
        // 结果为:test.x = 2 , test.y = 2 .

        return true;
    }
}

 来源(solidity官方英文文档0.8.13):https://docs.soliditylang.org/en/v0.8.13/contracts.html#special-functions

 

posted @ 2022-05-07 22:31  豆豆是只乖狗狗  阅读(2351)  评论(3)    收藏  举报