回退函数是智能合约的特殊函数,没有名字、没有参数、没有返回值。
一个简单的回退函数
1 2 3 4 5 6
| pragma solidity ^0.4.0; contract simplefallback{ function(){
} }
|
何时调用回退函数
合约调用未匹配函数签名
当程序找不到要调用的函数的时候就会调用默认的回退函数,但是 solidity 提供了编译器检查机制,不能直接通过 solidity 调用一个不存在的函数,所以我们通过 solidity 提供的底层函数 address.call() 来模拟一下
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
| pragma solidity ^0.4.24; contract ExecuteFallback{ event FallbackCalled(bytes data); function() public{ emit FallbackCalled(msg.data); } event ExistFuncCalled(bytes data, uint256 para); function existFunc(uint256 para) public { emit ExistFuncCalled(msg.data, para); } function callExistFunc() public returns(bool){ bytes4 funcIdentifier = bytes4(keccak256("existFunc(uint256)")); return address(this).call(funcIdentifier, uint256(1)); } function callNonExistFunc() public returns(bool){ bytes4 funcIdentifier = bytes4(keccak256("functionNotExist()")); return address(this).call(funcIdentifier); } }
|
点击 callExistFunc 会看到
这次点击 callNonExistFunc 看到对这次事件的描述是:”event”: “FallbackCalled”,而且要注意,这里 call 的返回值也为 true
一个没有定义一个回退函数的合约。如果接收 ether,会触发异常,并返还 ether(solidity v0.4.0 开始)。所以合约要接收 ether,必须实现回退函数
合约调用未包含任何数据
当我们使用 address.send(ether to send) 函数向某个合约直接转账的时候,因为这个行为没有发送数据,所以也会调用 fallback 函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| pragma solidity ^0.4.24; contract SendFallback{ event FallbackTrigged(bytes data); function() public payable{ emit FallbackTrigged(msg.data); } function deposit() public payable{ } function getBalance() public view returns(uint){ return address(this).balance; } event SendEvent(address to, uint value, bool result); function sendEther() public{ bool result = address(this).send(1); emit SendEvent(this, 1, result); } }
|
先给合约一些钱
最后更新时间: