Contract ABI decoder, selector calculator and call encoder
Every call to an Ethereum smart contract is a blob of bytes: a 4-byte function selector followed by the ABI-encoded arguments. Block explorers decode it for verified contracts, but when you are debugging a transaction, reviewing a wallet prompt, building calldata for a multisig or writing tests, you need to do it yourself. This contract ABI decoder takes an ABI JSON, lists every function with its selector and every event with its topic hash, decodes raw input data into named, typed values, and encodes a call from values you type.
It implements the Solidity ABI specification in plain JavaScript: static types (uint/int of any width, address, bool, bytes1–32), dynamic bytes and strings, fixed and dynamic arrays, and nested tuples (structs). Selectors and topics come from an in-page Keccak-256, so transfer(address,uint256) correctly yields 0xa9059cbb.
Nothing is uploaded and no RPC node is contacted. The page is informational only and not investment advice — what a transaction does on chain is defined by the contract, not by its ABI.
How to use the Contract ABI Decoder
- Paste the Contract ABI JSON array, or press Load ERC-20 sample. The table of functions, selectors, events and topics fills in as you type.
- To decode, paste the transaction’s input data into Transaction input data and press Decode. The matching function and each argument appear in a table; Copy JSON gives you the structured result.
- To encode, pick a Function, fill in the generated fields (arrays and structs as JSON) and press Encode calldata.
- Use the copy buttons next to each selector or topic when you need them for a filter, a proxy configuration or a 4-byte directory lookup.
- If the selector is not in the ABI, the decoder still shows the data split into 32-byte words so you can inspect it by hand.
Contract ABI Decoder features
Selectors and topics
Canonical signatures with tuples expanded to (type,type), hashed with Keccak-256 exactly as solc does.
Full type coverage
Static and dynamic types, nested arrays like uint256[2][], structs as tuples and structs inside arrays.
Named output
Arguments are labelled with the names from the ABI; tuples with named components decode to objects.
Checksummed addresses
Decoded addresses are shown in EIP-55 form so you can compare them with a wallet or explorer at a glance.
Clear errors
Truncated data, a selector that does not match, a value that does not fit its type and malformed JSON are each reported with the field that caused them.
How ABI encoding lays out calldata
After the selector, arguments are encoded as a head followed by a tail. Static values (numbers, addresses, booleans, fixed-size bytes, fixed arrays of static types) occupy 32-byte words directly in the head. Dynamic values — string, bytes, dynamic arrays and any tuple containing one — leave a 32-byte offset in the head that points to where the value starts in the tail, measured from the start of the argument block.
Example: batchSend((address,uint256)[] items, string memo) called with two items and the memo “hi” encodes as: offset of items (0x40, because the head is two words), offset of memo (0xe0), then the array — its length 2 followed by two static tuples of two words each — and finally the string: length 2 and the bytes 6869 right-padded to 32 bytes. The decoder follows each offset, which is also why a wrong ABI usually produces a “data ends early” error rather than silently wrong numbers.
Selectors, topics and collisions
Only four bytes of the hash identify a function, so unrelated signatures occasionally collide (about one in four billion pairs). Public 4-byte directories exist precisely because a selector alone cannot be reversed; when you have the ABI, as on this page, the match is exact. Event topics use the full 32-byte hash, so collisions are not a practical concern.
| Signature | Hash (Keccak-256) | Used as |
|---|---|---|
transfer(address,uint256) | 0xa9059cbb… | Function selector: first 4 bytes |
approve(address,uint256) | 0x095ea7b3… | Function selector |
balanceOf(address) | 0x70a08231… | Function selector |
Transfer(address,address,uint256) | 0xddf252ad…b3ef | Event topic 0: all 32 bytes |
Reading a wallet prompt safely
- Compare the decoded to or spender address with the one you expect, using the EIP-55 checksum tool if the case looks off.
- Convert the raw amount with the token unit converter: 1000000 is 1 USDC but only 0.000000000001 of an 18-decimal token.
- An
approvefor0xffff…ffff(2256 − 1) is an unlimited allowance. That is normal for some apps but worth noticing. - Proxies forward calls to an implementation contract; decode with the implementation’s ABI, not the proxy’s.
- Function names are not verified on chain. A contract can name a function
claimRewardand have it do anything — the decoded values show what you are passing in, not what the code does with them.
Contract ABI Decoder FAQ
What is a contract ABI?
The Application Binary Interface is a JSON description of a contract’s functions, events and errors — names, parameter types and mutability. Compilers emit it; explorers publish it for verified contracts; wallets and libraries use it to encode calls and decode results.
How is a function selector calculated?
Take the canonical signature — the function name and parameter types without names or spaces, e.g. transfer(address,uint256) — hash it with Keccak-256 and keep the first four bytes. The ABI decoder shows this for every function in the ABI.
Can the ABI decoder decode a transaction without the ABI?
Partly. Without a matching entry it cannot know the types, so it shows the selector and the 32-byte words that follow. Look the selector up in a public signature database, paste a minimal ABI with that function and decode again.
Does it handle structs and nested arrays?
Yes. Structs appear in the ABI as tuple types with components; the tool encodes and decodes them, including arrays of structs and structs that contain dynamic fields.
Why does decoding say the calldata ends early?
Either the data was truncated when copied, or the ABI you pasted is for a different contract version than the one the transaction targeted. Check that the selector in the table matches the first four bytes of your data.
Is pasting an ABI or calldata here safe?
Yes. Both are public data about a contract, and the page processes them locally without any network request. It never asks for and never needs a private key.