When a user signs up on my system, a custom 'deposit' contract gets created. N users signing up means N deposit contracts.
I am able to monitor the events from 1 contract using the following code:
contract_address = '' contract here
contract_abi = json.loads('ABI HERE')
contract = web3.eth.contract(address=contract_address, abi=contract_abi)
def handle_event(event):
print(web3.eth.get_block('latest')['number'])
temp = json.loads(Web3.toJSON(event))
print(temp)
async def log_loop(event_filter, poll_interval):
while True:
for PairCreated in event_filter.get_new_entries():
print("I'm here")
handle_event(PairCreated)
await asyncio.sleep(poll_interval)
def main():
event_filter = contract.events.EVENT.createFilter(fromBlock='latest')
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(
asyncio.gather(
log_loop(event_filter, 2)))
finally:
loop.close()
if __name__ == "__main__":
main()
However, this just monitors ONE contract, I want it to be able to monitor multiple contracts (the same event but emitted from multiple contracts)
Is there anything I can do to achieve this (apart from spawning another listener process for each new contract, that I'm sure will consume memory very quickly on any box we run this on) and simply wont scale.
Best Answer
So instead of monitoring all events from all contracts, what I did instead is created a new contract:
I then interface this contract in each individual contract and effectively all the contracts invoke this contract which sends out one event. I then just need to monitor one contract's events not all contracts.
While typing this, I've noticed that there was a glaring security problem whereby anyone could invoke reporter() and issue an Event (which I subsequently relied upon to mint a coin offchain).
I then upgraded the contract to create an array of admin addresses (each contract that will be subsequently monitored) which only they have the power to invoke reporter() and issue the Event.