据我所知,在另一个合同中调用函数的方法主要有两种。
1.)使用4字节methodID ->address.call(bytes4(sha3(‘foo()“))
2.)使用合同ABI -> contractInstance.foo()
我想知道是否有人可以解释为什么使用bytes4方法ID进行调用只能指示一个异常错误,而使用ABI进行调用时可以返回实际值。我猜这和ABI有关,但我想了解一下引擎盖下面到底发生了什么。谢谢。
发布于 2018-01-17 17:48:25
我不知道你在合同中使用ABI合同是什么意思。我认为您的意思是,当我们将合同导入另一个合同并通过创建对它的引用(如contractInstance = externalContract(contractAddress) )来访问它的实例时。
最终,当我们导入一个契约时,会有返回值的原因是因为我们知道在编译时每个函数调用将返回的数据类型和大小。然后,我们可以将返回数据放在正确的变量类型中。但是,当我们直接调用一个地址上的函数时,我们不知道返回值的类型和大小,因为这些细节没有存储在块链上。函数只返回原始数据。这意味着在调用该函数之后,我们不知道要将返回值存储在哪种类型的变量中,所以它是不允许的。
另外,由于Byzantium分叉,如果您在它之后直接执行一些程序集指令,您实际上可以从执行address.call()中获得返回值。特别是returndatacopy()指令,可以是在医生里看到。在我写的可升级的代理合同中可以看到一个示例用法(注意,该示例使用委托,但它的行为应该与使用调用相同)。这种方法仍然只返回原始数据,它不会为它创建一个变量类型。
https://ethereum.stackexchange.com/questions/36608
复制相似问题