Atualizar um Contrato

Você pode fazer upgrade de um contrato empacotado na linha de comando.

As etapas a seguir mostram como atualizar o projeto de contrato de Depósito Tokenizado de amostra. Para outros contratos empacotados, consulte o arquivo README empacotado com o pacote de contratos.

Uma atualização altera a implementação por trás do proxy existente; ela não cria um novo proxy ou redefine seu armazenamento.

A interface de linha de comando Hardhat suporta a atualização de contratos. Se você implantou um contrato inteligente usando a API de proxy RPC, ele será imutável e não poderá ser atualizado.

O projeto de referência inclui implementações V2 para demonstração e teste:
  • Token: contracts/TokenizedDeposit/_testContracts/TokenizedDepositUpgradeableV2.sol
  • Conta: contracts/obp-sdk/accounts/modules/v1/_testContracts/AccountWithERC5982UUPSV2.sol
Os contratos V2 preservam o layout de armazenamento V1, expõem version() como v2.0.0 e incluem um reiniciador initializeV2() vazio. Trate-os como código de referência; revise-os e substitua-os por sua própria implementação compatível para uma atualização real.

Para fazer upgrade de um contrato, você precisa do endereço do proxy do contrato, de uma rede Besu do Oracle Blockchain Platform configurada e de autoridade para submeter a proposta de governança. O contrato implantado deve estar ativo e elegível para seu caminho de autorização de upgrade configurado.

Antes de modificar uma implementação, preserve a compatibilidade de armazenamento. Anexar somente campos de armazenamento. Não reordene, remova ou altere o tipo de campos existentes, altere o layout de armazenamento herdado ou ignore a validação de atualização. Se a alteração for incompatível, implante um novo proxy e migre explicitamente o estado.

Observação:

Você deve apontar para a origem atualizada. A variável IMPLEMENTATION_CONTRACT é passada para a fábrica de contratos da Hardhat. Defina-o como o nome do contrato de Solidez totalmente qualificado para a versão atualizada.
<path-to-upgraded-contract>.sol:<upgraded-contract-name>
Não aponte a variável para o contrato V1 atual. Por exemplo, a implementação de referência do Depósito Tokenizado V2 é mostrada no exemplo a seguir.
contracts/TokenizedDeposit/_testContracts/TokenizedDepositUpgradeableV2.sol:TokenizedDepositUpgradeableV2
Se você criar uma implementação V3 ou personalizada diferente, substitua o caminho e o nome do contrato no comando por essa origem atualizada. Compile após a alteração e antes de executar o comando prepare.

Fazer Upgrade do Proxy de Token

  1. Execute o comando a seguir para preparar o upgrade do token. A preparação valida o layout de implementação e armazenamento, implanta a nova implementação exata, registra seu hash de código e endereços de biblioteca em um manifesto de atualização e envia a intenção de governança necessária. Ele ainda não atualiza o 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

    Com o DEPLOY_LIBRARIES definido como true, uma entrada de biblioteca nula é implantada e seu endereço se torna parte do hash do código de implementação revisado. Para reutilizar bibliotecas, forneça endereços de biblioteca compatíveis existentes na variável LIBRARIES_JSON. A variável INITIALIZER_DATA é uma calldata bruta codificada por ABI passada para a função upgradeToAndCall. Use 0x para os contratos V2 de referência fornecidos porque seu initializeV2() está vazio. Se sua nova implementação precisar ser inicializada, forneça a calldata do reinicializador codificada corretamente e revise-a como parte da proposta de atualização.

  2. Aprovar a proposta de governança. Se a variável GOVERNANCE_INTENT_MODE estiver definida como obp-besu, a etapa de preparação enviará a proposta por meio do proxy RPC do Oracle Blockchain Platform. Obtenha as aprovações exigidas pela configuração de governança de destino. O proxy permanece em sua implementação antiga até que a proposta seja aprovada e a etapa de execução seja concluída. Use GOVERNANCE_INTENT_MODE=json-rpc somente quando o projeto estiver configurado para submeter a intenção de governança diretamente ao contrato, em vez de por meio do ponto final do Oracle Blockchain Platform.
  3. Execute o upgrade do token. Após a aprovação, execute o mesmo manifesto que o comando prepare escreveu.
    UPGRADE_ACTION=execute \
    UPGRADE_MANIFEST=.obp-da/upgrades/deposittoken-v2.json \
    npx hardhat run scripts/upgrade/upgrade-deposittoken.ts --network obp-besu
    O script verifica o ID da cadeia de manifesto, o prazo e o hash de código de bytes de implementação preparado antes de chamar a função upgradeToAndCall.

Fazer Upgrade do Proxy da Conta

  1. Execute o comando a seguir para preparar a atualização da conta.
    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
    
    Substitua o valor totalmente qualificado da variável IMPLEMENTATION_CONTRACT pelo caminho e pelo nome do contrato da sua nova implementação de conta. Não reutilize o caminho de origem, o endereço proxy ou o manifesto do token para uma atualização de conta.
  2. Depois que a proposta de upgrade da Conta receber as aprovações de governança necessárias, execute o comando a seguir para aprovar e concluir a atualização da conta.
    UPGRADE_ACTION=execute \
    UPGRADE_MANIFEST=.obp-da/upgrades/deposittoken-account-v2.json \
    npx hardhat run scripts/upgrade/upgrade-account.ts --network obp-besu

Solucionando Problemas

Condição Resolução
Preparar validação de armazenamento com falha Não force a atualização. Corrija a alteração de layout incompatível ou implante um novo proxy e migre o estado.
Um manifesto de preparação anterior expirou ou tem como alvo uma implementação diferente Crie uma substituição deliberadamente definindo REPREPARE=true e mantendo o manifesto antigo como um registro de auditoria.
A execução é executada antes da aprovação Obtenha primeiro as aprovações de governança. Uma intenção aprovada é necessária para que o upgrade preparado se torne executável.
A implementação incorreta foi selecionada Verifique se a variável IMPLEMENTATION_CONTRACT usa o valor path:contract totalmente qualificado da origem atualizada e recompile e prepare um novo manifesto. Nunca execute um manifesto preparado para uma implementação diferente.
Executar é executado novamente O script detecta um proxy que já foi atualizado e registra esse resultado em vez de enviar uma segunda transação de atualização. Para um manifesto mais antigo que não tem implementationContract, forneça o mesmo valor IMPLEMENTATION_CONTRACT durante a execução para que o histórico de implementação possa ser sincronizado.