Decoding Ethereum Virtual Machine (EVM) log data from raw logs can be a complex process. This guide provides an example-first approach to deconstructing key smart contract topics.
Table of contents
Open Table of contents
Understanding EVM Log Format
EVM logs contain several key fields, including:
block_number
: The number of the block where the transaction was included.block_hash
: The hash of the block.transaction_hash
: The hash of the transaction.address
: The address of the contract that emitted the log.topics
: An array of 32-byte log topics.data
: A string containing any non-indexed data from the event.
The first topic in the topics
array is always the event topic itself. Any subsequent topics are for indexed data fields.
Decoding Log Data
1. Deconstructing Topics
Topics are 32-byte hexadecimal strings. To convert an indexed address from its padded format to a standard address format, follow these steps:
- Remove the
0x
prefix. - Take the last 20 bytes (40 characters) of the string.
- Add the
0x
prefix back to the beginning.
For example, to convert 0x0000000000000000000000005a2020ff5a7cf0b8c73b268863f630ce4bcbf859
:
- Strip the prefix:
0000000000000000000000005a2020ff5a7cf0b8c73b268863f630ce4bcbf859
. - Take the last 40 characters:
5a2020ff5a7cf0b8c73b268863f630ce4bcbf859
. - Add the prefix:
0x5a2020ff5a7cf0b8c73b268863f630ce4bcbf859
.
2. Deconstructing Data
The data
field is a single, long hexadecimal string prefixed with 0x
. To decode it:
- Remove the
0x
prefix. - Split the remaining string into fixed-width 64-character slices.
- Convert each slice from hexadecimal to the appropriate data type (e.g. number, boolean, or string) based on the event’s structure.
For example, using the data string 0x000000000000000000000000000000000000000000000000000000000098968000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000960544
:
- The first slice,
0000000000000000000000000000000000000000000000000000000000989680
, converts to the number10000000
(auint256
). - The second slice,
0000000000000000000000000000000000000000000000000000000000000001
, converts to1
(abool
). - The third slice,
0000000000000000000000000000000000000000000000000000000000960544
, converts to the number9831748
(auint256
).
Smart Contract Topic Examples
Here are some examples of smart contract topics and how to decode their data using the methods above.
Both indexed and non-indexed data
- Event Structure:
Buy(address indexed user, uint256 usdAmount, bool boughtBased, uint256 tokensReceived)
- Event Topic:
0x0261151a7784321c0b49e79b25a33288d9ddeb79bde1de0842c27553200bff5c
- Decoding:
- The
user
address is indexed and found in the second topic slot. - The
usdAmount
,boughtBased
, andtokensReceived
fields are not indexed and are found in thedata
field.
- The
Only indexed data
- Event Structure:
MarketCreated(uint64 indexed marketCounter, address indexed marketAddress, address indexed creator)
- Event Topic:
0xd653a09379af1a9472753eadfc8952c8fac7326a1dc3060a0b146ca0de7da5c6
- Decoding:
- All event parameters (
marketCounter
,marketAddress
, andcreator
) are indexed. marketCounter
is in the second topic slot,marketAddress
is in the third, andcreator
is in the fourth.- The
data
field is empty (0x
) because there are no non-indexed fields.
- All event parameters (
Only non-indexed data
- Event Structure:
CreatorFeesClaimed(uint256 amount)
- Event Topic:
0x17e81264e9784a525cc8509a5111e7e60a77a315c8091159f7b1ae8291d6917f
- Decoding:
- There is no indexed data, so the event topic is the only topic present.
- The
amount
is a non-indexed field, found in thedata
field.
Example SQL Filter
This SQL query shows how to filter for these events using the topic hashes.
SELECT * FROM raw_logs
WHERE
'0x0261151a7784321c0b49e79b25a33288d9ddeb79bde1de0842c27553200bff5c' = ANY(topics) -- Buy
OR '0xd653a09379af1a9472753eadfc8952c8fac7326a1dc3060a0b146ca0de7da5c6' = ANY(topics) -- Create Market
OR '0x17e81264e9784a525cc8509a5111e7e60a77a315c8091159f7b1ae8291d6917f' = ANY(topics) -- Claim Creator Fees