O que é ABI e para que serve?

porMatheusem26/05/2022

Nesse artigo iremos abordar sobre o que é uma ABI do contrato inteligente, para que serve e como codificar e decodificar.

O que é ABI (Application Binary Interface)

De modo simplificado, ABI significa Interface Binária de Aplicação em português, é um arquivo .json que descreve o contrato implantado e suas funções. Ele nos permite contextualizar o contrato e chamar suas funções através de outras aplicações.

Abaixo podemos ver como é uma ABI pronta

[
{
"constant": false,
"inputs": [
{
"name": "to",
"type": "address"
},
{
"name": "amount",
"type": "uint256"
}
],
"name": "transfer",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "account",
"type": "address"
}
],
"name": "getBalance",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
]

No exemplo, podemos notar que temos alguns atributos, são eles:

  • constant - define se a função é uma constante ou não (true / false)
  • inputs - é uma array de objetos que definem as entradas esperadas pela função
    • name - é o nome do parâmetro esperado
    • type - é o tipo de dado esperado
  • name - é o nome da função declarada no contrato
  • outputs - é uma matriz de objetos que serão os dados de saída que a função irá retornar
    • name - nome da variável que será retornada
    • type - tipo de dado que será retornado
  • payable - se é uma função que aceita pagamento
  • stateMutability - define a mutabilidade de uma função. Podendo ser um dos seguintes valores:
    • pure (especificado para não ler ou gravar o estado do blockchain)
    • view (especificado quando o estado do blockchain deve ser lido, mas nenhuma modificação pode ser feita)
    • nonpayable (isto é a mutabilidade padrão e não precisa ser mencionado ao escrever uma função no código, isso significa que uma função não aceita Ether; usando isso podemos ler e escrever o estado blockchain)
    • payable (mencionando isso significa que uma função aceita Ether e pode ler/gravar o estado do blockchain)
  • type - define o tipo de função. Podendo ser um dos seguintes, function, constructor, receive (para receber função ether ) ou fallback (para função padrão )

Codificar e decodificar uma ABI

Para codificar-mos uma ABI, podemos usar a função abi.encode que irá retornar a ABI codificada em bytes.

Para decodificar-mos a ABI, a função é abi.decode, passando os bytes como parâmetro para então obtermos os dados novamente.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
contract AbiDecode {
struct MyStruct {
string name;
uint[2] nums;
}
function encode(
uint x,
address addr,
uint[] calldata arr,
MyStruct calldata myStruct
) external pure returns (bytes memory) {
return abi.encode(x, addr, arr, myStruct);
}
function decode(bytes calldata data)
external
pure
returns (
uint x,
address addr,
uint[] memory arr,
MyStruct memory myStruct
)
{
// (uint x, address addr, uint[] memory arr, MyStruct myStruct) = ...
(x, addr, arr, myStruct) = abi.decode(data, (uint, address, uint[], MyStruct));
}
}

Testar no Remix