ABI and Bytecode in Solidity Explained

Smart contracts, as we know them, are written in human-readable code, but the EVM (Ethereum virtual machines) that executes the code use the human readable version. It rather uses the compiled bytecode, which will look like this for example:

However, to achieve this bytecode, we need a compiler to “compile” the source code into machine-readable codes.

For example, when smart contracts are written in a high-level language like Solidity, they are compiled in EVM executable bytecode (low-level).

What Happens when Contracts are compiled.

In Solidity, when the source code is compiled, two “artifacts” are generated namely: bytecode and ABI. As explained earlier, the source code is compiled into bytecode, which is the machine-readable low-level instructions that are deployable on the blockchain.

ABI, the second artifact, is also generated as a separate ABI file in JSON format, which is the human-readable interface for encoding and decoding function calls.

Bytecode in Solidity

This bytecode is a series of hexadecimal numbers that represent the instructions, in their binary form, that the EVM will execute on the blockchain when we interact with a smart contract.

Within bytecode, individual operation instructions are denoted as opcodes which are human-readable instructions with hexadecimal counterparts. These opcodes are generated by breaking down every line of code within the contract. This process ensures that the computer possesses precise instructions on how to execute our code during runtime.

Bytecode is further divided into two types, namely, creation and runtime bytecode.

The creation bytecode generates the runtime bytecode, which contains the constructor logic and parameters of smart contracts during compilation. This runtime bytecode serves as the permanent executable code stored on-chain, but unlike the creation bytecode, it is void of constructor logic and parameters.

Here is an example of two opcodes, their description, and their hexadecimal representation.

Here is a simple, smart contract and the bytecode generated during compilation.

Two things are required for your web application to interact with a smart contract on Ethereum: the contract's address and its ABI. Just like we have APIs(Application programming interfaces) That define the methods by which software can interact with each other, the ABI (application binary interfaces) define the methods and variables that can interact with a smart contract.

The smart contract compiler encodes the machine-readable bytecode ABI, which includes function signatures and variable declarations understood by the EVM-based bytecode. ABI encoding ensures seamless communication between the machine-readable bytecode and the Ethereum Virtual Machine (EVM) to facilitate interactions with external applications. The ABI outlines the parameters, function names, arguments, and data types for interacting with a smart contract. Also, it defines the structure (JSON format) of events emitted by the smart contract.

The JSON format of a contract’s ABI description can be in functions and/or events. Here are the elements present in the ABI description of a function:

type: This field specifies the type of function and can take one of the following values: 'function' (for regular functions), 'constructor' (for the contract constructor), 'receive' (for the receive ether function), or 'fallback' (for the default function).

name: It indicates the name of the function as defined in the Solidity code.

inputs: This is an array of objects that define the parameters of the function

outputs: Similar to inputs, outputs are an array of objects that define the return values of the function, if any.

stateMutability: This field specifies the mutability of the function and can take one of the following values: 'pure' , 'view', 'nonpayable', or 'payable'

Interesting in this example is the fact that the “count” variable is declared as view-function, which in fact represents the reality once deployed.

How ABI Interacts with External Applications

For external applications to interact with a smart contract using ABI, do the following.

1. Obtain the contract's ABI(JSON format), detailing its function signatures, input/output types, and event definitions.

2. Parse the ABI to extract details for interacting with the smart contract, including function signatures, input/output types, and event structures.

3. Utilize a web3 library like Web3.js for JavaScript to encode function calls or decode function return values according to the contract's ABI.

Link to the article