Skip to main content
Bloklake returns logs as they are on chain: address, topic0–topic3 and data. Decoding them into named arguments needs the event’s ABI:
  • topic0 is the event selector: keccak256 of the signature, e.g. keccak256("Swap(address,uint256,uint256,uint256,uint256,address)").
  • Indexed arguments are in topic1–topic3, one per topic, each 32 bytes.
  • Non-indexed arguments are ABI-encoded together in data.
Select topic0 only if you query several events at once and need to tell them apart.

Python (eth-abi)

pip install bloklake eth-abi "eth-hash[pycryptodome]" eth-utils
The client returns hex strings: decode bytes.fromhex(log["data"][2:]), and an indexed address is the last 40 hex characters of its topic. (Reading Arrow yourself, you get bytes directly: row["data"] and row["topic1"][12:].)

TypeScript (viem)

npm install @bloklake/client viem
The rows are already hex strings, which is what viem takes. decodeEventLog wants topic0 too, so it’s selected here. Leave out topics the event doesn’t use: topic3 is null for a two-argument Transfer.

Pitfalls

  • Same selector, different events. ERC-20 and ERC-721 Transfer have the same topic0. ERC-721 indexes the token id too, so it has a topic3 and empty data. Check before decoding.
  • Proxies. For a proxied contract, the events come from the proxy’s address, but you need the implementation’s ABI.
  • Anonymous events have no selector in topic0; their first indexed argument is there instead. Filter them by address and decode by position.
  • Indexed dynamic types (string, bytes, arrays) are stored as the keccak256 of the value, so the original can’t be recovered from the topic.