ethers.js-7-事件的检索,监听,过滤

🔎 1️⃣ 事件检索(查询历史事件)

用 contract.queryFilter 可以查询链上已经发生的事件。

基本用法

const filter = contract.filters.Transfer(from, to); // ERC20 Transfer 事件示例

const events = await contract.queryFilter(filter, fromBlock, toBlock);

for (const event of events) {

console.log(event.args);

}

复制代码
•	contract.filters.MyEvent(arg1, arg2, ...) 会创建一个过滤器。
•	fromBlock、toBlock 是区块高度,比如:

await contract.queryFilter(filter, 10000000, 'latest')

如果你只想查某个具体事件,可以用参数限制:

const filter = contract.filters.Transfer("0xSenderAddress", null); // 只过滤 from 地址

👂 2️⃣ 事件监听(实时监听新区块)

用 contract.on 或 contract.once。

持续监听

contract.on("Transfer", (from, to, value, event) => {

console.log(Transfer from ${from} to ${to} of ${value.toString()});

console.log("Full event:", event);

});

监听一次

contract.once("Transfer", (from, to, value, event) => {

console.log(Got one Transfer: ${from} -> ${to});

});

🔍 3️⃣ 事件过滤器

你可以直接用过滤器监听:

const filter = contract.filters.Transfer(null, "0xRecipientAddress");

contract.on(filter, (from, to, value, event) => {

console.log(Filtered Transfer: ${from} -> ${to} (${value.toString()}));

});

这样只会触发满足 to == 0xRecipientAddress 的 Transfer 事件。

🛠️ 4️⃣ 监听取消

如果要取消监听:

contract.off("Transfer", callback);

// 或

contract.removeAllListeners("Transfer");

如果你用了 filter,需要用同一个 filter 对象来取消:

contract.off(filter, callback);

🚀 小结

功能 方法

查询历史事件 contract.queryFilter

创建事件过滤器 contract.filters.XXX

实时监听事件 contract.on

只监听一次事件 contract.once

停止监听事件 contract.off / removeAllListeners

✍️ 小示例:完整监听与查询

import { ethers } from "ethers";

const provider = new ethers.providers.JsonRpcProvider("https://rpc-url");

const contract = new ethers.Contract(contractAddress, abi, provider);

// 查询历史 Transfer 事件

const filter = contract.filters.Transfer(null, "0xRecipientAddress");

const events = await contract.queryFilter(filter, 10000000, 'latest');

for (let e of events) {

console.log("Past event:", e.args);

}

// 监听未来 Transfer 事件

contract.on(filter, (from, to, value, event) => {

console.log(Realtime Transfer: ${from} -> ${to} (${value.toString()}));

});

const provider = new ethers.providers.JsonRpcProvider("https://rpc-url");

我们逐步拆开详细解释一下。

📌 1️⃣ ethers.providers

在 ethers.js 里,ethers.providers 是用来和区块链节点(比如以太坊节点)通信的模块。

provider 就像是你的"区块链网关":

• 读取链上的信息(余额、交易、区块、事件)

• 发送只读请求(比如 call)

• 监听新区块、事件

• 不负责签名(签名是由 Wallet 做的)

📌 2️⃣ JsonRpcProvider

ethers.providers.JsonRpcProvider 是最常用的 provider,直接通过 HTTP JSON-RPC 协议连接以太坊节点。

它可以连接:

• Infura / Alchemy 等公链服务商提供的 RPC

• 你自己搭建的 geth / besu / ganache 节点

• 或者 Hardhat / Foundry 的本地节点(比如 http://127.0.0.1:8545

它内部就会自动帮你发送类似:

{

"jsonrpc": "2.0",

"method": "eth_blockNumber",

"params": [],

"id": 1

}

这种 JSON-RPC 请求,拿到链上数据。

📌 3️⃣ "https://rpc-url"

这是你指定的 RPC URL,例如:

• 主网 Infura:

new ethers.providers.JsonRpcProvider("https://mainnet.infura.io/v3/your_project_id")

复制代码
•	Sepolia 测试网:

new ethers.providers.JsonRpcProvider("https://sepolia.infura.io/v3/your_project_id")

复制代码
•	Hardhat 本地:

new ethers.providers.JsonRpcProvider("http://127.0.0.1:8545")

🔍 总结一句

const provider = new ethers.providers.JsonRpcProvider("https://rpc-url");

就是:

创建一个 provider 对象,让你可以通过 HTTP 请求这个 RPC 节点,读取链上的区块、交易、合约数据,监听事件等。

它只是一个「只读」入口,不带私钥,也不能签名交易。

如果要发起转账或执行合约写操作,要用 new ethers.Wallet(privateKey, provider) 来组合 signer。

✅ 要不要我再帮你写一个 provider + wallet 的示例,让你可以用私钥发交易?

需要的话说一声就写。 🚀

相关推荐
超级大只老咪6 小时前
快速进制转换
笔记·算法
Fᴏʀ ʏ꯭ᴏ꯭ᴜ꯭.8 小时前
Keepalived VIP迁移邮件告警配置指南
运维·服务器·笔记
ling___xi9 小时前
《计算机网络》计网3小时期末速成课各版本教程都可用谢稀仁湖科大版都可用_哔哩哔哩_bilibili(笔记)
网络·笔记·计算机网络
中屹指纹浏览器10 小时前
中屹指纹浏览器底层架构深度解析——基于虚拟化的全维度指纹仿真与环境隔离实现
经验分享·笔记
Hello_Embed10 小时前
libmodbus 移植 STM32(基础篇)
笔记·stm32·单片机·学习·modbus
无聊的小坏坏11 小时前
实习笔记:用 /etc/crontab 实现定期数据/日志清理
笔记·实习日记
香芋Yu11 小时前
【机器学习教程】第04章 指数族分布
人工智能·笔记·机器学习
深蓝海拓13 小时前
PySide6从0开始学习的笔记(二十六) 重写Qt窗口对象的事件(QEvent)处理方法
笔记·python·qt·学习·pyqt
中屹指纹浏览器13 小时前
中屹指纹浏览器多场景技术适配与接口封装实践
经验分享·笔记
BugShare14 小时前
Obsidian 使用指南:从零开始搭建你的个人知识库
笔记·obsidian