I can see how I can get new events with contract.events.onvaluechanged. But I want to get all the events from a block number
On the provider, you can use resetEventsBlock ( blockNumber ) , which will rewind the provider to that the provided block and replay events from that block forward.
This is something that I plan to have a better API for in the future.
Currently many providers have fairly limited abilities and performance to look "far" in the past, and their reliability is not perfect. These are being addressed by the Geth team, which will likely be adopted by INFURA.
That was a quick response. I'll check it out. Thanks
Thanks @GFJHogue. getLogs on the provider looks good as I can filter to an address and specify from which block I want the logs from.
What I'm struggling with is how to convert solidity events to topics. How would I get all the Transfer events from an ERC 20 contract? eg
event Transfer(
address indexed fromAddress,
address indexed toAddress,
uint256 amount);
I can get the logs with the following code
const logs = await this.eventsProvider.getLogs({
fromBlock: fromBlock,
toBlock: "latest",
address: this.contract.address
});
From what I can tell the first item in the topics array is the hash of the event signature. Is there any utility in Ethers.js to get this hash?
Here is how you get the topics for the Transfer event in your contract:
var Transfer = this.contract.interface.events.Transfer();
this.eventsProvider.getLogs({
fromBlock: fromBlock,
toBlock: "latest",
address: this.contract.address,
topics: Transfer.topics
}) // ...
See the Events example here: https://docs.ethers.io/ethers.js/html/api-advanced.html#id3
Thanks @GFJHogue. I can now get a list of logs with
const TransferEvent = this.contract.interface.events.Transfer();
const logs = await this.transactionProvider.getLogs({
fromBlock: fromBlock,
toBlock: "latest",
address: this.contract.address,
topics: TransferEvent.topics
});
I then need to iterate over the logs and extract the data. Is there anything to help with converting data in the topics of each log? web3.js has event.returnValues which makes it very easy to pull the data you want from the log.
No problem :)
You should be able to use TransferEvent.parse(data) to convert the data. It's also shown in the example I mentioned.
It looks like parse takes two parameters: topics and data.
Using the following code I could do what I needed to do
const IssueEvent = this.contract.interface.events.Issue();
const logs = await this.transactionProvider.getLogs({
fromBlock: fromBlock,
toBlock: "latest",
address: this.contract.address,
topics: IssueEvent.topics
});
for (const log of logs)
{
const logData = IssueEvent.parse(log.topics, log.data);
console.log(logData);
//do something with logData which includes the event arguments are properties. eg logData.fromAddress, logData.toAddress and logData.amount
}
Thanks for your help @GFJHogue
As of version 3.0.1, the first line in the previous comment needs to change to
const IssueEvent = this.contract.interface.events.Issue;
Hopefully this helps anyone new to the library who wants to get past events.
Most helpful comment
As of version 3.0.1, the first line in the previous comment needs to change to
Hopefully this helps anyone new to the library who wants to get past events.