动态调用外部合同

时间:2017-03-30 00:32:19

标签: blockchain ethereum solidity

我正在努力使合约具有能够调用另一个合同的功能的功能。我的目标的关键部分是合同不应该在没有任何import语句的情况下部署,并且默认情况下不会知道合同的名称。换句话说,该合同的用户将输入被叫合同数据(即地址,名称)作为参数。实现这一目标的最佳方法是什么?

2 个答案:

答案 0 :(得分:7)

不确定为什么会被投票。

如果我正确理解了问题,您希望在不知道必须与之通信的合同的具体细节的情况下部署合同。

您可以通过假设其接口知识来大大简化这一过程。

您可以在不导入合同代码的情况下定义接口。定义函数接口并将函数定义留空:

contract WidgetInterface {

   function doSomething() returns(uint) {}
   function somethingElse() returns(bool isTrue) {}

}

使用该接口合同与实际合同交谈:

WidgetInterface w = WidgetInterface(actualContractAddress);

在我看来通常可以并且建议您随时注册授权/有效合同。按照这些方针维护一份可安全交谈的合同清单:

if(!isAuthorized(actualContractAddress)) throw; 

其中actualContractAddress由发件人提供,而isAuthorized()是您编写的用于查询内部注册表的函数。

希望它有所帮助。

答案 1 :(得分:2)

您可以使用Rob Hitchens建议的界面来执行此操作,或者您可以动态定义界面并使用.call,.callcode,.delegatecall执行方法。

以下是一个例子:

contract ContractsCaller {

    function execute(address contractAt, uint _i, bytes32 _b) returns (bool) {
        return contractAt.call(bytes4(sha3("testMethod(uint256,bytes32)")), _i, _b);
    }
}

contract Test {

    uint256 public i;
    bytes32 public b;

    function testMethod(uint256 _i, bytes32 _b) {
        i = _i;
        b = _b;
    }
}

可以在单独的文件中定义测试。 ContractsCaller除了地址和所调用方法的签名外,不需要知道关于Test的任何信息。

方法的签名是方法名称的前4个字节及其参数的类型:

bytes4(sha3("testMethod(uint256,bytes32)"))

More information about .call, .callcode, .delegatecall.