For those who want to do it in a hard way, here is an example of Uniswap v2 PairCreated event:
def decode_pair_created(log: LogResult) -> dict:
"""Process a pair created event.
This function does manually optimised high speed decoding of the event.
The event signature is:
.. code-block::
event PairCreated(address indexed token0, address indexed token1, address pair, uint);
"""
# The raw log result looks like
# {'address': '0x5c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f', 'blockHash': '0x359d1dc4f14f9a07cba3ae8416958978ce98f78ad7b8d505925dad9722081f04', 'blockNumber': '0x98b723', 'data': '0x000000000000000000000000b4e16d0168e52d35cacd2c6185b44281ec28c9dc0000000000000000000000000000000000000000000000000000000000000001', 'logIndex': '0x22', 'removed': False, 'topics': ['0x0d3648bd0f6ba80134a33ba9275ac585d9d315f0ad8355cddefde31afa28d0e9', '0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', '0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'], 'transactionHash': '0xd07cbde817318492092cc7a27b3064a69bd893c01cb593d6029683ffd290ab3a', 'transactionIndex': '0x26', 'event': <class 'web3._utils.datatypes.PairCreated'>, 'timestamp': 1588710145}
# Do additional lookup for the token data
web3 = log["event"].web3
token_cache: TokenCache = log["context"]
block_time = datetime.datetime.utcfromtimestamp(log["timestamp"])
# Any indexed Solidity event parameter will be in topics data.
# The first topics (0) is always the event signature.
token0_address = convert_uint256_string_to_address(log["topics"][1])
token1_address = convert_uint256_string_to_address(log["topics"][2])
factory_address = log["address"]
# Chop data blob to byte32 entries
data_entries = decode_data(log["data"])
# Any non-indexed Solidity event parameter will be in the data section.
pair_contract_address = convert_uint256_bytes_to_address(data_entries[0])
pair_count = int.from_bytes(data_entries[1], "big")
# Now enhanche data with token information
token0 = token_cache.get_token_info(web3, token0_address)
token1 = token_cache.get_token_info(web3, token1_address)
data = {
"block_number": int(log["blockNumber"], 16),
"timestamp": block_time.isoformat(),
"tx_hash": log["transactionHash"],
"log_index": int(log["logIndex"], 16),
"factory_contract_address": factory_address,
"pair_contract_address": pair_contract_address,
"pair_count_index": pair_count,
"token0_symbol": token0.symbol,
"token0_address": token0_address,
"token1_symbol": token1.symbol,
"token1_address": token1_address,
}
return data
Full example available on web3-ethereum-defi project.