定制升级权限

升级权限类型

在先前的示范中,智能合约升级几乎可以把所有功能重写,这会让用户产生担心。
当然,Sui Move也提供了不同等级的合约升级权限。从宽松到收紧的程度罗列如下:

  • Compatible: 最宽松的权限。可以修改所有函数的实现。可以剔除函数对范型输入参数的能力约束。可以让非public的函数变为public. 可以修改、删除任意 private, public(friend)entry 函数的输入输出参数。但除了能力约束之外不能修改public函数的输入输出参数。不能修改已有的类型。
  • Additive: 可以给 package 添加新的函数,比如新的 public函数和struct. 但不能对现有函数的代码做任何修改。
  • Dependency-only: 只能修改该 package 的依赖项。
  • Immutable: 无法再升级该 package .

最初发布合约的时候,得到的合约升级权限是最宽松的 Compatible. 可以调用 package.move 模块中的 only_additive_upgrades, only_dep_upgradesmake_immutable 这三个 public entry 函数来单向收紧升级权限。

合约升级过程

合约升级过程

合约升级的过程可以理解为三个环节。

  1. Authorization: 使用UpgradeCap授权升级合约,生成一个UpgradeTicket.
  2. Execution: 虚拟机消费了这个UpgradeTicket并验证合约的字节码、与旧版合约的兼容性,在链上创建升级后合约object. 如果升级成功就会返回UpgradeReceipt.
  3. Commit: 根据返回的UpgradeReceipt更新UpgradeCap上关于新建的 package 信息。

其中第2步 Execution 是内部指令,第1步和第3步在 package.move 中使用函数实现。

module sui::package {
    public fun authorize_upgrade(
        cap: &mut UpgradeCap,
        policy: u8,
        digest: vector<u8>
    ): UpgradeTicket;

    public fun commit_upgrade(
        cap: &mut UpgradeCap,
        receipt: UpgradeReceipt,
    );
}

定制权限作用

除了通过内置的命令行 sui client upgrade 调用默认的 authorization 和 commit 环节,还可以定制升级权限添加更多条件约束,比如投票、治理、允许清单、时间锁等功能。