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

  • A+
所属分类:以太坊ETH

chatGPT账号

可升级合约中可以使用 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 的开关打开,否则估计会报错。
免责声明

发文时比特币价格:$71249

当前比特币价格:[crypto coins=”BTC” type=”text” show=”price”]

当前比特币涨幅:[crypto coins=”BTC” type=”text” show=”percent”]

免责声明:

本文不代表路远网立场,且不构成投资建议,请谨慎对待。用户由此造成的损失由用户自行承担,与路远网没有任何关系;

路远网不对网站所发布内容的准确性,真实性等任何方面做任何形式的承诺和保障;

网站内所有涉及到的区块链(衍生)项目,路远网对项目的真实性,准确性等任何方面均不做任何形式的承诺和保障;

网站内所有涉及到的区块链(衍生)项目,路远网不对其构成任何投资建议,用户由此造成的损失由用户自行承担,与路远网没有任何关系;

路远区块链研究院声明:路远区块链研究院内容由路远网发布,部分来源于互联网和行业分析师投稿收录,内容为路远区块链研究院加盟专职分析师独立观点,不代表路远网立场。

本文是全系列中第279 / 280篇:行业技术

  • 我的微信
  • 这是我的微信扫一扫
  • weinxin
  • 我的电报
  • 这是我的电报扫一扫
  • weinxin
chatGPT账号
路远

发表评论

您必须登录才能发表评论!