rea-reverse

EVM function selector extractor: selectors, arguments and storage from bytecode

Paste deployed (runtime) contract bytecode to list its 4-byte function selectors with inferred argument types and state mutability, plus the storage layout and compiler metadata. No ABI, verified source or RPC needed.

Your bytecode never leaves your browser. EVMole runs as WebAssembly in a Web Worker on this page. Nothing is uploaded. How to verify this yourself

Whitespace and a leading 0x are ignored. Up to 1 MiB of bytecode.

Hex text or raw bytecode bytes.

Two limits to keep in mind

  • State mutability is inferred from the bytecode and can differ from what the source declares: a view function that never reads storage is reported as pure, for example.
  • EOF contracts (bytecode starting with 0xEF00) are not supported yet; only legacy EVM bytecode is analyzed.

A deployed smart contract does not carry its ABI. What it carries is bytecode, and at the start of almost every Solidity or Vyper contract that bytecode contains a dispatcher: a sequence of comparisons that matches the first four bytes of the call data against the selectors of the external functions the contract supports. Those selectors, and a good amount of information about each function, can be read back from the bytecode alone.

This tool does that inside your browser. You paste runtime bytecode or pick a file, and the page lists the selectors it finds, together with the argument types, state mutability and storage layout it can infer. The bytecode never leaves your machine.

What it does

Input. Paste hexadecimal runtime bytecode into the text area. A 0x prefix is optional and whitespace (spaces, line breaks) is ignored, so you can paste a copied block as is. You can also choose a file; the file may contain hex text or the raw bytes, and the page handles both. Limits: up to 1 MiB of bytecode, up to 4 MiB of input, and a 30-second time limit for the analysis.

Output. For each function the analyzer finds, you get:

  • the 4-byte selector, such as 0xa9059cbb
  • the byte offset of the function body in the bytecode
  • the dispatch type, telling you how the function is reached from the dispatcher
  • the inferred argument types, such as address,uint256
  • the inferred state mutability: pure, view, payable or nonpayable

Beyond the function list, the report also shows:

  • Storage layout: the storage slots the code touches, with offset and inferred type, and which selectors read or write each slot. Transient storage (TLOAD/TSTORE) is included.
  • Compiler metadata: the CBOR block that solc and other compilers append to the end of the runtime code, decoded where possible. It often contains the solc version and an IPFS hash of the metadata file.

You can export the whole result as JSON to keep it, diff it against a later version, or feed it to other tools.

Function names

A selector is the first four bytes of keccak256 of the function signature, for example keccak256("transfer(address,uint256)"). A hash cannot be reversed, so a name can never be “decoded” from bytecode. The only way to attach a name is to look the selector up in a list of known signatures.

The page ships with a built-in, offline signature table of a little over two hundred common signatures: ERC-20, ERC-721 and ERC-1155, Ownable, AccessControl, Uniswap and similar widely used interfaces. It does not query 4byte.directory or any other online database. A selector found in the table is labeled Offline table; anything else is labeled Unknown. If a table entry’s parameters do not agree with the parameters inferred from the bytecode, the page warns you that this may be a selector collision or an inference error. Four-byte selectors do collide, so a name match is a hypothesis, not proof.

How it works

The analysis engine is EVMole 0.9.3, compiled to WebAssembly and run in a Web Worker so the page stays responsive. EVMole does not need source code or an ABI. It executes the dispatcher symbolically to find the selector comparisons and the jump targets they lead to, then follows each function body to see how it reads call data (which suggests the argument types), whether it checks CALLVALUE (payable or not), and which storage and state-changing opcodes it reaches (view, pure or nonpayable). The same tracking of SLOAD, SSTORE, TLOAD and TSTORE produces the storage layout.

The metadata decoder looks at the length field in the last two bytes of the code and parses the CBOR map in front of it, which is where solc writes keys such as solc and ipfs.

