升级合同
您可以从命令行升级打包的合同。
以下步骤说明如何升级示例标记化存款合同项目。有关其他打包合同,请参见与合同包捆绑在一起的 README 文件。
升级会更改现有代理背后的实现;它不会创建新代理或重置其存储。
Hardhat 命令行界面支持升级合同。如果您使用 RPC 代理 API 部署了智能合同,则该合同不可变且无法升级。
该参考项目包括用于演示和测试的 V2 实施:
- 令牌:
contracts/TokenizedDeposit/_testContracts/TokenizedDepositUpgradeableV2.sol - 账户:
contracts/obp-sdk/accounts/modules/v1/_testContracts/AccountWithERC5982UUPSV2.sol
version() 公开为 v2.0.0 ,并包括空的 initializeV2() 重新初始化程序。将它们视为参考代码;查看它们并将其替换为您自己的兼容实施以进行实际升级。
要升级合同,您需要合同的代理地址、配置的 Oracle Blockchain Platform Besu 网络以及提交监管建议的权限。部署的合同必须处于有效状态,并且符合其配置的升级授权路径的条件。
在修改实施之前,请保持存储兼容性。仅附加存储字段。请勿重新排序、删除或更改现有字段的类型、更改继承的存储布局或绕过升级验证。如果更改不兼容,请部署新的代理并显式迁移状态。
注意:
必须指向升级的源。IMPLEMENTATION_CONTRACT 变量将传递给 Hardhat 的合同工厂。将其设置为升级版本的完全合格 Solidity 合同名称。<path-to-upgraded-contract>.sol:<upgraded-contract-name>请勿将变量指向当前 V1 合同。例如,以下示例显示了标记化保证金 V2 参考实施。contracts/TokenizedDeposit/_testContracts/TokenizedDepositUpgradeableV2.sol:TokenizedDepositUpgradeableV2如果创建不同的 V3 或定制实现,请将命令中的路径和合同名称替换为该升级的源。在更改后和运行 prepare 命令之前进行编译。
升级令牌代理
- 运行以下命令以准备令牌升级。准备验证实施和存储布局,部署确切的新实施,在升级清单中记录其代码散列和库地址,并提交所需的监管意图。它尚未升级代理。
UPGRADE_ACTION=prepare \ GOVERNANCE_INTENT_MODE=obp-besu \ TOKEN_PROXY=<token-proxy-address> \ IMPLEMENTATION_CONTRACT='contracts/TokenizedDeposit/_testContracts/TokenizedDepositUpgradeableV2.sol:TokenizedDepositUpgradeableV2' \ LIBRARIES_JSON='{"ERC20TokenHelperLib":null,"ERC20MultiLevelApprovalHelperLib":null}' \ DEPLOY_LIBRARIES=true \ INITIALIZER_DATA=0x \ UPGRADE_MANIFEST=.obp-da/upgrades/deposittoken-v2.json \ npx hardhat run scripts/upgrade/upgrade-deposittoken.ts --network obp-besu将
DEPLOY_LIBRARIES设置为true时,将部署空的库条目,其地址将成为审查的实施代码散列的一部分。要重用库,请在LIBRARIES_JSON变量中提供现有的兼容库地址。INITIALIZER_DATA变量是传递到upgradeToAndCall函数的原始 ABI 编码的 calldata。为提供的参考 V2 合同使用 0x,因为其initializeV2()为空。如果您的新实施需要初始化,请提供正确编码的重新初始化程序 calldata 并将其作为升级建议的一部分进行检查。 - 批准治理建议。如果
GOVERNANCE_INTENT_MODE变量设置为obp-besu,则准备步骤将通过 Oracle Blockchain Platform RPC 代理提交建议书。获取目标监管配置所需的审批。代理保持其旧实施状态,直到提案获得批准并执行步骤完成。仅当项目配置为直接向合同提交监管意向(而不是通过 Oracle Blockchain Platform 端点)时,才使用GOVERNANCE_INTENT_MODE=json-rpc。 - 运行令牌升级。在获得批准后,运行与
prepare命令相同的清单。
在调用UPGRADE_ACTION=execute \ UPGRADE_MANIFEST=.obp-da/upgrades/deposittoken-v2.json \ npx hardhat run scripts/upgrade/upgrade-deposittoken.ts --network obp-besuupgradeToAndCall函数之前,脚本将验证清单链 ID、最后期限和准备好的实现字节码散列。
升级帐户代理
- 运行以下命令以准备账户升级。
将UPGRADE_ACTION=prepare \ GOVERNANCE_INTENT_MODE=obp-besu \ ACCOUNT_PROXY=<account-proxy-address> \ IMPLEMENTATION_CONTRACT='contracts/obp-sdk/accounts/modules/v1/_testContracts/AccountWithERC5982UUPSV2.sol:AccountWithERC5982UUPSV2' \ LIBRARIES_JSON='{}' \ DEPLOY_LIBRARIES=false \ INITIALIZER_DATA=0x \ UPGRADE_MANIFEST=.obp-da/upgrades/deposittoken-account-v2.json \ npx hardhat run scripts/upgrade/upgrade-account.ts --network obp-besuIMPLEMENTATION_CONTRACT变量的全限定值替换为新账户实施的路径和合同名称。不要将令牌的源路径、代理地址或清单重用于账户升级。 - 在账户升级建议收到所需的监管审批后,运行以下命令以批准并完成账户升级。
UPGRADE_ACTION=execute \ UPGRADE_MANIFEST=.obp-da/upgrades/deposittoken-account-v2.json \ npx hardhat run scripts/upgrade/upgrade-account.ts --network obp-besu
故障排除
| 条件 | 解决方法 |
|---|---|
| 准备失败的存储验证 | 请勿强制升级。更正不兼容的布局更改,或者部署新的代理并迁移状态。 |
| 以前的准备清单已过期或针对不同的实施 | 通过设置 REPREPARE=true 并将旧清单保留为审计记录,故意创建替换。
|
| 执行在审批前运行 | 首先获得治理审批。在准备好的升级变为可执行之前,需要批准意图。 |
| 选择了错误的实施 | 验证 IMPLEMENTATION_CONTRACT 变量是否使用升级的源的全限定 path:contract 值,然后重新编译并准备新清单。切勿执行为其他实现准备的清单。
|
| 重新运行执行 | 该脚本检测已升级的代理,并记录结果而不是发送第二个升级事务处理。对于缺少 implementationContract 的较旧清单,在执行时提供相同的 IMPLEMENTATION_CONTRACT 值,以便可以同步实施历史记录。
|