美文网首页践行区块链
可升级合约中可以使用 immutable 变量么

可升级合约中可以使用 immutable 变量么

作者: Ashton | 来源:发表于2024-09-10 06:59 被阅读0次

前段时间 review 团队小伙伴合约代码的时候,提出有些变量是可以使用 immutable 来修饰的。但得到一个答复:我们这是可升级合约,不能用 immutable,真的是这样么?

0x01 OpenZeppelin 的警告

因为现在的可升级合约基本上都是使用的 OpenZeppelin 的合约模版,估计可升级合约不能用 immutable 变量的说法也是来源于 OpenZeppelin。
在 OpenZeppelin 的 Why can’t I use immutable variables? 这个文档里,确实解释了"为什么不能用 immutable 变量",主要有下面两个原因:

  1. 可升级合约没有构造函数,只有初始化函数,因此它们无法处理 immutable 变量。
  2. 由于不可变变量的值存储在字节码中,其值将在给定合约的所有代理之间共享。

只是这两个原因不能用 immutable 变量,我感觉是比较牵强的。

0x02 什么时候我们需要用 immutable 变量

immutable 是对变量的一种硬性约束,一旦初始化就不再改变。其中一个常见的场景是对固定合约地址的引用,比如对 USDT 合约地址的引用,我们明确知道这个合约地址在固定链上是不会发生改变的,但是因为我们有可能在不同链上部署我们的合约,起码要在一个网络的测试网和主网上部署我们的合约,直接用常量就很不方便,这个时候使用 immutable 变量,通过构造函数初始化后就不再改变,是最符合预期的。

当然,这种情况下我们也可以使用正常的变量,但这会引入额外两个问题:

  1. Gas 消耗更高
  2. 存在未来被恶意改变的风险
    所以对一个变量来说,能使用 immutable 约束的时候我们还是希望能够尽量使用 immutable 约束。

0x03 可升级合约就一定不能使用构造函数么

非也。
这其实只是 OpenZeppelin 为了方便构造函数误用而额外加的规范性限制,在可升级合约的实现合约中,使用构造函数初始化正常变量可能会得到与预期不一致的结果,但初始化 immutable 变量得到的结果应该是完全符合预期的。在实现合约构造函数中初始化的 immutable 变量在可代理合约中都可以正常读取。

0x04 结论

immutable 变量在可升级合约中使用没任何问题:

  1. 尽管通常情况下,可升级合约的实现合约中我们遵循 OpenZeppelin 规范,使用初始化函数 initialize 去初始化常规变量。但在需要的时候我们仍然可以使用构造函数去初始化 immutable 变量。
  2. 我们使用 immutable 变量的本意就是其初始化后就不再改变,所以同一个实现合约的不同代理看到同样的值并没啥问题。如果需要不同的值,实例化不同的实现合约就好了。
  3. 在使用升级插件的时候还是要注意把 unsafeAllow: constructor 和 unsafeAllow:state-variable-immutable 的开关打开,否则估计会报错。

相关文章

  • 浅谈Solidity: 9. 常数 constant和immut

    constant(常量)和immutable(不变量)。状态变量声明这个两个关键字之后,不能在合约后更改数值;并且...

  • 币礼包暂停服务公告

    根据Fountain基金会的合约升级公告 币礼包也将在合约升级期间暂停使用,合约升级完成后开放。

  • JAVA变量(二) 9.29

    Java变量使用规则 1.Java中变量需要先声明后使用。 2.变量使用时,可声明同时进行初始化,也可以先声明后赋...

  • 合约结构

    翻译原文date:20170617 在Solidity中的合约,就像是面向对象语言中的对象。每个合约可以包含变量,...

  • Immutable.js 笔记

    约定变量命名规则:如所有Immutable类型对象以`$`开头。 foo = Immutable.fromJS({...

  • 一文梳理 SASS

    变量可以是连续几个值,变量也可以被当做连续几个值中的一个值使用,变量在块外声明相当于全局变量。 中划线声明的变量可...

  • 官方文档翻译 Solidity的语法介绍

    合约 Solidity合约与面向对象语言中的类相似。它们包含可以修改这些变量的状态变量和函数中的持久数据。在不同的...

  • angular中的那些可替换升级的技术总结

    可服务升级替换的Service 这样可以选配某个provider 模块中配置使用TestProvide 模块中配置...

  • Redux 中使用 immutable

    初始化 安装依赖在 react 中,使用 immutable 需要两个依赖:immutable 和 redux-i...

  • 智能合约的结构组成

    概述: 在solidity中,合约类似于面向对象编程语言中的类,每个合约中可以包含状态变量,函数,函数修饰器,事件...

网友评论

    本文标题:可升级合约中可以使用 immutable 变量么

    本文链接:https://www.haomeiwen.com/subject/gcnyljtx.html