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

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

声明方式如下:

1
2
3
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代码示例如下:

1
2
3
4
5
6
7
8
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---回退函数

声明方式如下:

1
2
3
4
5
6
7
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代码示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
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 @   豆豆是只乖狗狗  阅读(2286)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示