web3.py: Log filter unable to match entries by unindexed argument values when argument is value is not 32bytes

  • Web3.py version 4.2.1
  • geth version: 1.8.0-unstable

https://web3py.readthedocs.io/en/latest/filters.html?highlight=eventFilter#module-web3.utils.filters

Says: event_filter = mycontract.events.myEvent.createFilter(fromBlock='latest', {'filter': {'arg1':10}})

But: https://web3py.readthedocs.io/en/latest/contracts.html?highlight=createfilter

Says: Contract.events.<event name>.createFilter(fromBlock=block, [toBlock=block, argument_filters={"arg1": "value"}, topics=[]])


More detail please see: https://ethereum.stackexchange.com/q/52521/4575

I have followed web3.py guide for filtering.

Through the contract instance api:

event_filter = mycontract.events.myEvent.createFilter(fromBlock='latest', {'filter':{'arg1':10}})

But I get an error for this line:

myContract.events.LogJob.createFilter(fromBlock='latest', {'filter': {'arg1':10}})

My main goal is the filter events based on their arguments.

Error I am having:

myContract.events.LogJob.createFilter(fromBlock='latest', {'filter': {'arg1':10}})
                                                                 ^
SyntaxError: positional argument follows keyword argument

[Q] How could I fix this error?


Please also note that argument_filters seems like does not work. After I use argument_filters I do not get any error, but filter returns [] even I provide correct event’s keyword (dictionary of argument name and its value).

Please see an example:

blockReadFrom = 1899201;
myFilter = eBlocBroker.events.LogJob.createFilter(fromBlock=blockReadFrom)
print(myFilter.get_all_entries())

Returns, here you can see that there is emitted event with 'storageID': 0 under AttributeDict:

[AttributeDict({'address': '0x128c9F368F12C24Cc2a4f88dCDCf3daA13C9667e', 'transactionHash': HexBytes('0x8f7c50fe276057ea90985be6d14dc7abb79ee0430c66bd161861b582b7db0c97'), 'args': AttributeDict({'desc': 'Science', 'jobKey': 'QmRsaBEGcqxQcJbBxCi1LN9iz5bDAGDWR6Hx7ZvWqgqmdR', 'index': 21, 'storageID': 0, 'clusterAddress': '0x75A4c787c5c18C587B284a904165Ff06a269B48C'}), 'transactionIndex': 0, 'event': 'LogJob', 'blockHash': HexBytes('0x9782cb281aa72defe54e0f84055a03a0b1bf6c6f21bd3d276a1252098f83c15f'), 'logIndex': 0, 'blockNumber': 1899201})]

blockReadFrom = 1899201;
myFilter = eBlocBroker.events.LogJob.createFilter(fromBlock=blockReadFrom, argument_filters={'storageID':0})
print(myFilter.get_all_entries())

Returns:

[]

And interesting point that following line returns a valid output even though 'arg1': 999 or 'arg111': 999 etc. does not exists.

myFilter = eBlocBroker.events.LogJob.createFilter(fromBlock=blockReadFrom, argument_filters={'arg1': 999})

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 24 (13 by maintainers)

Most upvoted comments

Have a look at the solidity doc regarding indexed event arguments.

You can designate up to 3 indexed arguments per event like so:

    event LogJob(address clusterAddress,
		 string indexed jobKey,
		 uint indexed index,
		 uint8 indexed storageID,		 
		 string desc
		 );

For dynamically sized arguments, like arrays, bytes and strings, the keccak hash of the value will be stored in the log topic list, rather than the value. Using indexed arguments allows you to quickly search the blockchain for the transaction where an event argument value was emitted to the log, but for dynamic sized arguments that are indexed you cant retrieve the value, you can only search for known values.

It means you need to plan for how your queries are going to look. Basically, only index the argument used to filter the results, not the argument results you want to retrieve. For example, if you will have the jobKey, and want to find the storageID or desc based on the jobKey, only have the jobKey indexed.

Closing as I believe this is covered in https://github.com/ethereum/web3.py/issues/836