用途:帮助开发者用 OpenZeppelin 代理模式升级 Solidity 智能合约,适用于实现 UUPS、Transparent 或 Beacon 可升级合约、执行 Hardhat 或 Foundry 升级流程、排查升级验证问题。
主要能力:介绍三种代理模式及选用建议——UUPS 升级逻辑在实现合约中(需重写 _authorizeUpgrade),Transparent 由独立 ProxyAdmin 管理,Beacon 通过共享 beacon 一次性升级多个代理;三者均使用 EIP-1967 存储槽。说明 v5 的 TransparentUpgradeableProxy 会自动部署 ProxyAdmin 并把 admin 存为 immutable,构造参数为 owner 地址,与 v4 不同。
编写规则:用初始化函数替代构造函数,顶层 initialize 使用 initializer 修饰符,父级 __X_init 需显式调用并只调用一次;构造函数中调用 _disableInitializers() 防止实现合约被直接初始化;不要在字段声明处设置初值(constant 安全,immutable 默认被视为不安全)。基础合约从 @openzeppelin/contracts-upgradeable 导入,接口和库从 @openzeppelin/contracts 导入,v5.5+ 起 Initializable 和 UUPSUpgradeable 也应直接从 @openzeppelin/contracts 导入。
存储规则:升级时不得重排、删除或改类型,不得在已有变量前插入,只能追加;不得更改继承顺序。推荐 ERC-7201 命名空间存储,需通过命令计算 STORAGE_LOCATION:node -e "..." "example.main",不可留 0x... 占位。命名空间 id 不得冲突,删除命名空间会被判为错误。
工作流:Hardhat 安装 npm install --save-dev @openzeppelin/hardhat-upgrades 及 peer 依赖,注册插件后用 upgrades 对象的 deployProxy、upgradeProxy 等函数,插件会校验升级安全性并在 .openzeppelin/ 记录实现地址;用 prepareUpgrade 可先验证部署实现。Foundry 需 forge install OpenZeppelin/openzeppelin-foundry-upgrades 等依赖,配置 ffi、ast、build_info、extra_output,依赖 Node.js,使用 Upgrades.deployUUPSProxy / upgradeProxy,升级前需用 /// @custom:oz-upgrades-from 标注,UnsafeUpgrades 跳过校验不应在生产使用。
限制:不支持将代理实现从 OpenZeppelin v4 升级到 v5(存储布局机制不同),建议用 v5 部署新代理并迁移用户;不使用 selfdestruct、不向不可信合约 delegatecall;V2 及以上需新初始化逻辑时使用 reinitializer(2);安全清单涵盖存储兼容、初始化保护、选择器冲突、_authorizeUpgrade 权限、测试升级路径等。详细 API 请查阅所安装插件的 README 或源码。