ethers.js监听事件fromBlock参数失效问题求助
Ethers.js监听Transfer事件指定起始区块不生效的解决办法
问题原因
你使用WebSocketProvider.on()方法监听日志时,这个API本质是订阅实时新增的区块日志,配置的fromBlock参数只会过滤订阅后收到的日志所属区块,不会主动回溯查询fromBlock到当前区块的历史日志。所以你会看到只从最新区块开始输出日志。
解决方案
要同时获取历史区块的Transfer日志和监听实时新增日志,需要分两步操作:
- 第一步:主动调用
provider.getLogs()拉取指定区块范围的历史日志 - 第二步:订阅实时新增的日志,此时可以将
fromBlock设为"latest",确保只接收新产生的日志
修改后的代码
const { ethers } = require("ethers"); async function main() { const provider = new ethers.providers.WebSocketProvider("wss:xxxxx"); const targetBlock = 12989984; // 1. 拉取历史区块范围内的Transfer日志 const historyFilter = { fromBlock: targetBlock, toBlock: "latest", topics: [ethers.utils.id("Transfer(address,address,uint256)")] }; try { const historyLogs = await provider.getLogs(historyFilter); console.log("历史区块Transfer日志:"); historyLogs.forEach(log => console.log(log)); } catch (err) { console.error("拉取历史日志失败:", err); } // 2. 订阅实时新增的Transfer日志 const realtimeFilter = { fromBlock: "latest", topics: [ethers.utils.id("Transfer(address,address,uint256)")] }; provider.on(realtimeFilter, (log, event) => { console.log("实时新增Transfer日志:"); console.log(log); }); } main();
额外说明
- 如果你的节点不支持大范围历史日志查询(比如部分免费节点限制区块范围),可以分段循环调用
getLogs,每次查询固定区块数量(比如1000块),直到覆盖到目标起始区块。 - 注意WebSocket连接的稳定性,若断开重连后需要重新处理历史日志的补拉逻辑。
内容的提问来源于stack exchange,提问作者Mr.c
相关产品推荐
相关产品推荐

