Ethereum Event Log Decoder

Turn raw log entries (address, topics, data) into named events and parameters. Over forty common events are recognised automatically; paste a contract ABI for anything else. Every log in a receipt is decoded at once.

Explorer "Logs" tabs, viem, ethers and JSON-RPC envelopes all work; every log in a receipt is decoded.
Examples:

Computed in your browser with JavaScript. Addresses are never uploaded or stored.

What is an event log?

An event log is the record an EVM contract writes when it executes the LOG0–LOG4 opcodes (emit in Solidity). Each entry contains the emitting contract's address, up to four 32-byte topics and an arbitrary-length data field. Decoding a log means matching topics[0] to an event signature, reading the indexed parameters from the remaining topics, and ABI-decoding the non-indexed parameters from data. Explorers do this with the verified source; this page does it from the signature alone, for forty-plus common events, or from any ABI you paste.

How a log is encoded

FieldContentExample (ERC-20 Transfer)
addressThe contract that emitted the event0xdAC17F958D2ee523a2206206994597C13D831ec7 (USDT)
topics[0]keccak256 of the canonical signature0xddf252ad… = keccak256("Transfer(address,address,uint256)")
topics[1]First indexed parameter, left-padded to 32 bytesfrom address
topics[2]Second indexed parameterto address
dataABI encoding of all non-indexed parameters32-byte value

Indexed parameters of static type (address, integers, bool, bytes1–32) are stored directly in the topic. Indexed parameters of dynamic type (string, bytes, arrays, structs) are replaced by the Keccak-256 hash of their encoding, as the Solidity ABI specification's events section describes; the decoder marks these as hashed.

Worked example: a USDT transfer

Click "ERC-20 Transfer" above. topics[0] matches the Transfer signature, and because there are exactly three topics the ERC-20 layout (two indexed addresses) is chosen over the ERC-721 layout (three indexed). topics[1] decodes to from = 0xd8dA6BF2…96045, topics[2] to to = 0x1111…1111, and the single data word 0x17d7840 is value = 25000000, which at USDT's six decimals is 25 USDT. The same mechanism decodes a Uniswap V2 Swap (two indexed addresses, four amounts in data) or an ERC-1155 TransferBatch, whose data field holds two dynamic arrays with offsets and lengths.

Events recognised without an ABI

The table below is generated on the page from the same signature list the decoder uses, so each topics[0] value is a self-test of the Keccak implementation. It covers ERC-20 and ERC-721 Transfer and Approval, ApprovalForAll, ERC-1155 TransferSingle, TransferBatch and URI, WETH Deposit and Withdrawal, Uniswap V2 Swap, Sync, Mint, Burn and PairCreated, Uniswap V3 Swap, Mint, Burn, Collect and PoolCreated, OwnershipTransferred, EIP-1967 Upgraded, AdminChanged and BeaconUpgraded, Initializable, Pausable and AccessControl events, Permit2 Approval, Permit, NonceInvalidation and Lockdown, ERC-4626 Deposit and Withdraw, and Safe ExecutionSuccess, ExecutionFailure, SafeMultiSigTransaction, owner and threshold changes, SafeSetup and ProxyCreation.

Accepted inputs

Related: compute a topic hash from any signature with the selector and topic calculator, decode the transaction's calldata with the ABI decoder, or inspect a raw transaction with the Ethereum transaction decoder.

Frequently asked questions

What are topics and data in an Ethereum log?

A log has up to four 32-byte topics and a variable-length data field. topics[0] is the Keccak-256 hash of the event signature (unless the event is anonymous); topics[1..3] hold the indexed parameters, one per topic; every non-indexed parameter is ABI-encoded into data, in declaration order, exactly like function arguments.

Why does an indexed string or bytes show a hash?

The EVM cannot fit a dynamic value into a 32-byte topic, so Solidity stores keccak256 of the value instead. The original string cannot be recovered from the log; it can only be compared against a candidate by hashing that candidate. Addresses, integers, bool and bytesN are stored in full and decode normally.

ERC-20 and ERC-721 Transfer have the same topics[0]. How are they told apart?

Both have the signature Transfer(address,address,uint256), so topics[0] is identical. ERC-721 indexes tokenId, giving four topics and empty data; ERC-20 indexes only from and to, giving three topics and a 32-byte data field. The decoder picks the layout whose indexed count matches the log.

What if the event is not recognised?

The log is shown raw with topics[0] highlighted. Paste the contract's ABI (events only are enough) or a single line such as event Bid(address indexed bidder, uint256 amount) into the ABI box and decode again. Signature databases such as 4byte.directory and openchain.xyz can help identify an unknown topic hash.

How do anonymous events work?

An event declared anonymous has no signature topic, so all of its topics are indexed parameters and nothing identifies it on-chain. The decoder can only match it against anonymous events in the ABI you provide, by topic count, and says so in a note.

Are the amounts converted to token units?

Integers are shown as exact decimals. For uint256 values a hint shows the value divided by 1018 and 106, which covers ETH, most ERC-20s, USDC and USDT. For other decimals use the token decimals converter; the decoder does not know each token's decimals.

Is anything uploaded?

No. Topic hashes for the built-in table are computed with Keccak-256 in your browser when the page loads, and decoding runs locally. The page makes no network requests after loading.