CREATE3 操作码——一种创新方式,用于部署智能合约并保持部署地址…

CREATE3操作码是一种创新的智能合约部署方式,能够使部署的地址在不同的EVM区块链上保持一致。文章详细介绍了CREATE3的优势、实现方式及其在跨链应用中的重要性。

CREATE3 操作码 — 一种创新的跨链智能合约部署方式。

CREATE3 操作码 — 一种创新的跨链智能合约部署方式。

最近,我一直在为 DERA 链 构建 AA 基础设施。在这个过程中,我发现了 CREATE3 这种智能合约部署方法,并对此感到非常兴奋。本文旨在详细阐述这一新提出的操作码、其 当前实现 以及它为 EVM 区块链带来的好处。让我们深入了解吧!

什么是 CREATE3(EIP-3171)?

CREATE3 旨在解决当前合约部署操作码 CREATE 和 CREATE2 中存在的一些局限性。通过引入一种更为灵活且可预测的生成合约地址的方法,CREATE3 旨在简化部署过程并增强跨链互操作性。

以下是 CREATE3 的一些关键点:

  • 提出了一个新的操作码 CREATE3,用于部署具有更可预测地址的合约。
  • 允许合约地址仅由部署者地址和 salt 确定,与合约的字节码无关。
  • 能够在不同链上将不同的字节码部署到相同的地址。

CREATE3 相对于 CREATE 和 CREATE2 的优势是什么?

  • CREATE:原始的操作码,用于部署合约。CREATE 根据部署者地址及其 nonce 生成地址。
address = keccak256(rlp_encode(deployer_address, nonce))[12:]

其中:

  1. deployer_address 是部署新合约的合约的 20 字节地址。
  2. nonce 是部署者地址的 nonce 值,每次新合约部署时递增 1。
  3. keccak256 是 Keccak-256 哈希函数。
  4. rlp_encode 是递归长度前缀(RLP)编码函数。

虽然这种方法是确定性的,但在部署之前缺乏可预测性,这使得开发人员难以提前预知合约地址。

  • CREATE2:为了提高可预测性,CREATE2 使用部署者地址、salt 和合约的字节码组合来生成地址。这使得开发人员能够在部署之前计算地址,从而便于状态通道和可升级合约等用例。然而,CREATE2 仍然将地址与字节码绑定,这可能会限制灵活性。
address = keccak256( 0xff + deployer_address + salt + keccak256(init_code))[12:]

其中:

  1. 0xff 是单个字节。
  2. deployer_address 是部署新合约的合约的 20 字节地址。
  3. salt 是一个 32 字节的哈希摘要,可以使用 keccak256 函数生成。
  4. init_code 是正在部署的合约的字节码。
  • CREATE3:合约地址仅由部署者地址和 salt 确定,与合约的字节码无关。确定部署地址的可行公式可以是:
address = keccak256(rlp_encode(deployer_address, salt))[12:]

其中:

  1. deployer_address 是部署新合约的合约的 20 字节地址。
  2. salt 是一个 32 字节的哈希摘要,可以使用 keccak256 函数生成。

通过将合约地址与其字节码解耦,CREATE3 实现了显著的进步。该操作码允许在不同的 EVM 兼容区块链上以一致的地址部署合约,即使由于优化或其他变化导致字节码略有不同。这一特性对于跨链应用程序尤其有益,因为在这些应用程序中,保持一致的地址至关重要。

尽管具有优于 CREATE 和 CREATE2 的优势,但该操作码尚未在以太坊中原生实现。在此期间,一些非协议库已经实现了它,并且这些库正在逐步被 Web3 项目采用。目前最流行的非协议库是由 0xsequence 提供的。

0xsequence 的 CREATE3 库

该库巧妙地利用当前可用的 CREATE2 和 CREATE 操作码实现了 CREATE3 方案。我认为,作者采用了一种“hacking”方法来解决手头复杂的难题。为他们点赞!让我们深入了解实现的细节。

该库提供了一个非常轻量级且简单的接口,基本上只提供一个 API:

function create3(bytes32 _salt, bytes memory _creationCode) internal returns (address addr)

其中:

  • _salt 是 32 字节的哈希摘要,可以使用 keccak256 函数生成。
  • _creationCode 是正在部署的合约的字节码。

尽管在参数中包含了 _creationCode,但它并不用于确定部署地址,这使得这个 create3 API 与 CREATE2 和 CREATE 操作码有所区别。此细节在 API 的注释中也明确提到。

查看代码,create3 API 可以分为两个顺序步骤:

  • 第一步:创建代理合约,该合约主要负责代理部署合约的创建。
// 创建代码
bytes memory creationCode = PROXY_CHILD_BYTECODE;

// 获取目标最终地址
// 注意:这是预执行检查,仅用于提前退出
addr = addressOf(_salt);
if (codeSize(addr) != 0) revert TargetAlreadyExists();

