分析跨区块链的可升级性模式 – ImmuneBytes

本文深入探讨了智能合约可升级性在不同区块链生态系统中的实现模式、权衡以及潜在的安全风险。文章详细介绍了以太坊的代理模式、Solana的程序权限、Cosmos的治理驱动迁移和Substrate的运行时升级,并强调了安全升级的最佳实践,指出可升级性在提供灵活性的同时,也带来了复杂性和责任。

2026年2月24日

引言

智能合约曾因其不可变性而备受赞誉。代码一旦部署就无法更改,这一理念既是其特点也是其缺陷。随着协议的成熟和用户需求的发展,开发者们意识到了固定逻辑的局限性。可升级性成为了解决方案。但它也付出了代价。每种升级机制都引入了新的复杂性、新类别的错误以及新的攻击面。

在过去几年中,我们审计了以太坊、Solana、Cosmos 和其他生态系统中的智能合约。一个反复出现的主题是开发者们尝试使其合约更具灵活性的创新——有时甚至是危险——方式。这篇博客深入探讨了现有的不同可升级性模式,它们在底层是如何实现的,以及它们可能出错的地方。

权衡:灵活性与最终性

不可变性在理论上听起来很完美。但无论你的智能合约写得多么好,错误总会发生。业务逻辑会演变。治理会改变。如果没有升级途径,不可变合约中的一个错误可能会永远锁定数百万美元。另一方面,升级能力可能会损害对去中心化的信任,并为 rug pulls、后门或意外“变砖”打开大门。

找到正确的平衡点至关重要。但要实现这一点,你需要了解可升级性的设计空间。

EVM 链中的可升级性

基于代理的模式

以太坊和其他 EVM 链中最广泛采用的方法是代理委托(proxy delegation)。在这种方法中,用户与一个代理合约交互,该代理合约使用 delegatecall 将逻辑执行转发给一个单独的实现合约(implementation contract)。

有几种常见的变体:

透明代理(Transparent Proxy)

使用一个 admin 账户来授权升级。只有 admin 才能调用升级函数;其他调用则转发到逻辑合约。这里最大的风险是意外地将升级函数暴露给公众或弄乱存储槽(storage slots)。

UUPS (通用可升级代理标准)

UUPS(通用可升级代理标准)不依赖外部 admin 代理,而是由实现合约包含升级逻辑。它更节省 gas 且更模块化,但如果升级授权逻辑没有得到适当保护,风险也更高。

信标代理(Beacon Proxy)

Beacon Proxy 专为多个代理共享相同实现逻辑的扩展用例而设计。一个 beacon 合约存储当前逻辑合约的地址。当它更新时,所有代理都会自动指向新的实现。由于共享逻辑的风险,这种模式更难安全地管理。

存储布局陷阱

EVM 环境中的可升级合约需要精确控制存储布局(storage layout)。代理合约和逻辑合约变量之间的任何不匹配都可能导致灾难性的损坏。Solidity 不强制执行布局一致性,因此一个错位的变量就可能悄无声息地破坏一切。

Solana:通过 Program Authorities 进行升级

Solana 智能合约(称为 programs)被编译成 BPF 字节码,并以指定的“升级权限”(upgrade authority)部署到链上。如果此账户持有必要的密钥,它可以在任何时候部署新版本的 program。

虽然 Solana 的升级模型在某些方面更简单,但它带来了中心化风险。如果升级权限是一个单一的热钱包,那么任何妥协了该热钱包的人都可以替换整个合约。我们看到一些项目推迟去中心化过长时间,有些甚至从未撤销其权限。这完全违背了使用 Solana 安全、高性能运行时的初衷。

Solana 还引入了程序派生地址(program-derived addresses, PDAs)相关的风险。一些开发者在升级过程中错误或不一致地使用 bumps,导致状态冲突或无法访问关键数据账户。

Cosmos 和 CosmWasm:治理驱动的迁移

