bor*_*yer 20 ethereum solidity smartcontracts
Solidity中的地址可以是帐户或合同(或其他事物,例如交易).当我有一个变量x,持有一个地址时,我该如何测试它是否是合同?
Man*_*áoz 50
是的,你可以通过使用一些EVM汇编代码来获取地址的代码大小:
function isContract(address addr) returns (bool) {
uint size;
assembly { size := extcodesize(addr) }
return size > 0;
}
Run Code Online (Sandbox Code Playgroud)
eth*_*eth 11
isContract使用 EXTCODESIZE的函数的最高投票答案被发现是可破解的。
如果从合约的构造函数调用该函数将返回 false(因为合约尚未部署)。
如果有的话,应该非常小心地使用代码,以避免安全黑客,例如:
https://www.reddit.com/r/ethereum/comments/916xni/how_to_pwn_fomo3d_a_beginners_guide(存档)
要重复:
不要使用 EXTCODESIZE 检查来阻止智能合约调用函数。这不是万无一失的,它可以被构造函数调用破坏,因为当构造函数运行时,该地址的 EXTCODESIZE 返回 0。
请参阅欺骗 EXTCODESIZE 返回 0 的合同的示例代码。
如果您想确保 EOA 正在调用您的合约,一个简单的方法是require(msg.sender == tx.origin). 但是,阻止合同是一种具有安全性和互操作性考虑的反模式。
这将需要在实现帐户抽象时重新审视。
编辑:自从第一次写这个答案以来,Solidity 发生了变化,@manuel-aráoz 有正确的答案。
没有办法可靠地检查地址是否是合同。以太坊的目标之一是平等对待人类和智能合约。这将导致智能合约与人类和其他合约无缝交互的未来。将来可能会改变,但现在任意地址是不明确的。
小智 7
这不是您可以使用Solidity在合同中查询的内容,但如果您只是想知道某个地址是否包含合同代码,您可以使用您的geth控制台或类似方法检查,例如:
> eth.getCode("0xbfb2e296d9cf3e593e79981235aed29ab9984c0f")
Run Code Online (Sandbox Code Playgroud)
使用十六进制字符串(此处0xbfb2e296d9cf3e593e79981235aed29ab9984c0f)作为您要查询的地址.这将返回存储在该地址的字节码.
你也可以使用一个blockchain扫描器找到合同的源代码,在该地址,例如在ecsol库上所显示etherscan.io.
| 归档时间: |
|
| 查看次数: |
13136 次 |
| 最近记录: |