Aggiorna un contratto

È possibile aggiornare un contratto in pacchetto dalla riga di comando.

I passi riportati di seguito mostrano come aggiornare il progetto del contratto di deposito con token di esempio. Per altri contratti in pacchetto, vedere il file README in bundle con il pacchetto contratto.

Un aggiornamento modifica l'implementazione dietro il proxy esistente; non crea un nuovo proxy né ripristina la memoria.

L'interfaccia della riga di comando Hardhat supporta l'aggiornamento dei contratti. Se hai distribuito uno smart contract utilizzando l'API proxy RPC, questo non è modificabile e non può essere aggiornato.

Il progetto di riferimento include implementazioni V2 per dimostrazioni e test:
  • Token: contracts/TokenizedDeposit/_testContracts/TokenizedDepositUpgradeableV2.sol
  • Account: contracts/obp-sdk/accounts/modules/v1/_testContracts/AccountWithERC5982UUPSV2.sol
I contratti V2 conservano il layout di storage V1, espongono version() come v2.0.0 e includono un reinizializzatore initializeV2() vuoto. Trattali come codice di riferimento; rivedili e sostituiscili con la tua implementazione compatibile per un aggiornamento effettivo.

Per eseguire l'upgrade di un contratto è necessario l'indirizzo proxy del contratto, una rete Besu di Oracle Blockchain Platform configurata e l'autorità per sottomettere la proposta di governance. Il contratto distribuito deve essere attivo e idoneo per il percorso di autorizzazione all'aggiornamento configurato.

Prima di modificare un'implementazione, preservare la compatibilità dello storage. Aggiungere solo i campi di memorizzazione. Non riordinare, rimuovere o modificare il tipo di campi esistenti, modificare il layout di memorizzazione ereditato o ignorare la convalida dell'aggiornamento. Se la modifica non è compatibile, distribuire un nuovo proxy ed eseguire la migrazione esplicita dello stato.

Nota:

È necessario puntare all'origine aggiornata. La variabile IMPLEMENTATION_CONTRACT viene passata alla fabbrica a contratto di Hardhat. Impostarlo sul nome del contratto Solidity completamente qualificato per la versione aggiornata.
<path-to-upgraded-contract>.sol:<upgraded-contract-name>
Non puntare la variabile al contratto V1 corrente. Ad esempio, l'implementazione di riferimento Deposito Tokenizzato V2 è illustrata nell'esempio seguente.
contracts/TokenizedDeposit/_testContracts/TokenizedDepositUpgradeableV2.sol:TokenizedDepositUpgradeableV2
Se si crea un'implementazione V3 o personalizzata diversa, sostituire il percorso e il nome del contratto nel comando con l'origine aggiornata. Compilare dopo la modifica e prima di eseguire il comando prepare.

Aggiorna proxy token

  1. Eseguire il comando seguente per preparare l'aggiornamento del token. Preparation convalida il layout di implementazione e storage, distribuisce la nuova implementazione esatta, registra l'hash del codice e gli indirizzi della libreria in un file manifesto di aggiornamento e sottomette l'intento di governance richiesto. Non aggiorna ancora il 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 impostato su true, viene distribuita una voce di libreria nulla e il relativo indirizzo diventa parte dell'hash del codice di implementazione rivisto. Per riutilizzare le librerie, specificare gli indirizzi delle librerie compatibili esistenti nella variabile LIBRARIES_JSON. La variabile INITIALIZER_DATA è dati di chiamata raw con codifica ABI passati alla funzione upgradeToAndCall. Utilizzare 0x per i contratti V2 di riferimento forniti perché il relativo initializeV2() è vuoto. Se la nuova implementazione deve essere inizializzata, fornire i dati di chiamata del reinizializzatore codificati correttamente ed esaminarli come parte della proposta di aggiornamento.

  2. Approvare la proposta di governance. Se la variabile GOVERNANCE_INTENT_MODE è impostata su obp-besu, il passo di preparazione sottomette la proposta tramite il proxy RPC di Oracle Blockchain Platform. Ottenere le approvazioni richieste dalla configurazione della governance della destinazione. La delega rimane sulla sua vecchia implementazione fino a quando la proposta non viene approvata e la fase di esecuzione viene completata. Utilizzare GOVERNANCE_INTENT_MODE=json-rpc solo quando il progetto è configurato per sottomettere l'intento di governance direttamente al contratto anziché tramite l'endpoint di Oracle Blockchain Platform.
  3. Eseguire l'aggiornamento del token. Dopo l'approvazione, eseguire lo stesso file manifesto scritto dal comando prepare.
    UPGRADE_ACTION=execute \
    UPGRADE_MANIFEST=.obp-da/upgrades/deposittoken-v2.json \
    npx hardhat run scripts/upgrade/upgrade-deposittoken.ts --network obp-besu
    Lo script verifica l'ID della catena di file manifesto, la scadenza e l'hash bytecode di implementazione preparato prima di chiamare la funzione upgradeToAndCall.

Aggiorna proxy account

  1. Eseguire il comando seguente per preparare l'aggiornamento dell'account.
    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
    
    Sostituire il valore completamente qualificato della variabile IMPLEMENTATION_CONTRACT con il percorso e il nome del contratto dell'implementazione del nuovo account. Non riutilizzare il percorso di origine, l'indirizzo proxy o il file manifesto del token per un aggiornamento dell'account.
  2. Dopo che la proposta di upgrade dell'account ha ricevuto le approvazioni di governance richieste, eseguire il comando seguente per approvare e completare l'upgrade dell'account.
    UPGRADE_ACTION=execute \
    UPGRADE_MANIFEST=.obp-da/upgrades/deposittoken-account-v2.json \
    npx hardhat run scripts/upgrade/upgrade-account.ts --network obp-besu

Risoluzione dei problemi

Condizione Risoluzione
Prepara convalida storage non riuscita Non forzare l'aggiornamento. Correggere la modifica del layout incompatibile oppure distribuire un nuovo proxy ed eseguire la migrazione dello stato.
Un file manifesto di preparazione precedente è scaduto o è destinato a un'implementazione diversa Creare una sostituzione deliberatamente impostando REPREPARE=true e mantenendo il file manifesto precedente come record di controllo.
Esecuzione eseguita prima dell'approvazione Ottenere prima le approvazioni della governance. È necessario un intento approvato prima che l'aggiornamento preparato diventi eseguibile.
È stata selezionata un'implementazione errata Verificare che la variabile IMPLEMENTATION_CONTRACT utilizzi il valore path:contract completamente qualificato dell'origine aggiornata, quindi ricompilare e preparare un nuovo file manifesto. Non eseguire mai un file manifesto preparato per un'implementazione diversa.
Esegui di nuovo Lo script rileva un proxy già aggiornato e registra il risultato anziché inviare una seconda transazione di aggiornamento. Per un file manifesto meno recente senza implementationContract, fornire lo stesso valore IMPLEMENTATION_CONTRACT durante l'esecuzione in modo che la cronologia dell'implementazione possa essere sincronizzata.