Skip to content

Calldata Decoder

Paste a contract address and raw calldata. Get the function it calls and every argument, decoded and typed. Other ABI decoders make you supply the ABI; this one resolves it from the address.

EthereumBaseBNB Smart ChainPolygonno signup · no wallet connect · free

The transaction's input data, starting with its 4-byte function selector.

Result

Paste a contract address and a raw calldata hex string, then click "Decode calldata" to see the function and its arguments here.

Run this elsewhere

Want your AI agent to run this?

Same query, no browser. Connect evmquery’s MCP server once and Claude, Cursor, ChatGPT, VS Code or Windsurf can read this contract in chat.

Then just ask

Decode the calldata 0x70a0823100000000000000000000000028c6c06298d514db089934071355e5743bf21d60 against 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 on Ethereum.

One-time setup for Claude Code

claude mcp add evmquery \
  --transport http \
  https://api.evmquery.com/mcp

The first connection opens a browser sign-in. Free tier, no credit card.

Why ABI-first decoders stall on real calldata

The Calldata Decoder turns a raw 0x transaction input into the function it calls and the arguments it carries. It is built for the moment you are staring at an unlabelled hex blob in a block explorer, a mempool feed, a multisig queue, or a failed transaction, and need to know what it actually does.

Every other calldata decoder in this category makes you bring the ABI. bia.is, solarity.dev’s decoder, and OpenChain’s old ABI tool all start with a text area where you paste the contract’s ABI JSON, and only then will they decode your bytes. That is the hard half of the job, and it is the half they hand back to you: if the contract is unverified, or a proxy, or one of forty deployments of the same protocol with drifting signatures, finding the right ABI is the work.

This tool only needs the contract address. evmquery resolves the ABI server-side, then decodes against it.

Key facts

  • Decodes raw calldata from a contract address alone. No ABI JSON to paste, no ABI file to find, no 4byte guesswork.
  • The ABI comes from evmquery’s contract resolution: verified source first (Sourcify, Etherscan), then code-reuse matching against known bytecode, IPFS metadata, known interfaces, and signature databases (OpenChain, 4byte, evmole).
  • Proxy-aware. Paste an EIP-1967, UUPS, Beacon, EIP-1167, EIP-2535 diamond, Gnosis Safe, or EIP-7702 address and the decoder runs against the implementation’s ABI, not the proxy’s own stub.
  • Matching is exact, not probabilistic: the 4-byte function selector is checked against the methods this specific contract exposes, so overloads and same-selector collisions resolve to the right one.
  • Covers Ethereum, Base, BNB Smart Chain, and Polygon, with more EVM chains being added.

Reading a decoded call

  1. Paste the contract address the transaction was sent to.
  2. Pick the chain it is deployed on.
  3. Paste the raw calldata, the 0x-prefixed input data from the transaction.
  4. Run it and read the decoded function and arguments in the result panel.

The result panel shows the matched function’s canonical signature, its 4-byte selector, the address the method actually executes on, and where its ABI was resolved from. Below that, every argument is listed with its name, its Solidity type, and its decoded value. A raw JSON toggle at the bottom shows the full resolved schema for debugging.

If nothing matches, the tool says so explicitly rather than guessing at a decode.

Selector matching against a resolved method set

Calldata has exactly two parts. The first four bytes are the function selector: the leading four bytes of keccak256 over the function’s canonical signature, so transfer(address,uint256) hashes down to 0xa9059cbb. Everything after that is the ABI-encoded argument list, packed into 32-byte words with offsets for the dynamic types.

Decoding the second part is mechanical, and every EVM library does it. The problem is the first part. A selector is a one-way hash of a signature, so you cannot invert 0xa9059cbb back into transfer(address,uint256). You either already know the ABI, or you look the selector up in a signature database and hope the answer applies to your contract. That hope is the failure mode: signature databases are crowd-sourced and full of collisions and near-duplicates, and they know nothing about which overload the contract in front of you actually implements.

