Hi 游客

更多精彩,请登录!

比特池塘 区块链前沿 正文

为什么要使用 CREATE2?

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

本版积分规则

成为第一个吐槽的人

落日余晖97 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    22