# 合约调用合约的三种方式 **Published by:** [fiveeth](https://paragraph.com/@fiveeth/) **Published on:** 2022-05-20 **URL:** https://paragraph.com/@fiveeth/QkTEh0IteuCEq4Pzpdwh ## Content 第一种:接口形式调用合约 为什么采用这种方式? 原因是因为被调用合约过于复杂的时候,全引入进来的话没有必要! 被调用合约: // 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"); } } ## Publication Information - [fiveeth](https://paragraph.com/@fiveeth/): Publication homepage - [All Posts](https://paragraph.com/@fiveeth/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@fiveeth): Subscribe to updates