Ethers.js监听BSC链Swap事件无数据返回问题排查
BSC链Swap事件监听器无数据返回问题排查
核心问题分析
你的代码逻辑本身没有语法错误,但存在两个关键问题导致无法收到事件:
- 进程自动退出:Node.js脚本执行完
main()函数后会立刻终止进程,不会保持后台监听状态,自然无法接收后续触发的Swap事件。 - HTTP节点的局限性:你使用的BSC HTTP节点(
bsc-dataseed1.binance.org)对实时事件推送的支持有限,部分公共节点存在速率限制或延迟,甚至不支持事件订阅功能。
修复方案
1. 替换为WebSocket节点
WebSocket协议更适合实时事件订阅,稳定性和实时性远优于HTTP节点。
2. 保持进程运行
添加逻辑阻止脚本自动退出,直到用户主动终止。
3. 增强调试与错误处理
添加事件参数格式化输出、连接错误监听,便于排查问题。
修复后的完整代码
const { ethers } = require("ethers"); // 使用BSC WebSocket节点,适配实时事件订阅 const provider = new ethers.providers.WebSocketProvider('wss://bsc-ws-node.nariox.org:443'); const address = '0x16b9a82891338f9bA80E2D6970FddA79D1eb0daE'; // BNB/USDT Pair地址 const pairABI = [ "function name() view returns (string)", "event Swap(address indexed sender, uint256 amount0In, uint256 amount1In, uint256 amount0Out, uint256 amount1Out, address indexed to)" ]; const contract = new ethers.Contract(address, pairABI, provider); const main = async () => { const name = await contract.name(); console.log(`\nListening for swap events for ${name}\n`); // 监听Swap事件,输出格式化后的交易数据 contract.on("Swap", (sender, amount0In, amount1In, amount0Out, amount1Out, to, event) => { console.log(`=== New Swap Detected ===`); console.log(`Sender: ${sender}`); // 注意:BNB是18位精度,USDT是6位精度,需对应Pair的token调整 console.log(`BNB In: ${ethers.utils.formatUnits(amount0In, 18)}`); console.log(`USDT In: ${ethers.utils.formatUnits(amount1In, 6)}`); console.log(`BNB Out: ${ethers.utils.formatUnits(amount0Out, 18)}`); console.log(`USDT Out: ${ethers.utils.formatUnits(amount1Out, 6)}`); console.log(`Recipient: ${to}`); console.log(`Tx Hash: ${event.transactionHash}\n`); }); // 监听节点连接错误 provider.on("error", (error) => { console.error("Node connection error:", error); }); // 监听节点断开,可添加重连逻辑 provider.on("close", () => { console.log("Node disconnected, attempting to reconnect..."); // 此处可补充重连代码 }); // 可选:查询最近100个区块的历史Swap事件,验证ABI和地址正确性 const pastEvents = await contract.queryFilter("Swap", -100); console.log(`Found ${pastEvents.length} historical swap events in recent blocks\n`); }; main(); // 保持进程运行,直到用户按下Ctrl+C终止 process.stdin.resume(); process.on('SIGINT', () => { console.log("\nStopping swap listener..."); provider.destroy(); process.exit(0); });
额外验证步骤
如果修复后仍无数据,可先执行历史事件查询代码(已包含在上述脚本中):
- 若能查到历史Swap事件,说明ABI和合约地址正确,问题出在实时推送节点;
- 若查不到历史事件,需检查合约地址是否对应目标Pair,或ABI是否准确。
内容的提问来源于stack exchange,提问作者thebridgesengineer
相关产品推荐
相关产品推荐

