EIP-1014: 精简版 CREATE2
Authors | Vitalik Buterin (@vbuterin) |
---|---|
Created | 2018-04-20 |
Table of Contents
Specification
在 0xf5
处添加一个新的操作码 (CREATE2
),它接受 4 个堆栈参数:endowment, memory_start, memory_length, salt。行为与 CREATE
(0xf0
) 完全相同,只是使用 keccak256( 0xff ++ address ++ salt ++ keccak256(init_code))[12:]
,而不是通常的发送者和 nonce 哈希作为合约初始化的地址。
CREATE2
具有与 CREATE
相同的 gas
模式,但还有一个额外的 hashcost
,即 GSHA3WORD * ceil(len(init_code) / 32)
,用于计算必须执行的哈希。hashcost
与内存扩展 gas 和 CreateGas
同时扣除:在评估结果地址和执行 init_code
之前。
0xff
是一个单字节,address
始终是20
个字节,salt
始终是32
个字节(一个堆栈项)。
因此,最后一轮哈希的 preimage 始终正好是 85
个字节长。
2018-08-10 的 coredev-call 决定使用上述公式。
Motivation
允许与链上尚不存在但可以依赖于最终只可能包含由特定 init code 创建的代码的地址进行交互(实际上或在通道中以反事实的方式)。对于涉及与合约进行反事实交互的状态通道用例非常重要。
Rationale
地址公式
- 确保使用此方案创建的地址不会与使用传统的
keccak256(rlp([sender, nonce]))
公式创建的地址冲突,因为0xff
只能是数据长度为数 PB 的 RLP 的起始字节。 - 确保哈希 preimage 具有固定大小,
Gas cost
由于地址计算取决于哈希 init_code
,因此如果执行可以重复导致哈希大块 init_code
,则客户端将容易受到 DoS 攻击,因为内存扩展只需支付一次。此 EIP 使用与 SHA3
操作码相同的每字成本。
Clarifications
init_code
是指当执行时,产生将被放置到状态中的运行时字节码的代码,并且通常被高级语言用来实现“构造函数”。
此 EIP 使冲突成为可能。EIP-684 指定了冲突时的行为:
如果尝试创建合约,由于创建交易或
CREATE
(或未来的CREATE2
)操作码,并且目标地址已经具有非零 nonce 或非空代码,则创建立即抛出,其行为与 init code 中的第一个字节是无效操作码时产生的行为完全相同。这从创世区块开始追溯适用。
具体来说,如果 nonce
或 code
非零,则创建操作失败。
使用 EIP-161
帐户创建交易和
CREATE
操作应在执行初始化代码之前,将 nonce 在其正常起始值之上递增 1
这意味着如果在交易中创建合约,则 nonce
立即变为非零,其副作用是同一交易中的冲突将始终失败 - 即使它是从 init_code
本身执行的。
还应该注意的是,SELFDESTRUCT
(0xff
) 对 nonce
或 code
没有直接影响,因此合约不能在一个交易中被销毁和重新创建。
Examples
示例 0
- address
0x0000000000000000000000000000000000000000
- salt
0x0000000000000000000000000000000000000000000000000000000000000000
- init_code
0x00
- gas (假设没有内存扩展):
32006
- result:
0x4D1A2e2bB4F88F0250f26Ffff098B0b30B26BF38
示例 1
- address
0xdeadbeef00000000000000000000000000000000
- salt
0x0000000000000000000000000000000000000000000000000000000000000000
- init_code
0x00
- gas (假设没有内存扩展):
32006
- result:
0xB928f69Bb1D91Cd65274e3c79d8986362984fDA3
示例 2
- address
0xdeadbeef00000000000000000000000000000000
- salt
0x000000000000000000000000feed000000000000000000000000000000000000
- init_code
0x00
- gas (假设没有内存扩展):
32006
- result:
0xD04116cDd17beBE565EB2422F2497E06cC1C9833
示例 3
- address
0x0000000000000000000000000000000000000000
- salt
0x0000000000000000000000000000000000000000000000000000000000000000
- init_code
0xdeadbeef
- gas (假设没有内存扩展):
32006
- result:
0x70f2b2914A2a4b783FaEFb75f459A580616Fcb5e
示例 4
- address
0x00000000000000000000000000000000deadbeef
- salt
0x00000000000000000000000000000000000000000000000000000000cafebabe
- init_code
0xdeadbeef
- gas (假设没有内存扩展):
32006
- result:
0x60f3f640a8508fC6a86d45DF051962668E1e8AC7
示例 5
- address
0x00000000000000000000000000000000deadbeef
- salt
0x00000000000000000000000000000000000000000000000000000000cafebabe
- init_code
0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef
- gas (假设没有内存扩展):
32012
- result:
0x1d8bfDC5D46DC4f61D6b6115972536eBE6A8854C
示例 6
- address
0x0000000000000000000000000000000000000000
- salt
0x0000000000000000000000000000000000000000000000000000000000000000
- init_code
0x
- gas (假设没有内存扩展):
32000
- result:
0xE33C0C7F7df4809055C3ebA6c09CFe4BaF1BD9e0
Citation
Please cite this document as:
Vitalik Buterin (@vbuterin), "EIP-1014: 精简版 CREATE2," Ethereum Improvement Proposals, no. 1014, April 2018. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-1014.