CREATE2
Article Summary
GPT 4
EATE2
是以太坊在 “君士坦丁堡” 这次硬分叉升级中引入的一个新操作码,不同于 CREATE
,它使用新的方式来计算合约地址,让生成的合约地址更具有可控性。通过 CREATE2
可以延伸出很多有意思的玩法,在 CTF 中最常见的就是利用这种可控性,在同一个地址先后部署字节码完全不同的合约。
原理
CREATE
如果利用外部账户或者使用 CREATE
操作码的合约账户创建一个合约,那么很容易就能确定被创建合约的地址。每个账户都有一个与之关联的 nonce
:对外部账户而言,每发送一个交易,nonce
就会随之 +1
;对合约账户而言,每创建一个合约,nonce
就会随之 +1
。新合约的地址由创建合约交易的发送者账户地址及其 nonce
值计算得到,其具体公式如下:
keccak256(rlp.encode(address, nonce))[12:]
CREATE2
不同于原来的 CREATE
操作码,在合约地址的计算方法上,CREATE2
不再依赖于账户的 nonce
,而是对以下参数进行哈希计算,得出新的地址:
- 合约创建者的地址(
address
) - 作为参数的混淆值(
salt
) - 合约创建代码 (
init_code
)
具体的计算公式如下:
keccak256(0xff ++ address ++ salt ++ keccak256(init_code))[12:]
一个需要注意的重要细节是,计算合约地址所需的最后一个参数并非合约代码,而是其创建代码。该代码是用来创建合约的,合约创建完成后将返回运行时字节码。
这意味着,如果我们控制了合约的创建代码并使其保持不变,然后控制合约构造函数返回的运行时字节码,那么我们很容易就能做到在同一个地址上,反复部署完全不同的合约。事实上 CREATE2
这种让合约在部署后可以被重新更改的特性存在着潜在的安全问题,也引起了人们对其的讨论。
在 CTF 中,这种特性往往会被用来作为一个技巧,通过在同一个地址上部署不同的合约用来 bypass 不同的校验。
This piece of writing is an original article, utilizing theCC BY-NC-SA 4.0Agreement. For complete reproduction, please acknowledge the source as Courtesy ofxiaocai