【Solidity】fallback和receive的用法
这两个是回调function,Solidity支持两种特殊的回调函数,receive()和fallback(),他们主要在两种情况下被使用:
- 接收ETH
- 处理合约中不存在的函数调用(代理合约proxy contract)
receive和fallback的区别
receive和fallback都能够用于接收ETH,他们触发的规则如下:

简单来说,合约接收ETH时,msg.data为空且存在receive()时,会触发receive();msg.data不为空或不存在receive()时,会触发fallback(),此时fallback()必须为payable。
receive()和payable fallback()均不存在的时候,向合约发送ETH将会报错。
代码范例
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract Receiver{
    event Received(address caller,uint amount,string message);
    event Foo(string message);
    fallback() external payable{
        emit Received(msg.sender, msg.value,"fallback was called");
    }
    receive() external payable{
        emit Received(msg.sender, msg.value,"receive was called");
    }
    function foo(string calldata message) public returns(string memory){
        emit Foo(message);
        return message;
    }
    function getBalance() public view returns(uint){
        return address(this).balance;
    }
}
contract Caller{
    event Response(bool success, bytes data);
    //付款将会回调receive
    function triggerReceive(address contractAddress)public payable{
        (bool success, bytes memory data) = contractAddress.call{value:msg.value, gas:5000}("");
        emit Response(success,data);
    }
    //foo function是纯在的,所以不会回调fallback
    function triggerFoo(address contractAddress,string calldata message)public payable{
        (bool success, bytes memory data) = contractAddress.call(
            abi.encodeWithSignature("foo(string)",message)
        );
        emit Response(success,data);
    }
    //由于function不存在所以去回调fallback
    function testCallDoesNotExist(address _addr) public {
        (bool success, bytes memory data) = _addr.call(
            abi.encodeWithSignature("doesNotExist()")
        );
        emit Response(success, data);
    }
}
结果1:触发triggerReceive,往receiver发送eth,由于call msg是空值,所以response log内data是0x,也就是空值

结果2:触发testCallDoesNotExist,由于receiver合约内不存在doesNotExist function,所以就会回调fallback

结果3:触发triggerFoo,由于receiver当中这function存在,所有并不会回调fallback

 
		Facebook评论