The same EVMole version is what the REA command line uses for inspect-evm-interface, so you can cross-check the browser result offline; see the guide linked below.

How your bytecode stays private

Your bytecode is not uploaded. That follows from how the page is built:

  • The analysis runs in a Web Worker on your device. The EVMole WebAssembly file (about 470 KB) is downloaded from this site, under /_astro/, as soon as the page loads, so after that the analysis works even with the network turned off.
  • The worker runs under a Content Security Policy that allows requests only to this site’s own origin, which it needs to load that .wasm file. Any other network access from the worker is blocked by the browser.
  • The only analytics event is evm_analyze. It carries success or an error code, a bucket for the number of functions found, and a bucket for the duration. It never contains bytecode, selectors, names or any other content. The full list of events is on the privacy page.
  • The tool page shows no ads.

How to verify this yourself

  1. Open your browser’s developer tools and switch to the Network tab before pasting anything. Run an analysis and inspect every request that appears. None of them contains your bytecode; the only requests from this site are page assets such as the .wasm file.
  2. Or load the page, wait for it to finish loading, then go offline (turn off Wi-Fi, or tick Offline in the Network tab) and run the analysis. It still completes, because nothing needs to leave your machine.

Limitations

Read the output as inference from bytecode, not as a verified ABI.

  • State mutability is inferred from the bytecode and can differ from what the source declares. For example, a function declared view that never actually reads state may be reported as pure. The compiler and optimizer can also change what is visible.
  • EOF contracts are not supported yet. Code that starts with 0xEF00 (the EVM Object Format) is rejected.
  • You need runtime (deployed) bytecode, not creation/init code. Creation code contains a constructor and copies the runtime code into memory; its dispatcher is not the one you want. With solc, use --bin-runtime, not --bin.
  • Proxies show only the proxy’s own selectors. A proxy forwards unknown calls to an implementation contract with DELEGATECALL. To see the real interface, analyze the implementation contract’s bytecode.
  • Argument types are inferred. Simple types are usually right. Nested structs, arrays and other dynamic types may be reported imprecisely.
  • Other compilers vary. Vyper output or hand-written bytecode can produce different, sometimes less complete, results than typical solc output.
  • No source and no decompilation. The tool recovers the interface and storage layout, not the logic. It does not produce Solidity or any other source.
  • An empty or short list does not prove that nothing else is callable. Unusual dispatchers may hide functions from the analysis.

FAQ

Does it look up function names online?

No. Names come only from the offline table built into the page. Selectors not in the table are shown as unknown. If you look them up in a public database yourself, treat any match as a hypothesis, because selectors collide.

Why does a function show as pure when the source says view?

Mutability is inferred from what the bytecode actually does. If a view function never reads storage or environment data, nothing in the code distinguishes it from pure. The reverse can also happen. Compare against the ABI when you have it.

I pasted bytecode and got almost nothing. Why?

The most common causes are creation code instead of runtime code, a proxy contract, or an EOF contract (starting with 0xEF00). Check which kind of bytecode you copied.

Where do I get runtime bytecode?

From your own build (solc --bin-runtime, or the deployedBytecode field in Hardhat or Foundry artifacts), or from a node using eth_getCode for an address you are allowed to examine. The tool itself makes no RPC or explorer requests.

Is the storage layout the same as solc’s storage layout output?

No. It is reconstructed from the slots the code accesses. It shows slots, offsets, inferred types and which selectors touch them, but not variable names, and slots computed at runtime (for example mapping entries) may not be fully represented.

What does the exported JSON contain?

The same data shown on the page: selectors, offsets, dispatch types, arguments, mutability, name matches, storage layout and decoded metadata. It is generated in your browser and saved directly to your device.

Compliance

Use this tool on contracts you wrote, contracts you are authorized to review, or public contracts whose bytecode is published on chain. Respect the licenses of the code you analyze and the laws that apply to you. Recovering an interface does not grant any right to the code, and the tool gives no advice on exploiting contracts.