How to Decode Calldata Without ABI: Function Selector and Parameter Steps
You can decode Call dat a without an ABI — look up the function selector (4 bytes) in a public database to find the "function name", then manually split the parameters according to the rules. Even if you can't find the name, you can still extract parameter values, just without the parameter names.
A leading global cryptocurrency platform,suitable for both beginners and experienced traders.
New user benefit: 20% off trading fees upon registration!!
1. First, understand the structure of Calldata: two parts
The input data (calldata) of a transaction looks like this: 0xa9059cbb0000000000000000000000003f5047bdb647dc39c88625e17bdbffee905a9f440000000000000000000000000000000000000000000011c9a62d04ed0c80000
Break it into two parts:
Function Selector: the first 4 bytes (
a9059cbb). It's the first 4 bytes of the Keccak-256 hash of the function signature (e.g.,transfer(address,uint256)), telling the contract "which function to call".Parameter data: everything after the 4 bytes. Each parameter is encoded in a 32-byte (64 hexadecimal characters) chunk, placed in order.
Prerequisite: you have a transaction's TxHash, or you directly obtained the calldata string.
2. Step 1: Look up the function name corresponding to the selector
Step 1: Query the function selector on 4byte.directory
What to do: Enter the first 4 bytes into the 4byte.directory database and find the matching function signatures.
How to do it:
Option A (web): Open 4byte.directory, type the 4-byte selector (e.g.,
0xa9059cbb) into the search box. The database returns a list of all matching signatures.Option B (API): Send a GET request to
https://www.4byte.directory/api/v1/signatures/?hex_signature=0xa9059cbb, which returns JSON results.
When you're done: You have one or more possible function signatures (e.g.,
transfer(address,uint256)). If multiple matches appear, it means different function signatures may have collided on the same selector; you need to filter them by the number of parameters.
4byte.directory is currently the largest public function selector database with a massive collection of signature mappings.
Step 2: If 4byte.directory doesn't have it, fall back to Etherscan's verified contract
What to do: If the database has no record, try to get the full ABI of the contract via Eth erscan's API.
How to do it: Call
https://api.etherscan.io/api?module=contract&action=getabi&address=target_contract_address. If the contract is open-source and verified, the API returns the full ABI. With the full ABI, you can decode precisely using Web3.py or ethers.js.When you're done: You have the full ABI or at least confirmed the function name.
A leading global cryptocurrency platform,suitable for both beginners and experienced traders.
New user benefit: 20% off trading fees upon registration!!
3. Step 2: Manually split the parameters (you can do it without an ABI)
Even if you can't find the function name, you can still extract the parameter values.
Step 3: Split the data into 32-byte chunks to extract parameters
What to do: After removing the function selector, split the remaining data into chunks of 64 characters (32 bytes).
How to do it: Take
0xa9059cbb0000000000000000000000003f5047bdb647dc39c88625e17bdbffee905a9f440000000000000000000000000000000000000000000011c9a62d04ed0c80000as an example:Selector:
a9059cbb1st parameter (address):
0000000000000000000000003f5047bdb647dc39c88625e17bdbffee905a9f44→ strip the 12-byte padding to get0x3f5047bdb647dc39c88625e17bdbffee905a9f442nd parameter (uint256):
00000000000000000000000000000000000000000000011c9a62d04ed0c80000→ decimal5250000000000000000000(with 18 decimals = 5250)
When you're done: You have a list of parameter values.
Common failure reason: Multiple function signatures sharing the same selector. For example,
transfer(address,uint256)andtransfer(address,address)can't collide, but different parameter types can indeed produce the same selector, this is "selector collision". The Nethereum documentation also explicitly states that the same selector may match multiple function signatures. In such cases, you need to deduce which function was actually called by looking at the actual parameter length.
Risk warning: 4byte.directory is a user-submitted database that is unaudited and may contain errors or misleading entries. Do not assume the call content is absolutely safe just from the function name you found.
After performing the above steps, how do you verify your decoding is correct?
Test with a verified ERC-20 transfer transaction: copy the calldata of a transfer call, extract the address and amount using the steps above — if the address matches the recipient you see, and the amount matches, the method is correct. Later, when encountering unknown contracts, if 4byte.directory returns multiple matches, use the parameter length to rule out the impossible ones.
