過濾事件總是返回主題
我的契約中有一個事件:
event CreatedUnfinishedRandomSVG(uint256 indexed tokenId, address nftOwner, uint256[] randomWords);
在我的 JS 腳本中,我僅在發出與此 tokenId 匹配的事件時才嘗試執行一些程式碼。這就是我過濾此事件的方式(安全帽、乙太幣、合約稱為 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);
以上,
tokenId
取自交易收據中的一個事件。this 的值始終為 1,並且我已經檢查過合約中再也沒有tokenId
’ 了(例如 2、3、4 等,創建 的程式碼tokenId
只被呼叫一次)。當我執行它並列印
events
時,我得到以下輸出:
{"address":"0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9","topics":["0x26cb4155602d63931f31f118192ad576866bf5df054834c85516a4273134bd1e","0x0000000000000000000000000000000000000000000000000000000000000001"]}
據我了解,
topics
數組中的第一個元素是事件簽名的雜湊(https://docs.ethers.io/v5/concepts/events/#events-solidity)。以下元素是索引參數,所以在這種情況下,它tokenId
等於 1。0x0000000000000000000000000000000000000000000000000000000000000001
等於 1,所以這是有道理的。但是,如果我在我的 JS 腳本中執行它:
const events = randomSvg.filters.CreatedUnfinishedRandomSVG(9999);
我明白了:
{"address":"0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9","topics":["0x26cb4155602d63931f31f118192ad576866bf5df054834c85516a4273134bd1e","0x000000000000000000000000000000000000000000000000000000000000270f"]}
如果我們將主題 (
0x000000000000000000000000000000000000000000000000000000000000270f
) 的第一個元素轉換為十進制數,我們得到 9999。這對我來說毫無意義……我的 JS 程式碼聲明我想過濾等於 9999
CreatedUnfinishedRandomSVG
的事件。tokenId
由於沒有等於 9999的事件CreatedUnfinishedRandomSVG
,所以tokenId
這肯定應該返回 null 嗎?這使得無法確定是否存在具有特定索引值的事件,因為無論
tokenId
您傳遞什麼進行過濾,您總是會得到結果???這是什麼原因?為什麼會這樣?我如何確定是否已發出具有特定值的事件?
附加資訊:
如果我執行:
const events = randomSvg.filters.CreatedUnfinishedRandomSVG();
我得到:
{"address":"0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9","topics":["0x26cb4155602d63931f31f118192ad576866bf5df054834c85516a4273134bd1e"]}
這只是主題雜湊…
有了這個:
// Filter for event const events = randomSvg.filters.CreatedUnfinishedRandomSVG(tokenId);
您還沒有過濾事件,而只是製作過濾器(這是您看到的對象)。
要過濾來自區塊鏈的實際實時事件:
const filter = randomSvg.filters.CreatedUnfinishedRandomSVG(tokenId); provider.on(filter, (log, event) => { console.log(log) // ... })
而是顯示收據中的事件:
const tx = ... // our transaction const receipt = await tx.wait(); for (let i=0; i<receipt.logs.length; i++) { if (receipt.logs[i].address == filter.address) { if (receipt.logs[i].topics[0] == filter.topics[0]) { console.log(receipt.logs[i]) } } }
我不認為有過濾這些的方法,但沒有什麼是你不能通過嵌套一些
if
s 來做的!