帖子
分享您的知识。
如何未经授权升级 Move 软件包?
我想理解 Sui Network 的这一方面,因为我要么构建、调试,要么部署涉及这个领域的东西. 我想详细解释这个机制或功能的工作原理,以及相关的 CLI 用法、移动代码结构或架构概念. 我的目标是获得足够的清晰度,将这些知识应用到一个真实的项目中——无论是自定义智能合约、NFT系统、钱包集成还是DeFi工具. 与 EVM 链相比,Sui Network 具有独特的功能,因此我对它的与众不同之处以及它如何影响开发最佳实践特别感兴趣. 有示例代码、命令行示例或典型错误需要注意会有所帮助,尤其是在使用 Sui CLI、SDK 或在本地网络/测试网上部署时. 归根结底,我希望避免常见错误,遵循最佳的安全原则,并确保我正在开发的功能在现实条件下表现出预期.
- Sui
- Transaction Processing
- Move
答案
14为了防止未经授权在 Sui 上升级 Move 包,关键机制是 upgrade_cap 对象. 该对象充当链上功能,授予升级已部署软件包的专有权限. 如果不拥有 upgrade_cap,任何人都无法升级软件包,从而保护其免受未经授权的更改.
当您使用 Sui CLI 发布软件包时:
sui 客户端发布--path. /my_package--gas-budget 10000
系统创建一个 upgrade_cap 对象并返回其对象 ID. 此对象必须包含在任何升级事务中,如下所示:
sui 客户端升级--package. <upgrade_cap_object_id>/new_package--升级上限--gas-budget 10000
为了保护您的包裹:
-
保护 upgrade_cap:将其安全地存储在硬件钱包或多重签名钱包中,以确保只有授权实体才能签署升级交易.
-
使用多重签名钱包获得升级权限:将 upgrade_cap 包装在多重签名钱包对象中. 这需要在接受升级交易之前进行多个签名,从而增加了一层安全性.
3.实施链下治理控制:将升级与链下审批流程相协调,以避免恶意升级.
-
不要与未经授权的各方共享 upgrade_cap 或将其暴露在不安全的环境中.
-
使用特定环境的访问控制:例如,将升级操作限制为运营基础架构中的特定部署环境或 IP 白名单.
-
审计升级交易:监控区块链中是否有任何未经授权或意外的升级调用,以便及时做出反应.
如果您失去了对 upgrade_cap 的控制权,任何持有该套餐的人都可以升级您的套餐,这会损害合同的完整性. 相反,如果您完全丢失了 upgrade_cap 并且没有备份,则无法再升级该软件包,这实际上是冻结了其状态.
与以太坊的代理升级模式不同,可升级性以合约逻辑编码,Sui 使用显式能力对象. 这种设计通过将升级权限直接绑定到您控制的链上对象来增强安全透明度.
在您的 Move 代码中,upgrade_cap 不会出现,因为升级权限是在合约逻辑之外管理的,但它在通过 CLI 或 SDK 进行部署和升级交易中至关重要.
检查软件包升级能力的示例:
sui 客户端获取软件包 <package_id>
这将显示包元数据,包括 upgrade_cap 对象.
通过遵循这些做法,您可以确保严格控制软件包升级,降低未经授权更改的风险,并保持用户对您的智能合约的信任.
在 Sui 网络中进行未经授权的升级(Move)
为防止未经授权升级 Sui 网络中的 Move 包,您需要确保只允许可信实体或地址进行升级. 这是通过**upgrade_cap
**机制和仔细控制谁有能力升级您的软件包来完成的.
关键概念:
upgrade_cap
**:限制谁可以升级软件包的功能. 您可以在upgrade_cap
合约部署期间设置和检查. *合同升级流程:Sui 合约一旦部署即可升级,但你需要控制谁可以触发这些升级.
防止未经授权的升级的步骤:
- 设置
upgrade_cap
:部署 Move 包时,定义upgrade_cap
以限制谁可以升级您的合约. - 授予升级权限:仅向可信地址(例如管理员)提供升级功能.
示例移动代码:
module MyPackage {
use 0x1::UpgradeCap;
public fun initialize(owner: address) {
let cap = UpgradeCap::new(owner); // Create upgrade capability for the owner
// Store the upgrade cap in a resource or object
}
public fun upgrade(owner: address) {
// Only the owner (who has the upgrade cap) can call this function
UpgradeCap::assert_cap(&cap, owner); // Ensure the caller has the upgrade cap
// Perform the upgrade logic here
}
}
upgrade_cap
### 设置的 CLI 示例:
发布或部署 Move 包时,可以将upgrade_cap
标识符传递给 Sui 客户端:
sui client publish --gas-budget 10000 --upgrade-cap <upgrade-cap-id>
常见错误:
*未正确关联 upgrade_cap
:如果升级功能设置不正确,未经授权的地址可能会意外获得升级合约的权限.
*错误的升级地址:确保只有授权地址(持upgrade_cap
有的地址)才能执行升级.
最佳实践:
*限制升级能力:仅将升级权限提供upgrade_cap
给可信地址或管理员.
*在 Testnet/Localnet 上测试:务必在本地/测试网络上测试您的升级逻辑,以确保防止未经授权的升级.
*安全存储 upgrade_cap
:确保安全管理持有升级功能的地址.
通过控制upgrade_cap
和谨慎限制谁可以触发升级,您可以避免未经授权的升级,并确保您的合同在部署后保持安全.
要在 Sui 中取消授权升级Move 包,你必须撤销或销毁该upgrade_cap
对象,因为此功能是授权包升级的唯一机制. 一旦upgrade_cap
销毁(例如,在 M public entry fun burn
ove 中通过),软件包将变为永久不可变,因为 Sui 在协议级别执行严格的可升级性控制. 这不同于 EVM 链,后者的可升级性依赖于代理模式或可变存储——SUI 的模型通过将升级与功能所有权明确挂钩来确保确定性安全性. 最佳实践是AdminCap
围绕upgrade_cap
可编程撤销实施治理控制的包装器(例如,),而不是直接烧毁,以备将来的去中心化.
要在 Sui Network 上对 Move 包进行未经授权的升级或禁用升级UpgradeCap
,您需要销毁或转移该包的初始部署期间生成的对象. UpgradeCap
是一个特殊对象,用于授予升级该特定软件包的权限. 没有此功能,将来就无法升级.
为防止升级,您可以将其转移UpgradeCap
到无法访问的地址(例如0x0
),或使用您控制的 Move 功能将其销毁. 例如,如果你想让合约不可变,可以在public entry fun burn_upgrade_cap(cap: UpgradeCap)
你的模块中加入一个函数,在部署后直接调用它. 一旦销毁,升级将永久禁用.
以下是用于烧录的 Move 片段示例:
public entry fun burn_upgrade_cap(cap: UpgradeCap) {
sui::package::delete_upgrade_cap(cap);
}
如果您通过 CLI 进行部署,则可以在发布后调用此入口函数:
sui client call \
--package <your_package_id> \
--module <your_module> \
--function burn_upgrade_cap \
--args <upgrade_cap_object_id>
当您出于安全或治理原因想要永久锁定智能合约逻辑时,禁用升级至关重要. 一旦上限被销毁或转移到没有私钥的地址,该包将完全不可更改.
为了防止在 Sui 中对 Move 包进行未经授权的升级,您可以对升级过程实施访问控制. 具体而言,您可以使用upgrade_cap
(升级功能)并确保它由可信实体或账户安全控制.
关键概念:
upgrade_cap
*升级功能:通过将 Move 包与可信地址关联来控制谁可以升级 Move 包.
*访问控制:仅允许拥有升级功能的账户触发升级.
最佳实践:
- 安全
upgrade_cap
所有权:仅向可信地址(例如部署者账户)授予升级权限. - 使用签名:在升级过程中实现验证签名者的逻辑,以确保只有授权用户才能执行升级.
示例代码:
module MyModule {
use sui::object::{Object, upgrade_cap};
public fun upgrade(beneficiary: &signer) {
let cap = upgrade_cap::get_cap(beneficiary);
assert!(cap.is_some(), 0); // Ensure the signer is authorized
// Logic for upgrading the contract
}
}
CLI 用法:
使用 Sui CLI 安全地发布和管理升级:
sui client publish --upgrade --package <package-id> --capability <upgrade-cap-id>
要避免的常见错误:
*松散的访问控制:避免分配upgrade_cap
给非可信账户.
*状态不兼容性:确保升级不会破坏现有对象状态或数据结构. 请务必先在本地网络/测试网络上进行测试.
为防止未经授权升级 Move 软件包,请执行以下操作:
####1. 使包不可变
// During publishing, set `UpgradePolicy` to `immutable`
let upgrade_cap = package::claim_and_keep(otw);
package::make_immutable(upgrade_cap); // 🔐 Burn upgrade capability
-效果:不允许进一步升级(如 EVM 合约).
####2. 安全管理 UpgradeCap
如果需要升级:
-转移upgrade_cap
到 Multisig/DAO:
transfer::transfer(upgrade_cap, @multisig_address);
-使用自定义身份验证逻辑:
public entry fun upgrade(
_: &AdminCap, // Requires admin permission
upgrade_cap: &mut UpgradeCap,
new_package: vector<u8>
) { package::upgrade(upgrade_cap, new_package); }
####CLI 示例(发布不可变)
sui client publish --gas-budget 100000000
# Then call `make_immutable` with the returned `upgrade_cap` ID
###与 EVM 的主要区别
UpgradeCap
-Sui:可选择升级(通过).
-EVM:默认情况下,合约是不可变的(没有原生升级机制).
###常见陷阱
- 丢失
upgrade_cap
:转移到无效地址 = 不可逆转. - 超权升级:避免向 EOA 授予升级权限.
UpgradeCap
为了确保没有人可以升级 Sui 网络上的 Move 包(包括你自己),你需要撤消与该包对象相关的权限. 这是控制未来升级权限的对象. 如果您删除此对象或使其不可访问,则该包将变为不可变且无法再次修改.
您可以使用 M sui::package::delete_upgrade_cap
ove 代码中的函数安全地执行此操作. 以下是您可以添加到模块中的简单示例:
use sui::package;
use sui::package::UpgradeCap;
public entry fun lock_package(cap: UpgradeCap) {
package::delete_upgrade_cap(cap);
}
然后,部署软件包后,使用 Sui CLI 或 SDK 在交易中执行此函数:
sui client call \
--package <your_package_id> \
--module <your_module_name> \
--function lock_package \
--args <upgrade_cap_object_id> \
--gas-budget 100000000
这样做会UpgradeCap
被烧毁,这意味着它不再存在于链上,没有人可以授权再次升级. 如果您想确保代码的不可变性,这是最佳实践——尤其是对于生产就绪的 DeFi 合约、NFT 标准或任何用户依赖无需信任的锁定行为的逻辑.
就架构环境而言:与默认情况下智能合约不可变的 EVM 不同,Sui 允许可升级的软件包,这既提供了灵活性,也带来了治理的复杂性. 要 “取消授权” 升级,必须明确销毁允许升级的密钥.
在此处阅读官方 Sui 软件包升级文档中的更多内容: https://docs.sui.io/build/packages-and-upgrades#making-packages-immutable
为防止未经授权升级 Sui 中的 Move 包,请在发布后销毁或锁定该upgrade_cap
对象.
upgrade_cap
(来自0x2::package::UpgradeCap
)是授予升级权限的头等对象. 如果它仍保留在发布商的地址中,则任何有访问权限的人都可以升级该软件包.
最佳实践:
-对于不可变合约:消耗能力:
public entry fun burn_upgrade_cap(cap: package::UpgradeCap) {
package::discard(cap); // Destroys the capability
}
-对于受监管的升级:转移upgrade_cap
到多重签名或 DAO 模块,而不是将其保存在一个账户中.
-切勿upgrade_cap
在没有访问控制的情况下在公共功能中公开.
CLI 检查:
sui client object --id [PACKAGE_ID] # Look for associated UpgradeCap object
一旦upgrade_cap
销毁,软件包就会变为永久不可变——这相当于 Sui “锁定” 合约(比如 EVM 的可升级模式).
这种机制是 Sui 以对象为中心的模型所独有的:升级权限由对象所有权强制执行,而不是由合同中的管理员角色或逻辑强制执行.
为防止在 Sui 中进行未经授权的升级:
- 烧掉
UpgradeCap
— 部署后将其摧毁以保持不变性. - 锁定
init
— 如果需要永久不变性,请勿共享上限.
###移动示例:
public fun lock_forever(cap: UpgradeCap) {
sui::package::make_immutable(cap) // Burns cap
}
主要注意事项:
✔ 没UpgradeCap
有,就不可能升级.
✔ 与 EVM 不同,Sui 允许可逆的不变性.
CLI 替代方案:
sui client call --function lock_forever --args <CAP_ID>
*(警告:除非您预先计划恢复方法,否则将永久保留. ) *
为了防止未经授权在 Sui 上升级 Move 包,核心机制是 upgrade_cap 对象. 此功能对象授予升级已部署软件包的专有权限. 如果没有 upgrade_cap,任何人都无法升级软件包,从而确保了安全性.
当你通过 Sui CLI 发布软件包时:
sui 客户端发布--path. /my_package--gas-budget 10000
创建并返回一个 upgrade_cap 对象. 升级软件包时必须提供此对象 ID:
sui 客户端升级--package. <upgrade_cap_object_id>/new_package--升级上限--gas-budget 10000
为了保护升级过程,请执行以下操作:
-
安全地存储 upgrade_cap,例如在硬件钱包或多重签名钱包中.
-
使用多重签名钱包来存放upgrade_cap,因此升级需要多个签名.
3.避免共享 upgrade_cap 对象 ID 或将其公之于众.
-
实施链下治理,在执行之前批准升级.
-
使用环境控制或基础设施白名单限制升级权限.
-
监控区块链交易以检测未经授权的升级尝试.
-
安全地备份 upgrade_cap 以避免失去升级能力.
-
请记住,丢失 upgrade_cap 意味着你无法再升级软件包了.
-
与 EVM 代理不同,Sui 的升级控制由不同的对象管理,而不是合约逻辑.
-
Move 代码本身不包含升级逻辑;它是通过 upgrade_cap 在外部处理的.
-
upgrade_cap 与软件包的元数据相关联,在查询软件包信息时可见:
sui 客户端获取软件包 <package_id>
-
在尝试升级之前,请务必验证 upgrade_cap 所有权.
-
升级时,软件包 ID 保持不变;只有代码会更改.
-
未经授权持有 upgrade_cap 允许恶意升级.
-
在操作环境中使用访问控制机制来保护升级交易.
-
设计您的 CI/CD 管道,使其需要手动批准步骤才能升级.
-
追踪团队或组织中谁持有 upgrade_cap 以追究责任.
-
如果需要,您可以将 upgrade_cap 对象转移到另一个账户,但要谨慎行事.
-
通过指定适当的燃气预算,保持升级交易的燃气效率.
-
将链上upgrade_cap控制与链下治理相结合是Sui上安全软件包升级的最佳实践.
To prevent unauthorized upgrades of a Move package on Sui, the core mechanism is the upgrade_cap object. This capability object grants exclusive authority to upgrade a deployed package. Without possessing the upgrade_cap, no one can upgrade the package, ensuring security.
When you publish a package via Sui CLI:
sui client publish --path ./my_package --gas-budget 10000
An upgrade_cap object is created and returned. This object ID must be provided when upgrading the package:
sui client upgrade --package ./new_package --upgrade-cap <upgrade_cap_object_id> --gas-budget 10000
To secure the upgrade process:
Store the upgrade_cap securely, such as in a hardware wallet or multisig wallet.
Use a multisig wallet to hold the upgrade_cap so multiple signatures are required for upgrades.
Avoid sharing the upgrade_cap object ID or exposing it publicly.
Implement off-chain governance to approve upgrades before execution.
Restrict upgrade access with environment controls or infrastructure whitelisting.
Monitor blockchain transactions to detect unauthorized upgrade attempts.
Back up the upgrade_cap securely to avoid losing upgrade ability.
Remember that losing the upgrade_cap means you cannot upgrade your package anymore.
Unlike EVM proxies, Sui’s upgrade control is managed by a distinct object, not contract logic.
The Move code itself does not hold upgrade logic; it's handled externally via the upgrade_cap.
The upgrade_cap is tied to the package’s metadata and visible when querying package info:
sui client get-package <package_id>
Always verify the upgrade_cap ownership before attempting upgrades.
When upgrading, the package ID remains constant; only the code changes.
Unauthorized possession of the upgrade_cap allows malicious upgrades.
Use access control mechanisms in your operational environment to protect upgrade transactions.
Design your CI/CD pipeline to require manual approval steps for upgrades.
Track who holds the upgrade_cap in your team or organization for accountability.
You can transfer the upgrade_cap object to another account if needed, but do so cautiously.
Keep upgrade transactions gas-efficient by specifying appropriate gas budgets.
Combining on-chain upgrade_cap control with off-chain governance is the best practice for secure package upgrades on Sui.
###1. 核心安全机制
Sui 使用upgrade caps(UpgradeCap
) 来控制软件包的可变性. 与 EVM 的不可变合约不同,Sui 允许升级,但有严格的所有权控制.
####关键属性
功能 | 描述 |
---|---|
upgradeCap | 授予升级权限的可转让对象 |
政策 | 定义允许的更改(向后兼容、累加、中断)的位标志 |
摘要验证 | 确保字节码与预期的哈希值匹配 |
###2. 实施模式
####基本不可变包
module my_pkg::governance {
use sui::package;
use sui::transfer;
use sui::tx_context;
// Burn upgrade cap at initialization
public fun init(ctx: &mut TxContext) {
let (upgrade_cap, _) = package::claim_upgrade_cap(ctx);
package::burn_upgrade_cap(upgrade_cap); // Permanent immutability
}
}
####DAO 控制的升级
module my_pkg::dao {
use sui::voting;
use sui::package;
struct DaoCap has key, store {
id: UID,
upgrade_cap: UpgradeCap,
threshold: u64
}
public entry fun authorize_upgrade(
dao: &mut DaoCap,
proposal_id: ID,
policy: u8,
digest: vector<u8>,
ctx: &mut TxContext
) {
assert!(voting::is_approved(proposal_id, dao.threshold), EACCESS_DENIED);
package::authorize_upgrade(&mut dao.upgrade_cap, policy, digest);
}
}
###3. CLI 执法
####以不可变方式部署
sui client publish --gas-budget 1000000000 --with-upgrade-capability false
###验证不可变性
sui client object <UPGRADE_CAP_ID> --json | grep "burned"
# Expected: "burned": true
###4. 安全最佳实践
####升级策略矩阵
| 政策标志 | 允许的更改 | 推荐用于 |
| -----------------------------| -----------------|
|0x1
(兼容)| 仅修复错误 | 稳定协议 |
|0x3
(增法)| 新功能 | 不断演变的系统 |
|0x7
(BREAKING)| 全部改动 | 早期开发 |
####多重签名保护
module my_pkg::multisig {
struct UpgradeVault has key {
id: UID,
cap: UpgradeCap,
required: u8,
approvals: vector<address>
}
public entry fun approve(
vault: &mut UpgradeVault,
signer: &signer
) {
let addr = signer::address_of(signer);
assert!(!vector::contains(&vault.approvals, &addr), EALREADY_APPROVED);
vector::push_back(&mut vault.approvals, addr);
if (vector::length(&vault.approvals) >= vault.required) {
package::authorize_upgrade(&mut vault.cap, POLICY_ADDITIVE, digest);
}
}
}
###5. 攻击向量和缓解措施
| 威胁 | 解决方案 | 移动示例 |
| ------------------| --------------|
struct TimedCap { unlock_epoch: u64 }
|Stolen Cap | 定时升级 | |
assert!(digest == expected_digest, EINVALID)
|恶意升级| 需要摘要验证 | |
required = 5/7
|治理收购| 渐进式去中心化 | 从多重签名开始 |
###6. 测试策略
####Localnet 试运行
sui client publish --upgrade-policy 1 --dry-run
# Verify no upgrade cap is created
####阴性测试用例
#[test(expected_failure = "EUPGRADE_NOT_AUTHORIZED")]
fun test_unauthorized_upgrade() {
let (_, publisher) = package::claim_upgrade_cap(ctx);
package::authorize_upgrade(&mut cap, 0x7, digest); // Should fail
}
###7. 监控和恢复
####链上验证
// TypeScript SDK check
const isImmutable = await client.getObject({
id: upgradeCapId,
options: { showContent: true }
}).then(obj => obj.data?.content?.type === '0x2::package::UpgradeCap');
####紧急冻结
public entry fun freeze_forever(cap: UpgradeCap) {
transfer::freeze_object(cap); // Makes cap non-transferable
}
###与 EVM 的主要差异化因素 | Aspect | Sui | EVM | | -------------| -----| |升级机制| 以对象为中心 | 代理模式 | |粒度| 每包控制 | 要么全有,要么全无 | |可审计性| 链上升级历史记录 | 不透明代理管理员 |
对于生产系统:
- 存
UpgradeCap
放在冷库中 - 实现带延时功能的多重签名 3.使用Sui Explorer监控升级提案
你知道答案吗?
请登录并分享。
Sui is a Layer 1 protocol blockchain designed as the first internet-scale programmable blockchain platform.

- ... SUIMatthardy+2095
- ... SUIacher+1666
- ... SUIjakodelarin+1092
- ... SUIChubbycheeks +1081
- ... SUITucker+1047
- ... SUIKurosakisui+1034
- ... SUIzerus+890