Mettre à niveau un contrat

Vous pouvez mettre à niveau un contrat packagé à partir de la ligne de commande.

Les étapes suivantes montrent comment mettre à niveau l'exemple de projet de contrat de dépôt segmenté. Pour les autres contrats packagés, voir le fichier README fourni avec le package de contrats.

Une mise à niveau modifie l'implémentation derrière le proxy existant ; elle ne crée pas de nouveau proxy ni ne réinitialise son stockage.

L'interface de ligne de commande Hardhat prend en charge la mise à niveau des contrats. Si vous avez déployé un contrat intelligent à l'aide de l'API proxy RPC, il est immuable et ne peut pas être mis à niveau.

Le projet de référence comprend des implémentations V2 pour la démonstration et les tests :
  • Jeton : contracts/TokenizedDeposit/_testContracts/TokenizedDepositUpgradeableV2.sol
  • Compte : contracts/obp-sdk/accounts/modules/v1/_testContracts/AccountWithERC5982UUPSV2.sol
Les contrats V2 conservent la disposition de stockage V1, exposent version() en tant que v2.0.0 et incluent un réinitialiseur initializeV2() vide. Traitez-les comme code de référence ; examinez-les et remplacez-les par votre propre implémentation compatible pour une mise à niveau réelle.

Pour mettre à niveau un contrat, vous avez besoin de l'adresse proxy du contrat, d'un réseau Oracle Blockchain Platform Besu configuré et de l'autorité nécessaire pour soumettre la proposition de gouvernance. Le contrat déployé doit être actif et admissible pour son chemin d'autorisation de mise à niveau configuré.

Avant de modifier une implémentation, conservez la compatibilité du stockage. Ajoutez uniquement des champs de stockage. Ne réorganisez pas, ne supprimez pas ou ne modifiez pas le type de champs existants, ne modifiez pas la disposition de stockage héritée ou ne passez pas la validation de mise à niveau. Si la modification est incompatible, déployez un nouveau proxy et migrez explicitement l'état à la place.

Remarque :

Vous devez pointer vers la source mise à niveau. La variable IMPLEMENTATION_CONTRACT est transmise à la fabrique de contrats de Hardhat. Affectez-lui le nom de contrat Solidity complet pour la version mise à niveau.
<path-to-upgraded-contract>.sol:<upgraded-contract-name>
Ne pointez pas la variable sur le contrat V1 actuel. Par exemple, l'implémentation de référence du dépôt segmenté V2 est illustrée dans l'exemple suivant.
contracts/TokenizedDeposit/_testContracts/TokenizedDepositUpgradeableV2.sol:TokenizedDepositUpgradeableV2
Si vous créez une implémentation V3 ou personnalisée différente, remplacez le chemin et le nom du contrat dans la commande par cette source mise à niveau. Compilez après la modification et avant d'exécuter la commande prepare.

Mettre à niveau le proxy de jeton

  1. Exécutez la commande suivante pour préparer la mise à niveau du jeton. La préparation valide la configuration de l'implémentation et du stockage, déploie la nouvelle implémentation exacte, enregistre son hachage de code et ses adresses de bibliothèque dans un manifeste de mise à niveau et soumet l'intention de gouvernance requise. Il ne met pas encore à niveau le 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

    Lorsque DEPLOY_LIBRARIES est défini sur true, une entrée de bibliothèque NULL est déployée et son adresse fait partie du hachage de code d'implémentation révisé. Pour réutiliser des bibliothèques, fournissez les adresses de bibliothèque compatibles existantes dans la variable LIBRARIES_JSON. La variable INITIALIZER_DATA est un calldata brut encodé ABI transmis à la fonction upgradeToAndCall. Utilisez 0x pour les contrats de référence V2 fournis car leur initializeV2() est vide. Si votre nouvelle implémentation doit être initialisée, fournissez des calldata de réinitialisation correctement encodés et examinez-les dans le cadre de la proposition de mise à niveau.

  2. Approuver la proposition de gouvernance. Si la variable GOVERNANCE_INTENT_MODE est définie sur obp-besu, l'étape de préparation soumet la proposition via le proxy RPC Oracle Blockchain Platform. Obtenez les approbations requises par la configuration de gouvernance cible. Le proxy reste sur son ancienne implémentation jusqu'à ce que la proposition soit approuvée et que l'étape d'exécution soit terminée. Utilisez GOVERNANCE_INTENT_MODE=json-rpc uniquement lorsque le projet est configuré pour soumettre l'intention de gouvernance directement au contrat plutôt que via l'adresse Oracle Blockchain Platform.
  3. Exécutez la mise à niveau du jeton. Après l'approbation, exécutez le même manifeste que celui écrit par la commande prepare.
    UPGRADE_ACTION=execute \
    UPGRADE_MANIFEST=.obp-da/upgrades/deposittoken-v2.json \
    npx hardhat run scripts/upgrade/upgrade-deposittoken.ts --network obp-besu
    Le script vérifie l'ID de chaîne de manifeste, la date limite et le hachage de code exécutable d'implémentation préparé avant d'appeler la fonction upgradeToAndCall.

Mettre à niveau le proxy du compte

  1. Exécutez la commande suivante pour préparer la mise à niveau du compte.
    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
    
    Remplacez la valeur qualifiée complète de la variable IMPLEMENTATION_CONTRACT par le chemin et le nom du contrat de votre nouvelle implémentation de compte. Ne réutilisez pas le chemin source, l'adresse proxy ou le manifeste du jeton pour une mise à niveau de compte.
  2. Une fois que la proposition de mise à niveau du compte reçoit les approbations de gouvernance requises, exécutez la commande suivante pour approuver et terminer la mise à niveau du compte.
    UPGRADE_ACTION=execute \
    UPGRADE_MANIFEST=.obp-da/upgrades/deposittoken-account-v2.json \
    npx hardhat run scripts/upgrade/upgrade-account.ts --network obp-besu

Dépannage

Condition Résolution
Préparer la validation du stockage en échec Ne forcez pas la mise à niveau. Corrigez la modification de présentation incompatible, ou déployez un nouveau proxy et migrez l'état.
Un manifeste de préparation précédent a expiré ou cible une implémentation différente Créez un remplaçant délibérément en définissant REPREPARE=true et en conservant l'ancien manifeste en tant qu'enregistrement d'audit.
Exécuter avant l'approbation Obtenez d'abord les approbations de gouvernance. Une intention approuvée est requise avant que la mise à niveau préparée ne devienne exécutable.
Une implémentation incorrecte est sélectionnée Vérifiez que la variable IMPLEMENTATION_CONTRACT utilise la valeur path:contract complète de la source mise à niveau, puis recompilez et préparez un nouveau manifeste. N'exécutez jamais un manifeste préparé pour une implémentation différente.
Exécuter à nouveau Le script détecte un proxy qui est déjà mis à niveau et enregistre ce résultat plutôt que d'envoyer une seconde transaction de mise à niveau. Pour un ancien manifeste qui manque de implementationContract, fournissez la même valeur IMPLEMENTATION_CONTRACT lors de l'exécution afin que l'historique d'implémentation puisse être synchronisé.