Actualización de un contrato

Puede actualizar un contrato empaquetado desde la línea de comandos.

Los siguientes pasos muestran cómo actualizar el proyecto de contrato de depósito con token de muestra. Para otros contratos empaquetados, consulte el archivo README que se incluye con el paquete de contratos.

Una actualización cambia la implementación detrás del proxy existente; no crea un nuevo proxy ni restablece su almacenamiento.

La interfaz de línea de comandos de Hardhat admite la actualización de contratos. Si ha desplegado un contrato inteligente mediante la API de proxy de RPC, es inmutable y no se puede actualizar.

El proyecto de referencia incluye implementaciones V2 para demostración y prueba:
  • Token: contracts/TokenizedDeposit/_testContracts/TokenizedDepositUpgradeableV2.sol
  • Cuenta: contracts/obp-sdk/accounts/modules/v1/_testContracts/AccountWithERC5982UUPSV2.sol
Los contratos V2 conservan el diseño de almacenamiento V1, exponen version() como v2.0.0 e incluyen un reinicializador initializeV2() vacío. Trátelos como código de referencia; revíselos y sustitúyalos por su propia implantación compatible para una actualización real.

Para actualizar un contrato, necesita la dirección proxy del contrato, una red de Besu de Oracle Blockchain Platform configurada y la autoridad para enviar la propuesta de gobernanza. El contrato desplegado debe estar activo y ser elegible para la ruta de autorización de cambio de versión configurada.

Antes de modificar una implementación, conserve la compatibilidad del almacenamiento. Agregar sólo campos de almacenamiento. No reordene, elimine ni cambie el tipo de campos existentes, modifique el diseño de almacenamiento heredado ni omita la validación de actualización. Si el cambio es incompatible, despliegue un nuevo proxy y migre explícitamente el estado en su lugar.

Nota:

Debe apuntar al origen actualizado. La variable IMPLEMENTATION_CONTRACT se transfiere a la fábrica de contratos de Hardhat. Defínalo en el nombre completo del contrato de Solidity para la versión actualizada.
<path-to-upgraded-contract>.sol:<upgraded-contract-name>
No apunte la variable al contrato V1 actual. Por ejemplo, la implementación de referencia de depósito tokenizado V2 se muestra en el siguiente ejemplo.
contracts/TokenizedDeposit/_testContracts/TokenizedDepositUpgradeableV2.sol:TokenizedDepositUpgradeableV2
Si crea una implementación personalizada o V3 diferente, sustituya la ruta y el nombre del contrato en el comando por ese origen actualizado. Compile después del cambio y antes de ejecutar el comando prepare.

Actualización del proxy de token

  1. Ejecute el siguiente comando para preparar la actualización del token. La preparación valida el diseño de implementación y almacenamiento, despliega la nueva implementación exacta, registra el hash de código y las direcciones de biblioteca en un manifiesto de actualización y envía la intención de gobernanza necesaria. Aún no actualiza el proxy.
    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

    Con DEPLOY_LIBRARIES definido en true, se despliega una entrada de biblioteca nula y su dirección pasa a formar parte del hash del código de implantación revisado. Para reutilizar bibliotecas, proporcione las direcciones de biblioteca compatibles existentes en la variable LIBRARIES_JSON. La variable INITIALIZER_DATA es datos de llamada codificados ABI sin formato transferidos a la función upgradeToAndCall. Utilice 0x para los contratos V2 de referencia proporcionados porque initializeV2() está vacío. Si es necesario inicializar la nueva implantación, proporcione los datos de llamada del reinicializador correctamente codificados y revíselos como parte de la propuesta de actualización.

  2. Aprobar la propuesta de gobernanza. Si la variable GOVERNANCE_INTENT_MODE se define en obp-besu, el paso de preparación envía la propuesta a través del proxy RPC de Oracle Blockchain Platform. Obtenga las aprobaciones necesarias para la configuración de gobernanza de destino. El proxy permanece en su antigua implementación hasta que se aprueba la propuesta y se completa el paso de ejecución. Utilice GOVERNANCE_INTENT_MODE=json-rpc solo cuando el proyecto esté configurado para enviar la intención de gobernanza directamente al contrato en lugar de hacerlo a través del punto final de Oracle Blockchain Platform.
  3. Ejecute la actualización del token. Después de la aprobación, ejecute el mismo manifiesto que escribió el comando prepare.
    UPGRADE_ACTION=execute \
    UPGRADE_MANIFEST=.obp-da/upgrades/deposittoken-v2.json \
    npx hardhat run scripts/upgrade/upgrade-deposittoken.ts --network obp-besu
    El script verifica el ID de cadena de manifiesto, la fecha límite y el hash de código de byte de implementación preparado antes de llamar a la función upgradeToAndCall.

Actualización del proxy de cuenta

  1. Ejecute el siguiente comando para preparar la actualización de la cuenta.
    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-besu
    
    Sustituya el valor totalmente cualificado de la variable IMPLEMENTATION_CONTRACT por la ruta y el nombre de contrato de la nueva implantación de cuenta. No reutilice la ruta de origen, la dirección proxy ni el manifiesto del token para una actualización de cuenta.
  2. Después de que la propuesta de actualización de la cuenta reciba las aprobaciones de gobernanza necesarias, ejecute el siguiente comando para aprobar y completar la actualización de la cuenta.
    UPGRADE_ACTION=execute \
    UPGRADE_MANIFEST=.obp-da/upgrades/deposittoken-account-v2.json \
    npx hardhat run scripts/upgrade/upgrade-account.ts --network obp-besu

Solución de problemas

Condición Resolución
Preparar validación de almacenamiento con fallos No fuerce la actualización. Corrija el cambio de diseño incompatible o despliegue un nuevo proxy y migre el estado.
Un manifiesto de preparación anterior ha caducado o tiene como destino una implementación diferente Cree una sustitución deliberadamente configurando REPREPARE=true y conservando el manifiesto antiguo como un registro de auditoría.
La ejecución se ejecuta antes de la aprobación Obtenga primero las aprobaciones de gobernanza. Se necesita una intención aprobada antes de que la actualización preparada se convierta en ejecutable.
Se ha seleccionado una implementación incorrecta Verifique que la variable IMPLEMENTATION_CONTRACT utilice el valor path:contract totalmente cualificado del origen actualizado y, a continuación, recompile y prepare un nuevo manifiesto. Nunca ejecute un manifiesto preparado para una implementación diferente.
La ejecución se vuelve a ejecutar El script detecta un proxy que ya está actualizado y registra el resultado en lugar de enviar una segunda transacción de actualización. Para un manifiesto anterior que carece de implementationContract, proporcione el mismo valor IMPLEMENTATION_CONTRACT al ejecutarlo para que se pueda sincronizar el historial de implementación.