No easy way to get all events for a contract (while still parsing the results). See this StackExchange question. One option is to iterate over all the events, but it's a bit awkward right now. I think the easiest way is:
from web3.contract import ContractEvent
filters = [
event.createFilter(fromBlock='latest')
for event in myContract.events
if isinstance(event, ContractEvent)
]
Some options:
__iter__ on Contract.events to iterate through all events in the ABI (my favorite option, except that it's inconsistent with contract.functions, which is doing the wrong thing IMO)Contract.all_events() equivalent to Contract.all_functions()Then the example changes to:
filters = [
event.createFilter(fromBlock='latest')
for event in myContract.events
]
Of course, we could also implement contract.create_filter() like web3.js's contract.events.allEvents. I kind of like that the filters are event specific right now, though. I don't think it's too big a deal to require callers to write a filter loop on events.
+1 for implementing __iter__. I need to think about all_events. While I see the use, it would be a simple filter with just the contract address, and not allow one to filter on arguments or topics. It might be better to just steer users towards instantiating filter object with just the contract address rather than providing a helper function to do the same.
Maybe we could publish a recipe on combining filters into a single object that can be polled.
It might be better to just steer users towards instantiating filter object with just the contract address rather than providing a helper function to do the same.
The key difference is that they want the automatic argument decoding, which they don't get with the generic filter on an address. I like the recipe idea.
@carver
Implement __iter__ on Contract.events to iterate through all events in the ABI (my favorite option, except that it's inconsistent with contract.functions, which is doing the wrong thing IMO)
__iter__() has been implemented in ContractFunctions. Is there something specific about that implementation that you would like to see changed? This might be a good time to figure out a consistent approach for both functions and events.
Is there something specific about that implementation that you would like to see changed?
Yeah, it's only returning the name (str) of the function. I think it should return the full ContractFunction object.
Wow, this ticket is still open! Here is a snippet that emits all decode-able events for a specific contract. I too found this was an annoyance @carver
from web3.contract import Contract
from web3._utils.events import get_event_data
from eth_utils import event_abi_to_log_topic
def fetch_events(contract: Contract, fromBlock, toBlock=None):
topic2abi = {event_abi_to_log_topic(_): _
for _ in contract.abi if _['type'] == 'event'}
logs = w3.eth.getLogs(dict(
address=contract.address,
fromBlock=fromBlock,
toBlock=toBlock
))
for entry in logs:
topic0 = entry['topics'][0]
if topic0 in topic2abi:
yield get_event_data(w3.codec, topic2abi[topic0], entry)
Ping @kclowes for an old issue that could use some love.
Most helpful comment
The key difference is that they want the automatic argument decoding, which they don't get with the generic filter on an address. I like the recipe idea.