Back to blogs
Written by
Patrick Collins
Published on
April 19, 2024

What is a Smart Contract ABI and How to Get it

The ABI of a smart contract is an acronym for the “Application Binary Interface.” It defines the standard way to interact with contracts in the Ethereum ecosystem;

Table of Contents

The “ABI” of a smart contract is an acronym for the “Application Binary Interface.” It defines the standard way to interact with contracts in the Ethereum ecosystem, both from outside the blockchain by human beings and for contract-to-contract interaction.

In this guide you will learn everything you need to know on what is a smart contract ABI and how to get it to start interacting with it.

Let’s just jump into an example.

What is a Smart Contract ABI

Image showing what is an ethereum virtual machine smart contract ABI

As we said before, The “ABI” of a smart contract defines the standard way to interact with it, both from outside the blockchain by human beings and for contract-to-contract interaction - Let’s take the following smart contract:

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

contract Counter {
    uint256 public number;

    function setNumber(uint256 newNumber) public {
        number = newNumber;
    }

    function increment() public {
        number++;
    }
}

When we compile this smart contract and deploy it on-chain, guess what the contract really is? All these English-written words are nice, but they aren’t what gets stored on the blockchain.

Instead, this is:


0x608060405234801561001057600080fd5b5060f78061001f6000396000f3fe6080604052348015600f57600080fd5b5060043610603c5760003560e01c80633fb5c1cb1460415780638381f58a146053578063d09de08a14606d575b600080fd5b6051604c3660046083565b600055565b005b605b60005481565b60405190815260200160405180910390f35b6051600080549080607c83609b565b9190505550565b600060208284031215609457600080fd5b5035919050565b60006001820160ba57634e487b7160e01b600052601160045260246000fd5b506001019056fea26469706673582212202d7dee18f1939c15cddbe7e354ba70087303b1f831d9e3192e0fcd25106ce31064736f6c63430008160033

A monster of hexadecimal and/or binary. So, when we interact with this jumble of hex, we should probably know:

  1. What functions can we call
  2. How to call the functions
  3. What parameters can we pass to the functions

The smart contract ABI is the guiding light that tells us how to interact with this bunch of nonsense hex on the chain because, remember, the human-readable solidity or viper isn’t what gets stored on chain; the hex does!

What does an ABI look like?

Using the contract above, the ABI looks like this:

{"abi": [
        {
            "type": "function",
            "name": "increment",
            "inputs": [],
            "outputs": [],
            "stateMutability": "nonpayable"
        },
        {
            "type": "function",
            "name": "number",
            "inputs": [],
            "outputs": [
                {
                    "name": "",
                    "type": "uint256",
                    "internalType": "uint256"
                }
            ],
            "stateMutability": "view"
        },
        {
            "type": "function",
            "name": "setNumber",
            "inputs": [
                {
                    "name": "newNumber",
                    "type": "uint256",
                    "internalType": "uint256"
                }
            ],
            "outputs": [],
            "stateMutability": "nonpayable"
        }
    ]
}


This is the JSON that allows us to know how to interact with and send hex data to this smart contract to interact with it. Let’s say I want to call the setNumber function on this contract, what is the exact data I need to send to this contract in order for that function to be invoked? Well, I can look at the setNumber function in the smart contract ABI to figure it out:

{
            "type": "function",
            "name": "setNumber",
            "inputs": [
                {
                    "name": "newNumber",
                    "type": "uint256",
                    "internalType": "uint256"
                }
            ],
            "outputs": [],
            "stateMutability": "nonpayable"
        }

I can see it’s a function that takes a uint256 as an input, has no output, and is not payable. With this information, I can use Foundry’s cast to craft the raw data I’d need to send to this contract:

cast calldata "setNumber(uint256)" 8

# returns:
0x3fb5c1cb0000000000000000000000000000000000000000000000000000000000000008

Because I had access to the smart contract ABI, I could derive the information I needed to create the data to interact with this contract.

The ABI also enables us to take this mess of machine-readable code and turn it back into human-readable code.

cast calldata-decode "setNumber(uint256)" 0x3fb5c1cb0000000000000000000000000000000000000000000000000000000000000008

# returns
8

We are getting a little into the territory of Function Selectors vs Function Signatures, but that’s a topic for another time. You can learn all about function selectors and function signatures on Cyfrin Updraft

