Skip to main content

4 min read

Overview​

A smart contract's Application Binary Interface (ABI) describes the functions and events that tools use to interact with it. An Ethereum client library uses this interface to encode function calls and decode results. This guide explains the ABI's JSON fields and shows how to generate one from Solidity.

Prefer a video walkthrough? Follow along with Radek and learn about ABI in 11 minutes.
Subscribe to our YouTube channel for more videos!

What is ABI?​

An ABI defines how a caller represents contract functions, arguments, return values, and events. Solidity's compiler can produce a JSON description of that interface alongside the contract's executable bytecode.

For a typical function call, a client library combines a function selector with arguments encoded according to their types. It uses the ABI to interpret the returned bytes. The byte encoding is not self-describing, so decoding requires knowledge of the expected types.

The ABI is an interface description, not the deployed contract's source code or bytecode. See the Solidity ABI specification for the encoding rules and JSON format.

Understanding the elements of ABI​

The JSON format of a contract’s ABI is given by various functions and/or events descriptions.

Following are the elements present in the ABI description of a function:

  • type: Defines the type of function. It can be one of the following, ‘function’, ‘constructor’, ‘receive' (for receive ether function), or ‘fallback’ (for default function).
  • name: Defines the name of the function.
  • inputs: It is an array of objects which defines parameters; each object has:
    • name: Defines the name of the parameters.
    • type: Defines the canonical types of the parameters. For example, uint256.
    • components: Used to define tuple types, if a tuple type is reached, it is represented as type = tuple [other properties of tuple elements like name, type goes here].
  • outputs: It is an array of output objects similar to inputs.
  • stateMutability: Defines the mutability of a function. It can be one of the following values: ‘pure’ (specified not to read or write blockchain state), ‘view’ (specified when blockchain state is to be read, but no modification can be done), ‘nonpayable’ (this is the default mutability and doesn’t need to be mentioned while writing a function in code, this means a function does not accept Ether; using this we can read and write blockchain state), ‘payable’ (mentioning this means a function accepts Ether and can read/write blockchain state).

Note: Constructors, receive functions, and fallback functions omit the name and outputs fields. Receive and fallback entries also omit inputs; constructor entries may include inputs. These fields are omitted rather than represented by blank strings.

Following are the elements present in the ABI description of an event:

  • type: here, it’s always ‘event’.
  • name: Defines the name of the event.
  • inputs: It is an array of objects which defines parameters; each object has:
    • name: Defines the name of the parameters.
    • type: Defines the canonical types of the parameters. For example, uint256.
    • components: Used to define tuple types, if a tuple type is reached, it is represented as type = tuple [other properties of tuple elements like name, type goes here].
    • indexed: This is ‘true’ if the field is part of the log’s topics and ‘false’ if it is one of the log’s data segments.
  • anonymous: This field is true if the event was declared as anonymous in the contract code.

How to get/generate ABI?​

One of the most common ways is to copy the ABI using the ABI button under compile tab of Ethereum REMIX IDE after the smart contract has complied.

Copying a compiled contract ABI from the Remix Solidity compiler panel

Another way is compiling and generating ABI using solc, which provides JavaScript bindings for Solidity Compiler. To install solc, we need to have npm, which comes with node.js. Check if node.js is installed on your system or not.

$ node -v

If not installed, you can download the LTS version of NodeJS from the official website.

Now let’s install solc

npm install --save-dev solc@0.8.30

Create test.sol with a contract that increments and reads a counter:

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

contract test {
uint256 private count;

function increment() public {
count += 1;
}

function getCount() public view returns (uint256) {
return count;
}
}

The private count variable is not exposed as a public getter. The ABI describes the two public functions: increment changes state and getCount reads it.

Generate the ABI using the locally installed compiler:

npx solcjs test.sol --abi

A file named test_sol_test.abi will be created in the same directory; it will have the ABI in the JSON format something like this:

[
{
"inputs": [],
"name": "getCount",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "increment",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]

Conclusion​

Now that you know what ABI is, learn more about Solidity,  Vyper smart contracts, and create your smart contracts. Learn more about ABI specifications from Solidity docs.

Subscribe to our newsletter for more articles and guides on Ethereum. If you have any feedback, feel free to reach out to us via Twitter. You can always chat with us on our Discord community server, featuring some of the coolest developers you'll ever meet :)