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.
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:
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:
A monster of hexadecimal and/or binary. So, when we interact with this jumble of hex, we should probably know:
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!
Using the contract above, the ABI looks like this:
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:
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:
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.
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
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.
An ABI includes several pieces of information for each function within a smart contract:
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.
You can see an ABI copy button when you compile a smart contract on Remix.
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.
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.
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:
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.
We could 100% hard-code calling this setNumber
function with raw data:
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.
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:
Using the ABI here, we can now call setNumber
as a function on our counterContract
object.
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!
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.