I am trying to gather all events of a specific type on the entire chain, regardless of what contract emitted them.
When trying to find solutions online, I came across code like the following (source):
const filterId = await provider.send('eth_newFilter', [{
address: ['0x123..', '0x456...'],
fromBlock, toBlock, topics
}])
const logs = await provider.send('eth_getFilterChanges', [filterId]);
Here, multiple contract addresses can be stated. This, however, is not what I am looking for as I do not know the addresses of the contracts that emitted the events I am trying to gather.
I am looking for a version of the following code that gives me historical events, not events that are just coming in:
const provider = new ethers.providers.Web3Provider(window.ethereum);
const filter = {
address: null,
topics: [
ethers.utils.id('MyEvent(address)')
]
};
provider.on(filter, event => {
console.log(event);
});
Note that setting address
to null
means that the contract's address is not a criterion, i.e. I am accepting events regardless of the address of the contract that emitted it.
I would prefer a solution using ethers.js but a low-level solution using an explicit RPC call or a solution using a different library would also be fine.
Edit: I have tried to combine the two code blocks above as follows:
const filter = {
address: null,
topics: [
ethers.utils.id('MyEvent(address)')
]
};
const filterId = await provider.send('eth_newFilter', [{
address: null,
fromBlock: '0x11',
toBlock: '0x9819f0',
topics: filter.topics,
}]);
const logs = await provider.send('eth_getFilterChanges', [filterId]);
console.log(logs);
However, this always yields the empty array.
Edit 2:
The following code is based on an answer:
const filter0 = {
address: null,
topics: [
ethers.utils.id('MyEvent(address)')
]
};
const filter12 = myContract.filters.MyEvent();
const response0 = await provider.getLogs(filter0);
const response1 = await provider.getLogs(filter12);
const response2 = await myContract.queryFilter(filter12);
console.log('response0', response0);
console.log('response1', response1);
console.log('response2', response2);
console.log(filter12);
However, response0
and response1
are the empty array. Only response2
contains an event. I used a contract that was recently deployed and that only ever emitted 1 event of the specified kind. From the output of the filter, I can see that filter12
is indeed restricted to the correct address, so I do not understand why even response1
was empty.