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çãoname
- é o nome do parâmetro esperadotype
- é o tipo de dado esperado
name
- é o nome da função declarada no contratooutputs
- é uma matriz de objetos que serão os dados de saída que a função irá retornarname
- nome da variável que será retornadatype
- tipo de dado que será retornado
payable
- se é uma função que aceita pagamentostateMutability
- 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 ) oufallback
(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: MITpragma 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)externalpurereturns (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));}}