定制升级权限
升级权限类型
在先前的示范中,智能合约升级几乎可以把所有功能重写,这会让用户产生担心。
当然,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_upgrades
和 make_immutable
这三个 public entry 函数来单向收紧升级权限。
合约升级过程
合约升级的过程可以理解为三个环节。
- Authorization: 使用
UpgradeCap
授权升级合约,生成一个UpgradeTicket
. - Execution: 虚拟机消费了这个
UpgradeTicket
并验证合约的字节码、与旧版合约的兼容性,在链上创建升级后合约object. 如果升级成功就会返回UpgradeReceipt
. - 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 环节,还可以定制升级权限添加更多条件约束,比如投票、治理、允许清单、时间锁等功能。