Upgrades Plugins
概述
安装和使用
请参阅 Hardhat Upgrades 或 Foundry Upgrades 的文档。
插件如何工作
这些插件提供了一些函数,可以处理合约的可升级部署管理。
例如,deployProxy
执行以下操作:
当您调用 upgradeProxy
时:
Hardhat 插件会跟踪您在项目根目录中的 .openzeppelin
文件夹中部署的所有实现合约以及代理管理员。 您将在此处找到每个网络一个文件。 建议您将除开发网络之外的所有网络的文件提交到源代码控制(您可能会看到它们为 .openzeppelin/unknown-*.json
)。
Foundry 插件不跟踪实现合约,但要求您 定义参考合约,以便验证新版本的实现的升级安全性。
代理模式
这些插件支持 UUPS、透明和信标代理模式。UUPS 和透明代理是单独升级的,而任何数量的信标代理可以通过升级它们指向的信标同时进行原子升级。 有关可用不同代理模式的更多详细信息,请参阅 Proxies 的文档。
对于 UUPS 和透明代理,请使用 deployProxy
和 upgradeProxy
。 对于信标代理,请使用 deployBeacon
、deployBeaconProxy
和 upgradeBeacon
。 有关示例,请参见 Hardhat Upgrades 和 Foundry Upgrades 的文档。
管理所有权
透明代理定义了一个 admin 地址,该地址有权升级它们。 默认情况下,admin 是在后台部署的 代理管理合约。 请记住,代理的 admin 只能升级它,但不能与实现合约交互。 阅读 透明代理和函数冲突 以获取有关此限制的更多信息。
代理管理合约还定义了一个 owner 地址,该地址有权操作它。 默认情况下,如果提供了透明代理部署期间使用的 initialOwner
地址,则代理管理员的所有者是该地址,否则是部署期间使用的外部拥有的帐户。 您可以通过调用 Hardhat 插件中的 admin.transferProxyAdminOwnership
函数,或者如果使用 Foundry,则调用代理管理合约的 transferOwnership
函数来更改代理管理员所有者。
警告:不要重用已部署的 ProxyAdmin
。 在 @openzeppelin/contracts
5.x 版本之前,提供给透明代理的地址是一个 initialAdmin
,而不是新部署的 ProxyAdmin
的 initialOwner
。 重用 ProxyAdmin
将禁用合约中的可升级性。
UUPS 和信标代理不使用管理地址。 UUPS 代理依赖于 _authorizeUpgrade
函数被覆盖以包括对升级机制的访问限制,而信标代理只能由其相应信标的所有者升级。
将升级代理或信标的权限转移到另一个地址后,您仍然可以使用本地设置来验证和部署实现合约。 这些插件包含一个 prepareUpgrade
函数,该函数将验证新的实现是否升级安全并且与先前的实现兼容,并使用您的本地 Ethereum 帐户进行部署。 然后,您可以从未管理地址或所有者地址执行升级本身。 您还可以使用 defender.proposeUpgrade
或 defender.proposeUpgradeWithApproval
函数来自动在 OpenZeppelin Defender 中进行升级设置。