// 创建 CREATE2 代理
address proxy; assembly { proxy := create2(0, add(creationCode, 32), mload(creationCode), _salt)}
if (proxy == address(0)) revert ErrorCreatingProxy();

代理创建代码如下:

0x67363d3d37363d34f03d5260086018f3:
      0x00  0x67  0x67XXXXXXXXXXXXXXXX  PUSH8 bytecode  0x363d3d37363d34f0
      0x01  0x3d  0x3d                  RETURNDATASIZE  0 0x363d3d37363d34f0
      0x02  0x52  0x52                  MSTORE
      0x03  0x60  0x6008                PUSH1 08        8
      0x04  0x60  0x6018                PUSH1 18        24 8
      0x05  0xf3  0xf3                  RETURN

部署后其运行时代码为:

0x363d3d37363d34f0:
      0x00  0x36  0x36                  CALLDATASIZE    cds
      0x01  0x3d  0x3d                  RETURNDATASIZE  0 cds
      0x02  0x3d  0x3d                  RETURNDATASIZE  0 0 cds
      0x03  0x37  0x37                  CALLDATACOPY
      0x04  0x36  0x36                  CALLDATASIZE    cds
      0x05  0x3d  0x3d                  RETURNDATASIZE  0 cds
      0x06  0x34  0x34                  CALLVALUE       val 0 cds
      0x07  0xf0  0xf0                  CREATE          addr

看起来有些复杂,但简单来说,这个代理能够创建具有任意字节码的另一个合约。对于对创建代码、初始化代码、运行时代码以及整体部署合约过程感兴趣的人,我推荐阅读这篇精彩的文章 https://www.rareskills.io/post/ethereum-contract-creation-code

请注意,代理合约使用 CREATE2 操作码部署,且 _salt 和 creationCode 保持不变,因此其部署地址是确定且一致的。

第二步:使用代理合约部署实际合约。

// 使用最终的初始化代码调用代理
(bool success,) = proxy.call{ value: _value }(_creationCode);
if (!success || codeSize(addr) == 0) revert ErrorCreatingContract();

合约的实际部署是通过调用代理合约的 fallback 函数来执行的,从而运行本质上使用 CREATE 操作码通过传入的字节码部署合约的运行时代码。部署地址如上所述已经预先确定,并在成功部署时从 API 返回;否则,它将回退。

这个优秀的实现提供了类似 CREATE3 的部署能力:

  • 仅基于部署者和 salt 的可预测地址。
  • 跨链地址一致性。

该库还提供了一个简洁的 API 来抽象掉复杂性,使得开发人员在 EVM 中原生支持 CREATE3 之前也能轻松使用类似 CREATE3 的功能。

CREATE3 实战

理论说得够多了,你可以通过在 DERA 链 上查看以下交易详情来看到 CREATE3 库的实际应用:https://trace.derachain.com/tx/0x8321186c0622398e4de33d8d9d8623cb77c73ccfc8716d8797ff8318a99b24fa?tab=internal

在 DERA 链上运行的 CREATE3。

在 DERA 链上运行的 CREATE3。

该交易是一个标准的 CREATE3 部署,其中 0x8e…A2ba 是代理合约,而 Smart Account 是实际部署的合约。

关键要点

  • CREATE3 操作码是一种创新的方式,用于在 EVM 区块链上部署智能合约,提供了优于 CREATE2 和 CREATE 操作码的优势。通过不依赖合约的字节码来确定部署地址,CREATE3 提供了一种更灵活和高效的合约部署方式。
  • 尽管 CREATE3 尚未在以太坊协议中原生支持,但 0xsequence 库已经提供了一种类似 create3 的部署能力,并且正在逐步被许多 Web3 项目采用。

总的来说,CREATE3 操作码代表了以太坊区块链上智能合约部署演进中的重大进步,提供了一种更高效、灵活的合约部署方式。随着以太坊生态系统的不断发展和成熟,CREATE3 的采用率可能会增加,为开发人员提供一种更高效、灵活的智能合约部署方式。

如果你觉得这篇文章内容有价值,请给我一个关注。这将让我的一天变得美好,并激励我撰写更多优质文章。非常感谢你的支持 🙏

参考资料

  1. EIP-3171 https://github.com/ethereum/EIPs/pull/3171
  2. 0xsequence 的 CREATE3 库 https://github.com/0xsequence/create3
  3. EVM 智能合约部署解释 https://www.rareskills.io/post/ethereum-contract-creation-code
  4. Rareskills 关于智能合约部署代码的精彩文章 https://www.rareskills.io/post/ethereum-contract-creation-code
  • 原文链接: medium.com/@barchitect/c...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
barchitect
barchitect
江湖只有他的大名,没有他的介绍。