﻿---
title: "可升级智能合约"
description: "可升级智能合约在授权主体替换或重定向实现时，保留代理地址和状态。这种灵活性也带来存储、初始化、治理与监控风险。"
image: "https://wiki.fcontext.com/og.png"
---

> Documentation Index
> Fetch the complete documentation index at: https://wiki.fcontext.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 可升级智能合约

> 仅供教育参考，不构成投资或安全建议。可升级性可能赋予特权主体改变合约行为的权力，并可能导致损失。

<a id="answer"></a>

## 直接答案

可升级智能合约是指这样一种已部署系统：它无需让用户迁往新的主地址，也无需放弃该地址保存的状态，就能改变实际执行的逻辑。在兼容以太坊的网络上，常见设计是由代理保存状态，并通过 `delegatecall` 把调用转发给实现合约。获得授权的升级会更换代理使用的实现，而代理地址、存储和余额保持不变。

这并不是改写不可变字节码，而是在应用前增加一层间接寻址。升级机制可以修复缺陷、增加功能，但也建立了一条能够改变提款、费用、权限或记账方式的特权控制路径。因此，用户既要评估当前代码，也要评估未来代码由谁、按什么规则决定。

并非所有代理都可升级，也并非所有可变系统都采用代理。有些项目部署新合约并迁移状态，另一些则永久关闭升级能力。实际链上架构和权限比前端标签更重要。

<a id="mechanism"></a>

## 工作机制

调用者向代理地址发送交易后，代理读取实现地址，并通过 `delegatecall` 在代理的存储上下文中执行实现代码。代码来自实现合约，但读写作用于代理存储，原始调用者和附带价值也会保留。ERC-1967 统一了实现、Beacon 和管理员存储槽，便于工具识别常见代理部署。

透明代理把升级管理放在代理中，并区分管理员调用和用户调用。UUPS 代理把升级逻辑放在实现中，并使用基于 ERC-1822 的兼容接口，因此实现内的升级授权尤其关键。Beacon 代理从 Beacon 获取实现，一次 Beacon 更新就可能改变多个代理。不同模式具有不同的信任边界和失效方式。

状态兼容性是核心工程约束。新实现必须正确解释既有存储；调整变量顺序、删除变量或改变类型都可能破坏状态，继承关系变化也可能产生同样后果。仅追加布局、预留存储间隙或 ERC-7201 命名空间存储有助于管理演进，但仍须逐版本验证。

构造函数初始化的是实现自身，而不是代理存储。因此代理部署通常要为相应版本调用一次 `initialize` 等初始化器。实现应锁定直接初始化，后续迁移则应使用范围明确的再初始化器。公开或可重复调用的初始化器可能让攻击者夺取角色或覆盖配置。

稳健的升级流程包括：

1. 固定旧实现和拟议实现的源码、编译设置、依赖、存储布局、部署地址与预期字节码。
2. 审查代码差异、存储兼容性、初始化或迁移、授权、外部依赖与回滚假设，并在分叉环境中测试完整升级交易。
3. 公布提案与实现地址，严格执行公开声明的多签、治理和时间锁流程，不保留未披露的绕过路径。
4. 执行后核验实现槽或 Beacon 槽、事件、字节码、初始化状态、角色与关键不变量，并记录区块。
5. 持续监控存储槽、角色和参数变化，制定不假定回滚必然安全的事件响应方案。

<a id="example"></a>

## 示例

假设某借贷协议需要新增还款功能，其代理当前委托给实现 A。团队部署实现 B，确认 B 只在存储末尾追加变量，并准备迁移调用。治理方公布字节码，并将升级置于 48 小时时间锁之后。执行完成后，同一代理地址改为委托给 B，既有余额仍保存在代理存储中。

这套流程的可靠程度取决于控制措施。用户应确认实现槽确实由 A 变为 B、迁移只执行一次，并且角色和余额符合预期。如果守护者可以绕过时间锁，或签名人能把 B 换成任意代码，那么即使常规提案按公开流程执行，这些权力仍属于实际信任模型。

<a id="risks"></a>

## 风险

- **特权替换：**管理员、多签、治理合约或被盗密钥可以安装恶意或有缺陷的逻辑。
- **存储损坏：**不兼容的布局可能错误解释余额、所有者、映射或账务数据。
- **初始化失败：**遗漏、重复或暴露的初始化器可能使系统无法使用或转移控制权。
- **模式特有故障：**透明、UUPS、Beacon 和自定义代理的失效方式不同；模式名称不能证明实现正确。
- **治理表演：**公开声称的时间锁或投票可能存在紧急绕过、延迟过短、投票权集中或签名安全薄弱等问题。
- **不安全的迁移或回滚：**新版本可能不可逆地改变状态，恢复旧代码未必能恢复旧含义。
- **验证缺口：**实现源码经过验证，并不能单独证明代理指向它、使用预期管理员或具有预期初始化状态。
- **监控与集成风险：**区块浏览器、界面、审计方和集成方可能仍跟踪旧实现，或遗漏影响全部 Beacon 代理的更新。

<a id="misconceptions"></a>

## 常见误区

- **“这个地址上的合约不可变。”**代理字节码可能不可变，但实际行为可通过实现槽或 Beacon 槽改变。
- **“多签使升级实现去中心化。”**只有签名人相互独立、门槛、运维和更换规则都可靠时，它才真正减少对单一密钥的依赖。
- **“时间锁能阻止恶意升级。”**它只提供观察和退出时间，不能让拟议代码自动变得安全，也无法帮助不能退出的用户。
- **“存储检查通过就证明升级安全。”**它只处理布局兼容性，不覆盖业务逻辑、授权、预言机、迁移或经济错误。
- **“放弃升级权一定会消除控制。”**必须在链上检查管理员、Beacon、治理合约、UUPS 授权和替代路径；表面上的放弃可能仍留下其他通道。

<a id="related"></a>

## 相关主题

- [智能合约](/zh-cn/crypto/smart-contract/)
- [如何阅读智能合约审计](/zh-cn/crypto/contract-audit/)
- [多重签名钱包](/zh-cn/crypto/multisig-wallet/)
- [时间锁](/zh-cn/crypto/timelock/)

<a id="sources"></a>

## 来源

- [ERC-1967: Proxy Storage Slots](https://eips.ethereum.org/EIPS/eip-1967) - Ethereum Improvement Proposals（查阅日期：2026-08-22）
- [ERC-1822: Universal Upgradeable Proxy Standard (UUPS)](https://eips.ethereum.org/EIPS/eip-1822) - Ethereum Improvement Proposals（查阅日期：2026-08-22）
- [ERC-7201: Namespaced Storage Layout](https://eips.ethereum.org/EIPS/eip-7201) - Ethereum Improvement Proposals（查阅日期：2026-08-22）
- [Proxy Upgrade Pattern](https://docs.openzeppelin.com/upgrades-plugins/proxies) - OpenZeppelin Docs（查阅日期：2026-08-22）
- [Writing Upgradeable Contracts](https://docs.openzeppelin.com/upgrades-plugins/writing-upgradeable) - OpenZeppelin Docs（查阅日期：2026-08-22）
- [Proxy](https://docs.openzeppelin.com/contracts/5.x/api/proxy) - OpenZeppelin Docs（查阅日期：2026-08-22）
- [Layout of State Variables in Storage and Transient Storage](https://docs.soliditylang.org/en/latest/internals/layout_in_storage.html) - Solidity Documentation（查阅日期：2026-08-22）

Source: https://wiki.fcontext.com/zh-cn/crypto/upgradeable-contract/index.mdx
