You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 11:20:28