ABI as translator — mapping frontend to bytecode payloads
JSON interfaces, function selectors, encoding args, and translating frontend calls to raw hex payloads.
When I first looked at a frontend Web3 codebase, I saw developers importing a massive, ugly JSON file called the ABI (Application Binary Interface) and passing it to ethers.js:
I kept asking: Why do we need this massive JSON file? Can't JavaScript just talk directly to the smart contract? Why does a Web3 app fail to compile if the ABI is slightly wrong?
The truth is, the ABI is the Rosetta Stone of Web3. It translates human-friendly JavaScript calls into raw hexadecimal payloads that the EVM can execute.
1. The Problem: EVM Speaks Hex, JS Speaks Objects
In a standard Web2 app, when you want to call an API, you send a JSON payload: POST /users { "id": 12, "name": "Alice" }. The server reads the string, parses the JSON, and maps it.
In Web3:
- The EVM has no concept of strings, object keys, or JSON.
- The EVM only understands hexadecimal bytes.
- The EVM doesn't know what a function named
transfer(address,uint256)is.
When you call contract.transfer("0x99...", 1000) in JavaScript, a library like ethers.js or viem uses the ABI JSON to format and serialize that function call into a single, compact hex string:
This raw hex string is packed into the data field of your transaction.
2. Anatomy of a Hex Payload: Function Selectors
Every transaction data payload calling a smart contract is structured into two parts:
- The Function Selector (First 4 bytes / 8 characters): This tells the EVM which function inside the contract to execute.
- The Encoded Arguments (Remaining bytes): This passes the parameters to the function.
How is the Function Selector calculated?
The EVM uses a cryptographic hash (Keccak-256) of the canonical function signature.
For example, to call transfer(address,uint256):
- Canonical signature:
transfer(address,uint256)(no spaces, uint256 instead of uint!) - Take Keccak-256 hash:
SmartAccount.sol
- Take the first 4 bytes:
0xa9059cbb.
Every time the EVM runs your transaction, it looks at the first 4 bytes (0xa9059cbb), matches it against its internal list of function selectors, and jumps directly to that block of code!
3. Layman Explanation: The Translator Booth
Imagine you are trying to order food at a restaurant in a country where the chef only speaks a very specific code language (e.g. they only understand index numbers: "Option 42, Value 12").
You only speak English: "I want to order 3 pizzas."
The ABI is your printed menu listing English names next to the chef's secret index numbers:
"orderPizza(uint256)"$\rightarrow$ Menu Item0x882a1b
Your frontend library is the translator booth. It takes your request ("3 pizzas"), looks at the ABI menu, translates it to 0x882a1b0000000000000000000000000000000000000000000000000000000000000003 (Menu Item 0x882a1b, Quantity 3 encoded), and hands it to the waiter (the RPC node) to deliver to the chef (the EVM).
If the menu is wrong or outdated, you translate the wrong code, the chef gets confused, and your order (the transaction) fails.

4. Technical Breakdown: ABI JSON Structure
An ABI is generated automatically by the compiler. It is an array of objects describing variables, functions, and events:
This tells the frontend:
- The function
transferexists. - It accepts an
addressand auint256. - It returns a
bool. - It does not accept payments (
nonpayable).
With this metadata, ethers can perform client-side validation: if you pass a string instead of a number for amount, it rejects the transaction before broadcasting, saving you failed transaction gas fees!
Many developers copy and paste ABIs manually into their frontend code, which leads to compilation errors when contracts evolve. Always use compiler artifact pipelines (like Hardhat's artifacts output or Wagmi's CLI/types integrations) to keep your ABIs synced automatically.
Take a signature like balanceOf(address). Calculate the Keccak-256 hash of that string using an online tool (like keccak-256.net). Extract the first 4 bytes. Compare it with the function selector shown on Etherscan for standard ERC-20 token contract calls.
Was this lesson helpful?
Let us know what you think of this specification. (submitting anonymously)