This tool resolves the ABI from the address first, then matches. That request is the same one behind the Contract Inspector:

POST /query/describe
{
"chain": "evm_ethereum",
"schema": { "contracts": { "target": { "address": "0x..." } } },
"include": ["resolution"]
}
  • The response lists every method evmquery could resolve for that address, each with a real ABI fragment: name, inputs, outputs, stateMutability.
  • If the address is a proxy, resolution follows the chain first. Each method reports the executesAt address its logic runs on, and diamonds get their facets flattened into one method list.
  • Each method also reports its source, so you can see whether a given signature came from verified source or from a signature database, and calibrate how much to trust the decode.
  • The tool then computes each resolved method’s selector locally, finds the one matching your calldata’s first four bytes, and decodes the remaining bytes against that method’s inputs.

Because the candidate set is “methods this contract exposes” rather than “every signature anyone ever uploaded”, a match is a real match.

Two selectors show up in decoded calldata more than any others: 0x095ea7b3 for ERC-20’s approve(address,uint256), and 0xa9059cbb for transfer(address,uint256). If you decode an approve call and want to know what allowance it actually left in place afterward (approvals in a mempool feed or a Safe queue don’t tell you the current state, only the transaction that would set it), the Token Allowance Checker reads allowance(owner, spender) directly rather than inferring it from calldata.

Decode calldata in your own stack

Two steps: resolve the ABI over REST, then decode locally with whatever ABI library you already use. The examples target USDC on Ethereum and a balanceOf(address) call.

REST (curl)

curl -X POST https://api.evmquery.com/api/v1/query/describe \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"chain": "evm_ethereum",
"schema": {
"contracts": { "target": { "address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" } }
},
"include": ["resolution"]
}'

Python

import requests
from eth_utils import function_abi_to_4byte_selector
from eth_abi import decode
CALLDATA = "0x70a0823100000000000000000000000028c6c06298d514db089934071355e5743bf21d60"
resp = requests.post(
"https://api.evmquery.com/api/v1/query/describe",
headers={"x-api-key": "YOUR_API_KEY"},
json={
"chain": "evm_ethereum",
"schema": {
"contracts": {"target": {"address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"}},
},
"include": ["resolution"],
},
timeout=10,
)
methods = resp.json()["contracts"][0]["methods"]
selector = bytes.fromhex(CALLDATA[2:10])
match = next(
(m for m in methods if function_abi_to_4byte_selector(m["abi"]) == selector),
None,
)
if match is None:
raise SystemExit(f"no resolved method with selector 0x{selector.hex()}")
types = [i["type"] for i in match["abi"]["inputs"]]
print(match["abi"]["name"], decode(types, bytes.fromhex(CALLDATA[10:])))
# balanceOf ('0x28c6c06298d514db089934071355e5743bf21d60',)

TypeScript

