Solidity智能合约开发 — 3.2-合约的fallback和函数重载

1.fallback 函数

每个智能合约有且仅有一个未命名的函数,称为fallback函数,没有参数且没有返回值,可见性必须是 external,且可以是 virtual的(即可以被重载),也可以有修改器 modifier。

fallback执行条件:

  1. 如果在一个合约的调用中,没有其他函数与给定的函数标识符匹配时(或没有提供调用数据),fallback函数会被执行;
  2. 当合约收到以太时,fallback函数会被执行。

执行条件1:如果在一个合约的调用中,没有其他函数与给定的函数标识符匹配时(或没有提供调用数据),fallback函数会被执行

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
 
//基合约实现
contract TestFallback {
    string message;
 
    //构造函数,初始化状态变量message
    constructor() {
        message = "hello";
    }
 
    fallback() external {
        message = "fallback"; 
    }
 
    //调用此合约中不存在的函数
    function testFallback() external returns (bytes memory) {
 
        // 调用不存在的函数getMsgNew()
        bytes memory method = abi.encodeWithSignature("getMsgNew()");
        (bool success, bytes memory returnData) = address(this).call(method);
 
        require(success, "get fail");
        return returnData;
    }
 
    //调用此合约中已存在函数,但是没有传递参数
    function testFallbackWithNoParam() external returns (bytes memory) {
 
        // 调用已存在的函数setMsg(),未传递参数
        bytes memory method = abi.encodeWithSignature("setMsg()");
        (bool success, bytes memory returnData) = address(this).call(method);
 
        require(success, "set fail");
        return returnData;
    }
 
    function getMsg() external view returns (string memory) {
        return message;
    }
 
    function setMsg(string memory _message) external {
        message = _message;
    }
}

上面状态,查看状态变量已修改fallback函数中设置的"fallback"了

执行条件2:当合约收到以太时,fallback函数会被执行,为了接收以太,fallback 函数必须标记为 payable。 如果不存在这样的函数(如下代码片段),则合约不能通过常规交易接收以太。

fallback() external payable {
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
 
// 包含fallback函数的合约,合约账户能够接收到其它合约转的以太
contract TestFallback {
    string message;
 
    //构造函数,初始化状态变量message,同时可向合约账户存款
    constructor() payable {
        message = "hello";
    }
 
    //回退函数,能够为此合约账户接收以太
    fallback() external payable {
    }
 
    //存款,若部署时忘记存款,可直接调用此函数向合约账户存款
    function deposit() external payable {
    }
 
    //发送以太
    function sendEther(address _addr) external {
        bool result = payable(_addr).send(2);
        require(result, "send fail");
    }
    
    //查看合约账户余额
    function getContractBalance() external view returns (uint256) {
        return address(this).balance;
    }
}
 
// 不包含fallback函数的合约
contract TestWithoutFallback {
 
    //构造函数,初始化时可向合约账户存款
    constructor() payable{
    }
 
    //存款,若部署时忘记存款,可直接调用此函数向合约账户存款
    function deposit() external payable {
    }
 
    //发送以太
    function sendEther(address _addr) external returns (bool) {
        bool result = payable(_addr).send(2);
        return result;
    }
 
    //查看合约账户余额
    function getContractBalance() external view returns (uint256) {
        return address(this).balance;
    }
}

使用未含fallback合约函数向有fallback合约发送以太(转账成功), 使用含fallback合约函数向未含fallback合约发送以太(转账失败)

 2. 函数重载

智能合约可以具有多个不同参数(类型,数量)的同名函数。这也使用于继承函数。

pragma solidity ^0.4.16

contract A{
     //  fun1编译有问题
    function fun1() returns(uint){
        
    }
    function fun1() returns(string){
        
    }
    
    
    //  fun2编译没问题
    function fun2(uint name){
        
    }
    function fun2(){
        
    }
    
    //  fun3编译没问题
    function fun3(uint name){
        
    }
    function fun3(uint8 name){
        
    }

}

需要注意的是,返回参数不作为重载解析的依据。

你可能感兴趣的:(web3.0安全,智能合约)