Python Web3 – How to Decode json.loads(log_event) Efficiently

eventsweb3.py

Using python 3.11.4, web3 6.9.0

I receive log information via websocket subscription. Below is sample output this omits:

swap_log = {
  'removed': False, 
  'logIndex': '0x8e', 
  'transactionIndex': '0x22', 
  'transactionHash': '0x17dfc27ab5506d7f989aa1aa04c75b5c79f74f508bcc5cf5c1e1afa200766a29', 
  'blockHash': '0xe543dc9239596a635c820762778875d0a7c9a2b1daef2924ccb91db7aa78c907', 
  'blockNumber': '0x1154e64', 
  'address': '0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640', 
  'data': '0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffe897f6df20000000000000000000000000000000000000000000000003523e83b7315d3c20000000000000000000000000000000000006068aa20f003aa6b6703f385517e000000000000000000000000000000000000000000000002157d62b06ae34527000000000000000000000000000000000000000000000000000000000003162d', 
  'topics': ['0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67', 
           '0x0000000000000000000000003208684f96458c540eb08f6f01b9e9afb2b7d4f0', 
           '0x0000000000000000000000001111111254eeb25477b68fb85ed929f73a960582']
}

If I try to decode w/ web3 I get the following error:

>>> swap_contract.events.Swap().process_log(swap_log)
web3.exceptions.MismatchedABI: The event signature did not match the provided ABI

However, if I use web3 to get the log on its own, it works:

swap_txn_hash = '0x17dfc27ab5506d7f989aa1aa04c75b5c79f74f508bcc5cf5c1e1afa200766a29'
txn_receipt = w3.eth.get_transaction_receipt(swap_txn_hash)
txn_log = txn_receipt['logs'][7]  #happened to be the 8th event in this txn's logs
swap_contract.events.Swap().process_log(txn_log)

And here is the difference between the websocket subscription output and what web3 provides:

websocket:

{
'removed': False,
'logIndex': '0x8e',
'transactionIndex': '0x22',
'transactionHash': '0x17dfc27ab5506d7f989aa1aa04c75b5c79f74f508bcc5cf5c1e1afa200766a29',
'blockHash': '0xe543dc9239596a635c820762778875d0a7c9a2b1daef2924ccb91db7aa78c907',
'blockNumber': '0x1154e64',
'address': '0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640',
'data': '0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffe897f6df20000000000000000000000000000000000000000000000003523e83b7315d3c20000000000000000000000000000000000006068aa20f003aa6b6703f385517e000000000000000000000000000000000000000000000002157d62b06ae34527000000000000000000000000000000000000000000000000000000000003162d',
'topics': ['0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67', '0x0000000000000000000000003208684f96458c540eb08f6f01b9e9afb2b7d4f0', '0x0000000000000000000000001111111254eeb25477b68fb85ed929f73a960582']
}

web3:

AttributeDict({
'address': '0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640',
'blockHash': HexBytes('0xe543dc9239596a635c820762778875d0a7c9a2b1daef2924ccb91db7aa78c907'),
'blockNumber': 18173540,
'data': HexBytes('0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffe897f6df20000000000000000000000000000000000000000000000003523e83b7315d3c20000000000000000000000000000000000006068aa20f003aa6b6703f385517e000000000000000000000000000000000000000000000002157d62b06ae34527000000000000000000000000000000000000000000000000000000000003162d'),
'logIndex': 142,
'removed': False,
'topics': [HexBytes('0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67'), HexBytes('0x0000000000000000000000003208684f96458c540eb08f6f01b9e9afb2b7d4f0'), HexBytes('0x0000000000000000000000001111111254eeb25477b68fb85ed929f73a960582')],
'transactionHash': HexBytes('0x17dfc27ab5506d7f989aa1aa04c75b5c79f74f508bcc5cf5c1e1afa200766a29'),
'transactionIndex': 34})

Clearly web3 does some internal processing to convert from all string representation to Int, HexBytes, etc. Is there a pre-existing way to do this conversion w/in the web3 library or do I need to create my own converter?

Best Answer

Is there a pre-existing way to do this conversion w/in the web3 library or do I need to create my own converter?

For decoding textual JSON-RPC response, you can reuse the code from web3.py, namely LOG_ENTRY_FORMATTERS. How to apply this to your own Python code is left as an exercise to the reader.