Events

如何收集任何合約發出的歷史事件

  • January 20, 2022

我試圖收集整個鏈上特定類型的所有事件,無論是什麼合約發出的。

在嘗試線上查找解決方案時,我遇到瞭如下程式碼(source):

const filterId = await provider.send('eth_newFilter', [{
 address: ['0x123..', '0x456...'],
 fromBlock, toBlock, topics
}])

const logs = await provider.send('eth_getFilterChanges', [filterId]);

在這裡,可以聲明多個合約地址。然而,這不是我想要的,因為我不知道發出我試圖收集的事件的合約的地址。

我正在尋找以下程式碼的一個版本,它給我歷史事件,而不是剛剛出現的事件:

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);
});

請注意,設置addressnull意味著合約的地址不是標準,即我接受事件而不管發出它的合約的地址。

我更喜歡使用 ethers.js 的解決方案,但使用顯式 RPC 呼叫的低級解決方案或使用不同庫的解決方案也可以。


編輯:我嘗試將上面的兩個程式碼塊組合如下:

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);

但是,這總是產生空數組。


編輯2:

以下程式碼基於答案:

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);

但是,response0response1都是空數組。只response2包含一個事件。我使用了一個最近部署的合約,它只發出了 1 個指定類型的事件。從過濾器的輸出中,我可以看到filter12確實限制在正確的地址,所以我不明白為什麼甚至response1是空的。

您是否嘗試使用eth_getLogs. 這也通過 Ethers 提供程序公開:https ://docs.ethers.io/v5/api/providers/provider/#Provider-getLogs 。

參數的語法與 for 相同eth_newFilter

引用自:https://ethereum.stackexchange.com/questions/118517