I have an event in my contract:
event CreatedUnfinishedRandomSVG(uint256 indexed tokenId, address nftOwner, uint256[] randomWords);
In my JS script, I am trying to run some code only if the event that matches this tokenId has been emitted. This is how I am filtering for this event (hardhat, ethers, contract is called RandomSvg):
// Get contract object so we can get address
let randomSVGObject = await get("RandomSVG");
let randomSvgAddress = randomSVGObject.address;
// Get the RandomSVG contract factory
const randomSvgFactory = await ethers.getContractFactory("RandomSVG");
const randomSvgInterface = randomSvgFactory.interface;
// Get signer
const accounts = await hre.ethers.getSigners();
const signer = accounts[0];
// Create a new randomSVG Contract instance
const randomSvg = new ethers.Contract(
randomSvgAddress,
randomSvgInterface,
signer
);
.... call function on RandomSvg that emits the below event....
// Filter for event
const events = randomSvg.filters.CreatedUnfinishedRandomSVG(tokenId);
Above, tokenId
is taken from an event in the transaction receipt. The value of this is always 1, and I have checked that there are never any more tokenId
's in the contract (eg 2, 3, 4 etc, the code that creates the tokenId
is only called once).
When I run this and print events
, I get the following output:
{"address":"0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9","topics":["0x26cb4155602d63931f31f118192ad576866bf5df054834c85516a4273134bd1e","0x0000000000000000000000000000000000000000000000000000000000000001"]}
From my understanding, the first element in topics
array is the hash of the event signature (https://docs.ethers.io/v5/concepts/events/#events-solidity). The following elements are the indexed parameters, so in this case, it is the tokenId
which is equal to 1. 0x0000000000000000000000000000000000000000000000000000000000000001
is equal to 1, so this makes sense.
However, if I run this in my JS script:
const events = randomSvg.filters.CreatedUnfinishedRandomSVG(9999);
I get this:
{"address":"0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9","topics":["0x26cb4155602d63931f31f118192ad576866bf5df054834c85516a4273134bd1e","0x000000000000000000000000000000000000000000000000000000000000270f"]}
If we convert the first element of topics (0x000000000000000000000000000000000000000000000000000000000000270f
) to decimal number, we get 9999. This makes no sense to me…
My JS code stated that I wanted to filter CreatedUnfinishedRandomSVG
events where the tokenId
is equal to 9999. Since there are no CreatedUnfinishedRandomSVG
where tokenId
is equal to 9999, surely this should return null?
This makes it impossible to determine if an event with a specific indexed value exists, because no matter what tokenId
you pass in to filter on, you always get a result???
What is the reasoning for this and why is this happening?
How would I determine if an event with a specific value has been emitted?
Additional info:
If I run:
const events = randomSvg.filters.CreatedUnfinishedRandomSVG();
I get:
{"address":"0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9","topics":["0x26cb4155602d63931f31f118192ad576866bf5df054834c85516a4273134bd1e"]}
Which is only the topic hash…
Best Answer
With this:
you aren't yet filtering events, but only making the filter (which is the object you've seen).
To filter for actual live events from the blockchain:
Instead to show the events from a receipt:
I don't think there's a method to filter these, but nothing you can't do by nesting some
if
s!