合约调用合约的三种方式

第一种:接口形式调用合约

为什么采用这种方式?

原因是因为被调用合约过于复杂的时候,全引入进来的话没有必要!

被调用合约:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Counter {
    uint public count;

    function inc() external  {
       count += 1;
    }

    function dec() external {
        count -= 1;
    }
}

调用合约:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// 这个接口名称叫什么不重要,规范建议首字母大写
interface ICounter {
    function count() external view returns(uint);
    function inc() external;
}

contract Interface {
    uint public count;
    
    // _counter为被调用合约的地址
    function examples(address _counter) external {
        ICounter(_counter).inc();
        count = ICounter(_counter).count();
    }
}

第二种:直接引入形式调用合约

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract CallOtherContract {
    // 第一种方式
    // function setX(address _test, uint _x) external {
    //     TestContract(_test).setX(_x);
    // }

    // 第二种方式
    function setX(TestContract _test, uint _x) external {
        _test.setX(_x);
    }

    function getX(address _test) external view returns(uint) {
        return TestContract(_test).getX();
    }

    function setXandSendEth(address _test, uint _x) external payable{
        TestContract(_test).setXandSendEth{value: msg.value} (_x);
    }

    function getXandSendEth(address _test) external view returns(uint x, uint value) {
        (x, value) = TestContract(_test).getXandSendEth();
    }
}

contract TestContract {
    uint public x;
    uint public value;

    function setX(uint _x) public {
        x = _x;
    }

    function getX() public view returns(uint) {
        return x;
    }

    function setXandSendEth(uint _x) public payable {
        x = _x;
        value = msg.value;
    }

    function getXandSendEth() public view returns(uint,uint) {
        return (x, value);
    }
}

第三种:call形式调用合约(注意问题)

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract TestCall {
    string public message;
    uint public x;

    event Log(string message);

    fallback() external payable {
        emit Log("fallback called");
    }

    function foo(string memory _message, uint _x) external payable returns(bool, uint) {
        message = _message;
        x = _x;
        return (true, 999);
    }
}


contract Call {
    bytes public data;

    function callFoo(address _test) external payable {
        (bool _status, bytes memory _data) = _test.call{value: 100}(abi.encodeWithSignature(
            "foo(string,uint256)", "call", 10));  // "foo(string,uint256)"这块参数类型之间一定不能有空格
        require(_status, "call failed");
        data = _data;
    }

    function callOther(address _test) external {
        (bool _status, ) = _test.call(abi.encodeWithSignature(
            "callOther()"));
        require(_status, "callOther failed");
    }
}