import { decodeAbiParameters, toFunctionSelector } from "viem";
const CALLDATA =
"0x70a0823100000000000000000000000028c6c06298d514db089934071355e5743bf21d60";
const resp = await fetch("https://api.evmquery.com/api/v1/query/describe", {
method: "POST",
headers: {
"x-api-key": process.env.EVMQUERY_API_KEY!,
"Content-Type": "application/json",
},
body: JSON.stringify({
chain: "evm_ethereum",
schema: {
contracts: { target: { address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" } },
},
include: ["resolution"],
}),
});
const { contracts } = await resp.json();
const selector = CALLDATA.slice(0, 10);
const match = contracts[0].methods.find(
(m) => toFunctionSelector(m.abi) === selector,
);
if (!match) throw new Error(`no resolved method with selector ${selector}`);
const args = decodeAbiParameters(match.abi.inputs, `0x${CALLDATA.slice(10)}`);
console.log(match.abi.name, args);
// balanceOf [ '0x28C6c06298d514Db089934071355E5743bf21d60' ]

The free tier has no monthly cap. Get a free API key to drop these snippets into your project.

Where decoded calldata actually gets read

  • Reviewing a multisig transaction before you sign it. A Safe queue shows you a target address and a hex blob. Decoding it is the difference between approving a treasury transfer and approving an owner change. Cross-check the signers who would need to approve it with the Gnosis Safe Inspector, which reads the same Safe’s owner list and threshold directly.
  • Debugging a reverting transaction. Confirm the call you built is the call you meant to build, with the arguments you meant to pass, before you go looking for the revert reason.
  • Reading an unverified or unfamiliar contract’s traffic. When the explorer shows “Method ID 0x…” and nothing else, resolution from the address often recovers a signature the explorer did not have.
  • Auditing what a script or bot actually sent. Feed logged calldata back through the decoder and check it against what the code intended.
  • Untangling proxy traffic. Calldata sent to a proxy address decodes against the implementation’s ABI, which is where the function you care about lives.
  • Confirming an NFT transfer before it lands. A decoded safeTransferFrom(address,address,uint256) call tells you the token ID and both addresses; the ERC-721 Inspector then confirms who owns that token ID right now, before the transaction you’re reviewing changes it.

FAQ

Do I need the contract’s ABI to decode calldata here?

No. That is the difference between this and most calldata decoders. You paste the contract address and evmquery resolves the ABI server-side, from verified source (sourcify, etherscan) where it exists, then from code-reuse matching, metadata-ipfs, known-interface matching, and signature databases (openchain, fourbyte, evmole). The decoder runs against whatever it resolves.

What is a function selector?

The first four bytes of calldata, and the only part of it that says which function is being called. It is the first four bytes of the keccak256 hash of the function’s canonical signature, so transfer(address,uint256) becomes 0xa9059cbb. Everything after those four bytes is the ABI-encoded argument list.

Can I look up a 4byte signature without a contract address?

Not on this page. A standalone 4byte signature lookup tells you what a selector is probably called, but it cannot tell you which overload a specific contract actually exposes, so the arguments it decodes can be wrong. Resolving the ABI from the address first removes that ambiguity, which is why the address field is required.

Why does it say no matching function?

The selector in your calldata does not match any method evmquery resolved for that address. Usually the calldata belongs to a different contract or a different version of the same one, the function is not part of the contract’s public ABI (internal, or removed in an upgrade), or the ABI could not be fully resolved for that address. The Contract Inspector shows the full resolved method list, which tells you which of the three you are looking at.

Does it follow proxies?

Yes. Contract resolution follows EIP-1967, UUPS, Beacon, EIP-1167 minimal proxies, EIP-2535 diamonds, Gnosis Safe, and EIP-7702 delegations, so pasting a proxy address decodes against the implementation’s ABI rather than the proxy’s own near-empty one. If you just want to confirm which pattern an address uses without decoding a specific call, the Proxy Contract Detector runs the same resolution and shows the full hop chain on its own.

Which chains are supported?

Ethereum, Base, BNB Smart Chain, and Polygon today. More EVM chains are being added on the evmquery backend.

Can I use this from my own application?

Yes. The ABI resolution step is a single POST to the public REST API, and the decoding step is a few lines of viem, ethers, or eth-abi. See the snippets above. The free tier has no monthly cap, and bringing your own API key removes the rate limit applied to this page.

Limits and accuracy

  • The decode is only as good as the resolved ABI. Methods resolved from signature databases rather than verified source can carry an imprecise parameter list, and the result panel reports the source for exactly this reason.
  • Resolution reflects the contract’s current on-chain state. Calldata from an old transaction sent to a since-upgraded proxy may not match today’s implementation ABI.
  • Constructor arguments and raw ETH transfers are not calldata in this sense and will not match anything.
  • The demo is rate limited per browser. If you hit the limit, grab a free API key and the limit goes away.

A successful decode tells you what a transaction claims to call, not whether it is safe to sign. Argument values still need reading.

Run this query in your own code

No monthly cap on the free tier. No credit card needed.