Skip to content

合约调用合约

我们希望合约A能够被合约B所调用。

合约A,Storage.sol

solidity
// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.8.2 <0.9.0;

/**
 * @title Storage
 * @dev Store & retrieve value in a variable
 */
contract Storage {
    uint256 number;

    /**
     * @dev Store value in variable
     * @param num value to store
     */
    function store(uint256 num) public {
        number = num;
    }

    /**
     * @dev Return value 
     * @return value of 'number'
     */
    function retrieve() public view returns (uint256){
        return number;
    }
}

方式一:通过interface

合约B,StorageCaller.sol

solidity
// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.8.2 <0.9.0;

interface Storage {
    function store(uint256 num) external;

    function retrieve() external view returns (uint256);
}

contract StorageCaller {
    Storage storage_contract;

    constructor(address StorageAddress) {
        storage_contract = Storage(StorageAddress);
    }

    function Store(uint256 num) public {
        storage_contract.store(num);
    }

    function Retrieve() public view returns (uint256) {
        return storage_contract.retrieve();
    }
}

如此,通过interface的方式即可实现合约B对合约A的调用。

方式二:通过call

合约B,StorageCaller2.sol

solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.2 <0.9.0;

contract StorageCaller2 {
    address storage_contract_addr;

    constructor(address StorageAddress) {
        storage_contract_addr = StorageAddress;
    }

    function Store(uint256 num) public {
        (bool success, ) = storage_contract_addr.call(
            abi.encodeWithSignature("store(uint256)", num)
        );
        require(success, "Call to store function failed");
    }

    function Retrieve() public view returns (uint256) {
        (bool success, bytes memory data) = storage_contract_addr.staticcall(
            abi.encodeWithSignature("retrieve()")
        );
        require(success, "Call to retrieve function failed");
        return abi.decode(data, (uint256));
    }
}