摘要
通过 loader-v3 部署的程序在设置了升级权限时可以升级。撤销权限会使程序变为不可变。本文涵盖升级机制、loader-v3 部署和升级指令、构建验证以及可用的加载器程序。
部署程序
升级程序
要升级程序,账户必须拥有升级权限(通常是最初部署该程序的账户)。在部署或升级过程中,新字节码会被上传到临时缓冲区账户,然后写入 programdata
account。将升级权限设置为 None 后,程序将变为不可变,永久禁止后续更新。
升级机制
当
UpgradeableLoaderInstruction::Upgrade
被处理时,运行时会:
- 验证 Program account 可写且归 loader-v3 所有。
- 验证 Buffer account 包含具有正确权限的
Buffer状态。 - 验证 ProgramData account 的
upgrade_authority_address匹配且不为None。 - 验证该程序未在当前 slot (
clock.slot != slot) 中已部署。 - 从缓冲区加载并验证新的 ELF 字节码。
- 将新字节码从缓冲区复制到 ProgramData account,并将剩余字节清零。
- 为 ProgramData account 提供租金豁免所需资金。
- 清空缓冲区账户(将 lamports 设为 0)并截断其数据。
- 新版本将在下一个 slot (
deployment_slot + 1) 生效。
Program 账户本身(其状态和 programdata_address
指针)在升级过程中不会发生变化。只有 ProgramData
账户的字节码和 slot 元数据会被更新。
Loader-v3 指令参考
Loader-v3(BPF Loader Upgradeable)是当前在 Solana 上部署程序的默认加载器。
| 指令 | 描述 |
|---|---|
InitializeBuffer | 将缓冲区账户的状态设置为 Buffer 并指定权限。如果已初始化则失败。 |
Write | 在缓冲区账户中指定偏移量处写入字节。权限持有者必须签名。 |
DeployWithMaxDataLen | 创建新程序:派生 ProgramData 地址,通过 CPI 调用 System Program 创建 ProgramData 账户,验证并部署来自缓冲区的 ELF,设置 Program 账户状态并将其标记为可执行。 |
Upgrade | 从缓冲区替换现有程序 ProgramData 账户中的字节码。 |
SetAuthority | 更改 Buffer 或 ProgramData 账户的权限。在 ProgramData 上设置为 None 会使程序变为不可变。Buffer 权限不能设置为 None。 |
SetAuthorityChecked | 类似于 SetAuthority,但要求新权限持有者也签署交易。 |
Close | 通过将 lamport 转移给接收者来关闭缓冲区、未初始化或 ProgramData 账户。关闭 ProgramData 还会向程序缓存写入 Closed 墓碑标记。无法关闭在当前 slot 中部署的程序。 |
ExtendProgramChecked | 按指定字节数扩展 ProgramData 账户的分配空间,额外的租金由付款人提供。 |
验证程序
Solana 支持可验证构建,允许用户确认程序的链上字节码与其公开源代码匹配。Anchor 框架为可验证构建提供了内置支持。
要检查已部署程序的验证状态,请在 Solana Explorer 上搜索其程序 ID,或使用 Ellipsis Labs 的 Solana Verifiable Build CLI 独立验证链上程序。
加载器程序
| 加载器 | 地址 | 可升级性 | 描述 |
|---|---|---|---|
| 原生加载器 | NativeLoader1111111111111111111111111111111 | 仅通过验证器软件升级 | 拥有内置程序(系统、投票、质押)和其他加载器 |
| BPF 加载器 (v1) | BPFLoader1111111111111111111111111111111111 | 否(加载器管理已禁用) | 旧版程序 |
| BPF 加载器 (v2) | BPFLoader2111111111111111111111111111111111 | 否(加载器管理已禁用) | 旧版程序 |
| BPF 可升级加载器 | BPFLoaderUpgradeab1e11111111111111111111111 | 是,如果设置了升级权限 | 拥有所有新部署的程序 |
Is this page helpful?