SwiftHTML & CSSSolidityDesenvolvimento de JogosSolana/Rust
05.12.2024

Lição 231: Lidando com Mudanças no ABI do Contrato

Ao trabalhar com contratos inteligentes na Ethereum, a Interface Binária de Aplicação (ABI) é fundamental para a interação com os contratos. Ela define como as estruturas de dados são codificadas/decodificadas e como as funções podem ser chamadas. No entanto, quando um contrato é atualizado, sua ABI pode mudar, o que pode causar problemas na interação com o contrato. Nesta lição, vamos explorar como lidar com mudanças no ABI revisando um exemplo básico.

Entendendo Mudanças no ABI

Antes de mergulhar em exemplos, é essencial entender os tipos de mudanças que podem afetar a ABI:

  1. Adicionando Funções: Novas funções podem ser adicionadas, o que não quebra chamadas existentes.
  2. Removendo Funções: A remoção de funções pode levar a erros, pois os clientes ainda podem estar tentando acessar funções não existentes.
  3. Alterando Assinaturas de Funções: Alterar os parâmetros de entrada/saída de funções existentes criará incompatibilidades.
  4. Mudando Variáveis de Estado: Mudar variáveis de estado, especialmente seus tipos ou visibilidade, também afetará a ABI.

Exemplo de Contrato

Vamos começar com um contrato simples que iremos modificar ao longo do tempo. O contrato inicial será o seguinte:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract ArmazenamentoSimples {
    uint256 private dados;

    event DadosArmazenados(uint256 indexed valor);

    function armazenar(uint256 valor) public {
        dados = valor;
        emit DadosArmazenados(valor);
    }

    function recuperar() public view returns (uint256) {
        return dados;
    }
}

Representação do ABI

O ABI do contrato ArmazenamentoSimples pode ser gerado usando ferramentas como solc ou truffle, e geralmente se parece com isto:

[
    {
        "inputs": [
            {
                "internalType": "uint256",
                "name": "valor",
                "type": "uint256"
            }
        ],
        "name": "armazenar",
        "outputs": [],
        "stateMutability": "nonpayable",
        "type": "function"
    },
    {
        "inputs": [],
        "name": "recuperar",
        "outputs": [
            {
                "internalType": "uint256",
                "name": "",
                "type": "uint256"
            }
        ],
        "stateMutability": "view",
        "type": "function"
    },
    {
        "anonymous": false,
        "inputs": [
            {
                "indexed": true,
                "internalType": "uint256",
                "name": "valor",
                "type": "uint256"
            }
        ],
        "name": "DadosArmazenados",
        "type": "event"
    }
]

Lidando com Mudanças no ABI

1. Exemplo: Adicionando uma Função

Vamos adicionar uma função que nos permite redefinir o valor armazenado:

function redefinir() public {
    dados = 0;
    emit DadosArmazenados(0);
}

O ABI atualizado agora incluirá a função redefinir:

{
    "inputs": [],
    "name": "redefinir",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
}

Interação: Os clientes agora podem chamar esta nova função sem afetar a funcionalidade existente.

2. Exemplo: Removendo uma Função

Suponha que queremos remover a função armazenar. Aqui está o contrato atualizado (sem a função armazenar):

function recuperar() public view returns (uint256) {
    return dados;
}

Impacto: Se os clientes ainda estavam tentando chamar armazenar, enfrentarão problemas.

3. Exemplo: Alterando Assinaturas de Funções

Vamos modificar a função recuperar para retornar uma string em vez de um uint256:

function recuperar() public view returns (string memory) {
    return "Nenhum dado disponível"; // Para fins de demonstração.
}

Essa mudança quebrará todos os aplicativos clientes que esperam um tipo de retorno uint256. Para lidar com tais mudanças de assinatura:

  • Atualizar as bibliotecas/códigos dos clientes para corresponder à nova assinatura da função.
  • Comunicar essas mudanças claramente nas atualizações de versão.

Melhores Práticas para Gerenciar Mudanças no ABI

  1. Versionamento: Sempre incremente a versão do seu contrato ao fazer mudanças que afetem o ABI e forneça um changelog claro.
  2. Documentação: Sempre documente as mudanças feitas no ABI em uma seção separada, facilitando para os desenvolvedores adaptarem seu código.
  3. Manutenção de Compatibilidade Retroativa: Se possível, mantenha a compatibilidade retroativa ao criar novas funções em vez de alterar/remover as existentes.
  4. Teste: Escreva testes para as funções que foram alteradas e para as implantações para garantir que tudo está funcionando conforme esperado após uma mudança no ABI.

Conclusão

Lidar com mudanças no ABI é crucial para manter e atualizar contratos inteligentes. Se você está adicionando, removendo ou alterando funções, seguir as melhores práticas pode ajudar a prevenir interrupções nas interações dos clientes e reduzir confusões na comunidade de desenvolvedores. Esteja sempre atento ao ABI e informe os usuários sobre quaisquer mudanças futuras para garantir uma transição suave.

Video

Did you like this article? Rate it from 1 to 5:

Thank you for voting!