Is the ABI for humans or machines?

As you can see, the ABI helps humans translate human-readable code to computer code and computer code back into human-readable code. Without ABIs, we’d have to write all our code using raw low-level hex or bytecode, which would be awful for reading complex codebases.

Components of an ABI

An ABI includes several pieces of information for each function within a smart contract:

  • Function Names: Helps in identifying functions.
  • Function Arguments: Includes type, order, and data structure.
  • Return Types: Specifies the data type that a function call returns.
  • Events: If the contract includes events, the ABI will also describe these along with the parameters they return.

How to get a smart contract ABI

Developers can generate a smart contract ABI using the Solidity compiler (solc), Remix,or other development frameworks like Foundry or Hardhat.

Most of the times, these tools will automatically create the ABI when you compile the smart contract.

Get the smart contract ABI using Remix

You can see an ABI copy button when you compile a smart contract on Remix.

image showing how to obtain the smart contract abi using remix

Get the smart contract ABI using Foundry

For Foundry, After a successful run of forge build, you can find the ABI of any smart contract by looking at the compilation details in the out folder.

image showing how to get smart contract abi using foundry

Get the smart contract ABI using Hardhat

For Hardhat, we can find the ABI in the artifacts/build-info folder. After a successful run of npx hardhat compile these folders will be generated.

image showing how to get solidity smart contract abi using hardhat

Using a smart contract ABI on Solidity

You’ve probably seen Interfaces in your Solidity smart contract code before. When calling a contract function in Solidity, our Smart Contract needs to work out how to send the raw data to the contract. In solidity, providing a contract interface is a great way to secretly provide the ABI. For example:

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

interface ICounter {
    function setNumber(uint256 newNumber) external;

    function increment() external;
}


The interface above can be compiled, resulting in an ABI that will help solidity-based contracts build the raw data to interact with our Counter contracts. In fact, if you compile this interface, you’ll get nearly the exact same ABI as the original contract!

Not exactly the same, as we left off the number part for simplicity.

If we have this interface, we can then call the setNumber function of a Counter contract because, under the hood, solidity will use the ABI generated from this interface to help generate the raw data needed to call our Counter contract.

ICounter(counter_address).setNumber(8);

We could 100% hard-code calling this setNumber function with raw data:

counter_address.call(0x3fb5c1cb0000000000000000000000000000000000000000000000000000000000000008);

However, you can see pretty easily that this is horrible for humans to read, so we use an interface to make our codebases much more readable.

Using the smart contract ABI in Javascript

Additionally, in all our javascript-based applications we need the ABI for our code to know what data to send to the contract as well. If you’re using the ethers package, you’ve probably seen a setup similar to this:

const provider = new ethers.providers.JsonRpcProvider();
const counterAddress = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"

const counterABI = [
        {
            "type": "function",
            "name": "increment",
            "inputs": [],
            "outputs": [],
            "stateMutability": "nonpayable"
        },
        {
            "type": "function",
            "name": "number",
            "inputs": [],
            "outputs": [
                {
                    "name": "",
                    "type": "uint256",
                    "internalType": "uint256"
                }
            ],
            "stateMutability": "view"
        },
        {
            "type": "function",
            "name": "setNumber",
            "inputs": [
                {
                    "name": "newNumber",
                    "type": "uint256",
                    "internalType": "uint256"
                }
            ],
            "outputs": [],
            "stateMutability": "nonpayable"
        }
    ]

// The Contract object
const counterContract = new ethers.Contract(counterAddress, counterABI, provider); 

Using the ABI here, we can now call setNumber as a function on our counterContract object.

‍await counterContract.setNumber(8)

By providing the ABI above, the ethers package can convert setNumber(8) into raw hex data for the smart contract to process. Otherwise, we’d have to, once again, manually craft the raw data ourselves, which isn’t human-readable and would be annoying to code!

Summary: what is a smart contract ABI

The ABI, or “Application Binary Interface,” allows humans and machines to encode or decode data back and forth. Our packages for interacting with smart contracts know how to encode our human-readable code, and when a human receives a jumble of machine-readable bytecode, we can convert it back to human-readable.

Secure your protocol today

Join some of the biggest protocols and companies in creating a better internet. Our security researchers will help you throughout the whole process.
Stay on the bleeding edge of security
Carefully crafted, short smart contract security tips and news freshly delivered every week.