CREATE3操作码是一种创新的智能合约部署方式,能够使部署的地址在不同的EVM区块链上保持一致。文章详细介绍了CREATE3的优势、实现方式及其在跨链应用中的重要性。
CREATE3 操作码 — 一种创新的跨链智能合约部署方式。
最近,我一直在为 DERA 链 构建 AA 基础设施。在这个过程中,我发现了 CREATE3 这种智能合约部署方法,并对此感到非常兴奋。本文旨在详细阐述这一新提出的操作码、其 当前实现 以及它为 EVM 区块链带来的好处。让我们深入了解吧!
CREATE3 旨在解决当前合约部署操作码 CREATE 和 CREATE2 中存在的一些局限性。通过引入一种更为灵活且可预测的生成合约地址的方法,CREATE3 旨在简化部署过程并增强跨链互操作性。
以下是 CREATE3 的一些关键点:
address = keccak256(rlp_encode(deployer_address, nonce))[12:]
其中:
虽然这种方法是确定性的,但在部署之前缺乏可预测性,这使得开发人员难以提前预知合约地址。
address = keccak256( 0xff + deployer_address + salt + keccak256(init_code))[12:]
其中:
address = keccak256(rlp_encode(deployer_address, salt))[12:]
其中:
通过将合约地址与其字节码解耦,CREATE3 实现了显著的进步。该操作码允许在不同的 EVM 兼容区块链上以一致的地址部署合约,即使由于优化或其他变化导致字节码略有不同。这一特性对于跨链应用程序尤其有益,因为在这些应用程序中,保持一致的地址至关重要。
尽管具有优于 CREATE 和 CREATE2 的优势,但该操作码尚未在以太坊中原生实现。在此期间,一些非协议库已经实现了它,并且这些库正在逐步被 Web3 项目采用。目前最流行的非协议库是由 0xsequence 提供的。
该库巧妙地利用当前可用的 CREATE2 和 CREATE 操作码实现了 CREATE3 方案。我认为,作者采用了一种“hacking”方法来解决手头复杂的难题。为他们点赞!让我们深入了解实现的细节。
该库提供了一个非常轻量级且简单的接口,基本上只提供一个 API:
function create3(bytes32 _salt, bytes memory _creationCode) internal returns (address addr)
其中:
尽管在参数中包含了 _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 的部署能力:
该库还提供了一个简洁的 API 来抽象掉复杂性,使得开发人员在 EVM 中原生支持 CREATE3 之前也能轻松使用类似 CREATE3 的功能。
理论说得够多了,你可以通过在 DERA 链 上查看以下交易详情来看到 CREATE3 库的实际应用:https://trace.derachain.com/tx/0x8321186c0622398e4de33d8d9d8623cb77c73ccfc8716d8797ff8318a99b24fa?tab=internal
在 DERA 链上运行的 CREATE3。
该交易是一个标准的 CREATE3 部署,其中 0x8e…A2ba 是代理合约,而 Smart Account 是实际部署的合约。
总的来说,CREATE3 操作码代表了以太坊区块链上智能合约部署演进中的重大进步,提供了一种更高效、灵活的合约部署方式。随着以太坊生态系统的不断发展和成熟,CREATE3 的采用率可能会增加,为开发人员提供一种更高效、灵活的智能合约部署方式。
如果你觉得这篇文章内容有价值,请给我一个关注。这将让我的一天变得美好,并激励我撰写更多优质文章。非常感谢你的支持 🙏
- 原文链接: medium.com/@barchitect/c...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!