Hi 游客

更多精彩,请登录!

比特池塘 区块链前沿 正文

为什么要使用 CREATE2?

落日余晖97
67 0 0
6 F- P$ n0 ~8 {5 E9 Q, n: p7 h
编者注:君士坦丁堡升级引入了 CREATE2 操作码,这个操作码不像 CREATE 那样根据合约创建交易的发起地址和 Nonce 来产生合约地址,而是根据合约的初始化代码(init code)来产生。前段时间,有人认为 CREATE2 会给合约引入新的风险因素,但 Jeff Coleman 坚持认为,CREATE2 绝不完美,但所谓的风险其实并不来源于 CREATE2 本身,而是来自于 CREATE 的遗留问题。本文是他对 CREATE2 的解释和辩护。也许读完之后,你也会同意 Hudson 说的:“应该像看待 CALL 和 DELEGATECALL 带来的风险那样来看到 CREATE2 带来的风险”。
/ q( a0 U3 L  J
5 o+ }  X% L% S+ {6 Z* w
总结一下,PSA 有两点结论:5 k3 \. T7 O2 p* j5 s- s
CREATE 函数在将来会让人们越来越难以验证一个合约的身份。: A* \6 q+ _4 |# H) n0 P1 S
CREATE2 函数会帮助缓解这个问题,尽管如此,我们仍需仔细检查合约初始话代码(init code),这将变得与验证合约代码同等重要,以下是原因:
. Y6 D2 Q' Q- B2 e' `; o- x, G1)就像硬件钱包,冷钱包,以及各种嵌入式或者离线设备的开发者们已经意识到的一样,CREATE 函数让合约代码和合约地址之间的关系变得过于多样。当你使用 CREATE 时,你无法提前预测哪段代码将处于某个给定的地址上。你也无法在合约部署之后容易地 “验证” 这段代码,除非你有区块链的直接访问权限,或者使用某些非常复杂的技巧。这些技巧可能包括与无密钥地址(即合约地址)进行非常混乱的多重转账操作,并且需要提前预付未来的手续费用等等。! f- [, T$ N+ r& K5 I
2)CREATE2 函数则让地址变成了对合约代码的一种承诺,并且相比之下可能的状态更少。但是我们在这里讨论的是 “初始化代码(init code)”,它的哈希值(hash)和盐(salt)共同决定了这个合约的地址。这实际上是一个巨大的优势,只要人们确实 “验证” 了初始代码。因为它意味着人们可以检查代码工厂与它们所创合约之间的关系,甚至完全无需知晓网络的状态,也可以判断正在部署的合约。所以硬件钱包,冷钱包之类的服务都能很好地运行。* t; [* p$ c" z' J
3)但是尤其值得注意的是,这不能使你免受故意造成的不确定性的伤害。如果没有作出严格的限制,一段使用 DELEGATECALL 或者 CALLCODE 的合约初始代码,可以产生无数种结果。这就是人们口中所说的 “偷梁换柱(replace a contract)”。你不可能真的替换那些 CREATE2 所创地址中的 “初始化代码”,但是如果初始化代码本身具有不确定性,你可能会破坏并使用不同的代码重新创建这个合约,这就像你后来将 DELECATECALL 指向新地址一样。这与每个人 (特别是硬件钱包和冷钱包解决方案) 今天在尚无法确认某个合约已经部署时候的处境都是一样的。CREATE2 使得合约的创建环境更加公平,每个人都能确认初始代码的有效性。但是它却并不能保护合约不受初始代码不确定性的伤害。) u$ m& p; \" z( h9 ~0 J- C  ^
4)CREATE2 是极为富有远见的,因为用硬编码的椭圆曲线生成的 EOA 地址(即用户地址)可能最终会消亡,取而代之的是各式各样的签名方法。CREATE 函数对地址身份所作的假设在未来可能比现在君士坦丁堡 (Constantinople)阶段更加不切合实际,而 CREATE 函数的一些带有状态的假设已经开始调整了 。这和 CREATE2 函数没有任何关系,它更多是暴露了 CREATE 函数的缺陷,这些缺陷已经在链下以及实际确证之前有所体现。( F' O2 R. W3 i" k
5)如果你将初始代码检验工作视为验证地址 “里面是什么” 的手段、视为 CREATE2 本身的一部分,那么你就基本不会遇上 CREATE 函数的旧问题。但是如果你同时使用这两个函数,可能就会遇上 @jasoncarver 一直在讨论的奇怪代码表现。这并不是 CREATE2 函数的问题,反而更有可能是当我们逐渐摒弃 CREATE 函数时,CREATE 函数被暴露出越来越多的问题。我意识到很多人并没有意识到 CREATE 函数的问题,所以将其归因于另一个函数。实际上,我们有迫切的需求立刻停用 CREATE 函数。+ [5 K" e! I7 |0 x1 X
6)实际上,这意味着:网站,用户,开发者和合约都需要通过 “初始化代码” 来验证合约的身份,而不是通过字节码。如果我们标准化它们的初始模式,这将使得标准部署流程和标准生产流程更加容易。而且,这也比现行的、让人们受困于试图将合约验证向后兼容进 CREATE 模型的非标准化技术好很多。CREATE2 更便宜、更快速、无状态,而且能够面向未来。# g' r, j' L8 i3 H  ^
7)如果你绝对必须在君士坦丁堡 (Constantinople)之后使用 CREATE 函数,请必须采取特定的步骤确保你合约的功能能够被用户信任,并且将你采用的步骤告诉用户。现在在 CREATE 函数中已经存在一些奇怪的陷阱,使用的时间越长,它可能产生的问题就越多。请尽快转移到 CREATE2 函数中来。
. u0 J+ }5 @* J; Y4 y" c9 [/ H我可能也应该指出,已有的工厂验证模式已经很容易被初始代码不确定性影响,所以这是一个现存的缺陷,而不是新出现的。离线或硬件钱包也总是容易受到初始代码不确定性的损害。目前,大多数初始代码都处于合理范围,因此大大减轻了这种风险。当我们在未来使用 CREATE2 的各项优势功能的同时,我们也需要不断验证合约来保证我们的安全。2 U1 K4 `6 y# M/ _- ?; g& V
我认为,关于 CREATE 函数讨论的最终解决方案如下:基本上我们需要基于内容来为合约赋予地址(这包括确定构造器参数以及多重实例化,做法分别是对初始代码进行哈希(hash)和加盐(salt)),取消自我销毁(self-destruct),并且使用租金存储和恢复机制来处理存储恢复。这意味着合约 nonce 将不再存在而且 CREATE 函数将消失。比起在君士坦丁堡 (Constantinople)阶段部署 CREATE2 函数,如果任何人有一个更好的的方法,来使我们摆脱合约不确定性的影响,我将诚挚地期待。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

落日余晖97 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    22