Alert Source Discuss
Standards Track: Core

EIP-1014: 精简版 CREATE2

Authors Vitalik Buterin (@vbuterin)
Created 2018-04-20

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 中的第一个字节是无效操作码时产生的行为完全相同。这从创世区块开始追溯适用。

具体来说,如果 noncecode 非零,则创建操作失败。

使用 EIP-161

帐户创建交易和 CREATE 操作应在执行初始化代码之前,将 nonce 在其正常起始值之上递增 1

这意味着如果在交易中创建合约,则 nonce 立即变为非零,其副作用是同一交易中的冲突将始终失败 - 即使它是从 init_code 本身执行的。

还应该注意的是,SELFDESTRUCT (0xff) 对 noncecode 没有直接影响,因此合约不能在一个交易中被销毁和重新创建。

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.