一、作用以及优点
- 部署可升级合约,插件自动部署proxy和proxyAdmin合约,帮助管理合约升级和交互;
- 升级已部署合约,通过插件快速升级合约,脚本开发方便快捷;
- 管理代理管理员的权限,只有proxyAdmin的owner才有权限升级,权限可转移;
- 插件自动检测合约是否可升级,无需人工check代码,高效快捷;
二、使用方法--基于hardhat框架(引用:官网文档)
2.1 安装插件
通过以下命令来安装需要的插件:
npm install --save-dev @openzeppelin/hardhat-upgrades @nomiclabs/hardhat-ethers ethers
安装完成后,将其加载到您的 Hardhat 配置文件中:
// hardhat.config.js
require('@openzeppelin/hardhat-upgrades');
2.2 插件使用
Hardhat 用户将能够编写使用该插件部署或升级合约的脚本,并管理代理管理员权限:
deployProxy完成的工作:
验证实现合约是可安全升级的;
- 为项目部署ProxyAdmin合约,如果不存在的话;
- 部署实现合约;
- 部署并实例化代理合约;
upgradeProxy完成的工作:
- 验证新的实现合约是可安全升级的,并且和之前的实现合约兼容;
- 升级代理以使用新的实现合约;
插件会追踪.openzeppelin目录下的文件,每个网络一个文件,文件内记录了ProxyAdmin合约地址,Proxies合约和实现合约地址,文件的名称是{unknown-chainId}.json。如果属于某个网络的json文件已存在,那么ProxyAdmin合约不再重新部署。如果属于某个网络的json文件不存在,那么直接升级到新的实现合约会报错:
升级时必须有unknown-chainId.json文件提供上下文信息。
2.3 注意事项
编写升级合约时需要注意:
不要给变量设置初始值,如果必须要设置的话,需要使用 /// @custom:oz-upgrades-unsafe-allow state-variable-immutable 注释在合约代码中标记,或者在升级脚本中使用state-variable-assignment,例如:await upgrades.upgradeProxy(contract.address, BoxV2, {unsafeAllow: ['state-variable-assignment', 'delegatecall']})来禁用检查;
不要改变变量名,如果非要改变变量名,需要使用/// @custom:oz-renamed-from x 来禁用检查;
不要改变变量类型;
升级交易必须由ProxyAdmin合约的owner发起,否则交易会报错;
更多注意事项和使用技巧可查看官方文档:官方文档