Sui V0.31版本重要特性:Package可更新

Sui智能合约是由一系列Move模块组成的package objects构成,packages具有不可篡改的特性,保证交易可以在没有达到完全共识(快速通道交易)的情况下,也能在智能合约上安全的运行。如果有人更改了packages,对应的objects信息将会被共享,并要求在交易完成前达成共识。(关于更多「共享」内容,可参阅:https://docs.sui.io/learn/objects#shared)
然而,考虑到代码需不断开发迭代,package objects的不可篡改就变成一个棘手的问题。开发者需要更新他们的代码并提交代码变更的同时想从快速通道交易中获益。Sui network提供了一个既可以保留packages原有不可篡改属性的同时,又可以升级packages的方法,成功解决了这一难题。
本文将介绍如何使用Sui Client CLI升级packages,Move开发者可以参考package module documentation文档(https://github.com/MystenLabs/sui/blob/main/crates/sui-framework/docs/package.md),了解代码在升级packages过程中所做的处理。
要求#
在升级之前,您的packages需要满足以下几点要求:
升级前,要准备需要升级package的UpgradeTicket,当发布package时会生成UpgradeCap,这时你可以作为UpgradeCap所有者发布UpgradeTicket,Sui Client CLI可以自动处理这些请求。
您升级前后的版本代码结构必须相互兼容:
现有的public函数签名和结构体字段需要保持一致;
您可以增加新的结构体和函数;
您可以向现有结构添加功能;
您可以从现有(公共或其他)删除函数中泛型约束;
您可以调整函数的运行方式;
您可以更改非public函数的签名,包括friend和entry函数签名。
注意:如果您的package包含依赖项,且该依赖项也已升级,则您的package不会根据新版本自动更新,您必须明确的显示升级后的package来指向新的依赖项。
升级#
使用sui client upgrade指令升级packages可以满足上述要求,同时为以下参数提供值:
— gas-budget:最大gas预算。
— cap:UpgradeCap的ID,发布指令后将收到此ID。
使用Move代码升级packages的开发者,可以通过定义访问类型和函数来自定义升级策略。例如,一个Move开发者或许想要在未经所有者同意时驳回packages升级,make_immutable函数(https://github.com/MystenLabs/sui/blob/main/crates/sui-framework/docs/package.md#0x2_package_make _immutable)可以满足其需求,还有更多类型的高级策略可以使用,如使用UpgradeTicket和Upgrade Receipt指令也可以实现这个功能。详情请见GitHub上的自定义升级策略(https://github.com/MystenLabs/sui/issues/2045)。
当你使用Sui Client CLI,upgrade指令会在处理后生成升级签名摘要,同时使用UpgradeCap授权升级可以获取UpgradeTicket,并在升级成功后使用UpgradeReceipt更新UpgradeCap。要了解更多有关升级过程的信息,请参阅 package module(https://github.com/MystenLabs/sui/blob/main/crates/sui-framework/docs/package.md)。
示例#
您将开发一个名为sui_package的package,基本信息如下:
package准备完毕并发布:
随后会收到如下响应:
此面板展示了Object修改的部分,其中包含升级所需的两条信息,一个是UpgradeCap ID,另一个是package ID。
你可以在响应中使用Object.objectType值来识别不同的objects:输入UpgradeCap,得到一个String(“0x2::package::UpgradeCap”)值,输入objectType ,从中读取String(“<PACKAGE-ID>::sui_package::<MODULE-NAME>”)值。
为确保其他的package可以使用这个package作为依赖项,必须升级package配置文件(Move.toml )包含这些信息。
更新地址别名并在[package]部分添加一个新的published-at条目,两者都指向链上ID:
published-at值允许Move编译器去验证这些packages的依赖性。
合约运行一段时间后,当你决定要升级sui_package来增添一些所需的功能,你需要在运行upgrade指令前,再次编辑你的基础信息。在[addresses]部分,你需要升级sui_package的地址使其以0x0开头,这可以保证验证器为升级的package发布一个新的地址。当然,你可以保留published-at值不变,因为它仅在发布依赖型package时由工具链读取。保存的信息现在大概有以下内容:
当基础信息和代码修改就位,可以使用sui client upgrade指令升级package了。将UpgradeCap ID(示例中的<UPGRADE-CAP-ID>值)传递给 — upgrade-capability flag。
如果package不满足上述要求,会提醒你;如果满足,编译器将在发布升级的package后,返回其结果值:
显示的结果,将是从升级后的package中获得一个新的ID,而升级前的packages,需要将这些信息保存起来,这样依赖sui_package的其他packages才知道如何在链上找到这些验证代码。再次编辑你的配置信息,为published-at值提供升级后的package ID ,即可在[addresses]部分返回原始sui_package ID值:
published-at值会随着升级而不断调整,升级后,[addresses]中的sui_package ID总是与原始的package ID相对应。你必须将返回值调整为0x0,才能使编译器知道在运行upgrade指令之前,为升级创建一个新的ID。

关于 Sui Network
Sui是基于第一原理重新设计和构建而成的L1公有链,旨在为创作者和开发者提供能够承载Web3中下一个十亿用户的开发平台。Sui上的应用基于Move智能合约语言,并具有横向可扩展性,让开发者能够快速且低成本支持广泛的应用开发。
官网:https://sui.io/
Twitter:https://twitter.com/SuiNetwork
Discord:https://discord.com/invite/sui
中文Medium:https://medium.com/sui-network-cn
中文电报群:https://t.me/Sui_Blockchain_Chinese