ABI

A Interface Binária de Aplicação (ABI) no Ethereum é um padrão crucial para interagir com contratos inteligentes na blockchain do Ethereum. É essencialmente um formato de interface que permite que os contratos inteligentes se comuniquem com aplicativos externos e com outros contratos na blockchain. A ABI define como as funções de um contrato inteligente podem ser chamadas, incluindo os parâmetros necessários e os tipos de dados retornados, facilitando a interação entre o código binário de baixo nível que é executado na Ethereum Virtual Machine (EVM) e o código de alto nível escrito por desenvolvedores e usuários.

Principais características da ABI

  • Definição de funções: A ABI especifica as funções do contrato inteligente, incluindo nomes, tipos de parâmetros de entrada e saída, e se são funções de visualização ou funções que alteram o estado na blockchain.

  • Codificação de dados: Fornece regras para a codificação (transformação de dados de alto nível para sua representação binária) e decodificação (o processo inverso) dos argumentos das funções e dos valores retornados. Isso garante que as chamadas de funções e transações possam ser interpretadas corretamente pelos contratos inteligentes.

  • Eventos: A ABI também define eventos que os contratos inteligentes podem emitir. Esses eventos permitem que aplicativos externos recebam notificações sobre mudanças ou ações específicas que ocorrem dentro dos contratos inteligentes.

A seguir, veja um exemplo de uma ABI para um contrato inteligente. Imagine que este contrato inteligente tenha como propósito gerenciar uma lista simples de tarefas, permitindo que os usuários adicionem tarefas e as marquem como concluídas. O contrato pode incluir funções como addTask, que adiciona uma nova tarefa, e markTaskCompleted, que marca uma tarefa como concluída.

O código Solidity do contrato pode ser assim:

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

contract TodoList {

    struct Task {
        string description;
        bool isCompleted;
    }

    Task[] public tasks;

    function addTask(string memory _description) public {
        tasks.push(Task(_description, false));
    }

    function markTaskCompleted(uint _taskId) public {
        tasks[_taskId].isCompleted = true;
    }

    function getTask(uint _taskId) public view returns (string memory, bool) {
        Task storage task = tasks[_taskId];
        return (task.description, task.isCompleted);
    }
}

Para este contrato, uma ABI de exemplo que descreve as funções disponíveis poderia ser assim:

    {
        "inputs": [
            {
                "internalType": "string",
                "name": "_description",
                "type": "string"
            }
        ],
        "name": "addTask",
        "outputs": [],
        "stateMutability": "nonpayable",
        "type": "function"
    },
    {
        "inputs": [
            {
                "internalType": "uint256",
                "name": "_taskId",
                "type": "uint256"
            }
        ],
        "name": "markTaskCompleted",
        "outputs": [],
        "stateMutability": "nonpayable",
        "type": "function"
    },
    {
        "inputs": [
            {
                "internalType": "uint256",
                "name": "_taskId",
                "type": "uint256"
            }
        ],
        "name": "getTask",
        "outputs": [
            {
                "internalType": "string",
                "name": "",
                "type": "string"
            },
            {
                "internalType": "bool",
                "name": "",
                "type": "bool"
            }
        ],
        "stateMutability": "view",
        "type": "function"
    }
]

Esta ABI descreve as três funções do contrato TodoList, incluindo os tipos dos parâmetros de entrada e saída. A propriedade stateMutability indica se a chamada da função modifica o estado do contrato (nonpayable para addTask e markTaskCompleted, que não aceitam ETH mas modificam o estado) ou apenas lê dados (view para getTask, que não altera o estado do contrato).

Esta ABI permite que aplicativos clientes saibam como interagir com o contrato inteligente, invocando suas funções e lendo suas respostas. Ao integrar essa ABI em um aplicativo (por exemplo, usando Web3.js ou ethers.js), os desenvolvedores podem fazer chamadas às funções do contrato de forma simples, passando os argumentos necessários e processando os valores retornados.

Uso da ABI

Para interagir com um contrato inteligente, um aplicativo externo precisa conhecer sua ABI. Esse requisito existe porque o código dos contratos inteligentes é compilado em bytecode antes de ser implantado na blockchain, e o bytecode por si só não é suficiente para determinar como interagir com o contrato de forma eficaz.

Quando um desenvolvedor usa ferramentas como Remix ou Hardhat para compilar e implantar contratos inteligentes, essas ferramentas geram automaticamente a ABI com base no código-fonte do contrato. Em seguida, o desenvolvedor pode integrar essa ABI em aplicativos clientes (por exemplo, um aplicativo web que interage com o contrato) para facilitar a comunicação.

Exemplo de Uso da ABI

Imagine que você tenha um contrato inteligente em Solidity que inclui uma função para obter o nome de um usuário. Para chamar essa função a partir de um aplicativo web, você precisaria da ABI do contrato. Com a ABI, você pode usar uma biblioteca do Ethereum como Web3.js ou ethers.js para criar uma instância do contrato em seu aplicativo e fazer chamadas às suas funções como se fossem funções JavaScript.

const contractABI = /* ABI do contrato inteligente aqui */;
const contractAddress = '0x...'; // Endereço do contrato implantado

const web3 = new Web3('<http://localhost:8545>');
const myContract = new web3.eth.Contract(contractABI, contractAddress);

// Chamando uma função do contrato
myContract.methods.nomeDaFuncao().call()
.then(result => {
    console.log(result);
});

Last updated