使用 CosmWasm 构建的 Cosmos 合约允许通过 migrate 入口点进行显式迁移。这种模式的优点在于升级逻辑是合约本身的一部分。当通过链上治理提出并批准升级时,新的 WASM 字节码被上传,然后执行继续。

由于状态自动保留且迁移逻辑明确定义,存储不匹配的风险较低。然而,不正确的迁移代码或治理层中的权限错误仍然可能导致问题。

我们遇到的一个常见问题是迁移逻辑中缺乏验证;合约通常假定存储中存在某些值而不进行检查,这导致升级后出现恐慌或不变量被破坏。

Substrate/Polkadot:运行时级别升级

在 Polkadot 和其他基于 Substrate 的链中,整个 runtime 可以通过治理提案进行替换。这允许进行强大、协调的升级,但同时也引入了复杂性。你升级的不是单个合约,而是整个链的逻辑。

对于用 Ink! (Substrate 的智能合约语言) 编写的合约,升级并非原生支持。你通常需要部署一个新合约并手动迁移状态,除非你已经构建了自定义的升级机制。这赋予了开发者灵活性,但安全性的重担则完全落在了他们身上。

跨生态系统的安全陷阱

无论底层链是什么,风险都可归结为以下几个关键类别:

  • 不当的访问控制:将升级函数暴露给未经授权的用户是一个常见的关键问题。无论是以太坊中泄露的 admin 密钥,还是 Solana 上未撤销的 authority,控制权都至关重要。
  • 状态损坏:在 EVM 中,这通常是由于存储布局不匹配导致的。在 CosmWasm 中,这通常是不安全的迁移逻辑造成的。在 Substrate 中,则通常是由于开发者定义的迁移错误导致的。
  • 合约变砖:升级失败可能会使合约处于无法使用的状态。例如,一个错误地禁用升级函数的 UUPS 合约将永远无法再次升级。或者在 Solana 中,在上传正确的二进制文件之前意外撤销升级权限可能会冻结系统。
  • 治理漏洞:在允许治理控制升级的链上,糟糕的法定人数阈值或投票操纵可能允许恶意行为者强行进行用户不希望的升级。

真实案例和经验教训

  • 2022 年,一个主要的以太坊 DeFi 协议进行了一次升级,却意外覆盖了关键的存储变量,冻结了数十亿美元的 TVL,直到部署了热修复程序。

  • 一个基于 Solana 的项目因为在不同版本中错误地计算了 bumps,导致失去了对其 PDA vault 的访问权限。

  • 在 Cosmos 中,配置错误的迁移逻辑导致一些用户在升级后余额被清零,迫使链停止运行并进行手动恢复。

每个生态系统都有自己的故事。共同的主题总是相同的:可升级性功能强大,但默认情况下很少是安全的。

设计更安全的升级

作为安全研究人员,我们倾向于将可升级性视为一种特权且危险的操作。如果你必须使用它,我们建议如下:

  • 将升级访问权限锁定在 multisig 或 timelock 合约之后。
  • 始终在分叉的主网环境中模拟你的升级。
  • 明确验证不同版本之间的存储布局。
  • 详细记录每个升级路径,包括预期结果和失败场景。
  • 如果你的生态系统支持治理升级,请强制执行严格的法定人数和投票期。

最重要的是:制定回滚计划。即使你认为升级是万无一失的。

最终想法

可升级性并非区块链系统中的缺陷。它是许多生产协议中的必需品。但它也是合约可能拥有的最危险的功能之一。无论你是在以太坊中使用 delegatecall,Solana 中的升级权限,还是 Cosmos 中的迁移Hook,有一点始终不变:你正在用不可变性来换取责任。

这不仅仅是编写可升级合约的问题。而是要设计不会损害用户信任、去中心化或安全性的升级路径。

在这方面,真正的模式不仅仅是代码,更是谨慎。

  • 原文链接: blog.immunebytes.com/202...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
ImmuneBytes
ImmuneBytes
Stay Ahead of the Security Curve.