# EIP-1014: Skinny CREATE2 **Published by:** [shaneson.eth](https://paragraph.com/@shaneson-eth/) **Published on:** 2022-06-16 **URL:** https://paragraph.com/@shaneson-eth/eip-1014-skinny-create2 ## Content Eip学习进行时。在Uniswap 的代码中,出现了以下这段代码。当时我在研读代码的时候留意到了,create2不是一个标准的语法糖,所以这里肯定会有比较深的理论和学习的地方。经过学习和研究,这是用于Create Contract的EIP-1014标准。CREATE2 是以太坊在 “君士坦丁堡” 这次硬分叉升级中引入的一个新操作码,不同于 CREATE,它使用新的方式来计算合约地址,让生成的合约地址更具有可控性。通过 CREATE2 可以延伸出很多有意思的玩法,在 CTF 中最常见的就是利用这种可控性,在同一个地址先后部署字节码完全不同的合约。原理如果利用外部账户或者使用 CREATE 操作码的合约账户创建一个合约,那么很容易就能确定被创建合约的地址。每个账户都有一个与之关联的 nonce:对外部账户而言,每发送一个交易,nonce 就会随之 +1;对合约账户而言,每创建一个合约,nonce 就会随之 +1。新合约的地址由创建合约交易的发送者账户地址及其 nonce 值计算得到,其具体公式如下keccak256(rlp.encode(address, nonce))[12:] 不同于原来的 CREATE 操作码,在合约地址的计算方法上,CREATE2 不再依赖于账户的 nonce,而是对以下参数进行哈希计算,得出新的地址:合约创建者的地址(address)作为参数的混淆值(salt)合约创建代码 (init_code)keccak256(0xff ++ address ++ salt ++ keccak256(init_code))[12:] 一个需要注意的重要细节是,计算合约地址所需的最后一个参数并非合约代码,而是其创建代码。该代码是用来创建合约的,合约创建完成后将返回运行时字节码。 这意味着,如果我们控制了合约的创建代码并使其保持不变,然后控制合约构造函数返回的运行时字节码,那么我们很容易就能做到在同一个地址上,反复部署完全不同的合约。事实上 CREATE2 这种让合约在部署后可以被重新更改的特性存在着潜在的安全问题,也引起了人们对其的讨论。 在 CTF 中,这种特性往往会被用来作为一个技巧,通过在同一个地址上部署不同的合约用来 bypass 不同的校验。 ## Publication Information - [shaneson.eth](https://paragraph.com/@shaneson-eth/): Publication homepage - [All Posts](https://paragraph.com/@shaneson-eth/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@shaneson-eth): Subscribe to updates