监听Uniswap Router02的addLiquidity事件报错:contract.events.addLiquidity不是函数
问题:Web3.js监听Uniswap Router02的addLiquidity事件报错
contract.events.addLiquidity is not a function 我尝试监听Uniswap Router02合约的addLiquidity事件以抓取新增交易对数据,复制使用Web3.js代码时出现错误:contract.events.addLiquidity is not a function。已确认ABI中存在该事件、合约地址正确,且语法符合Web3.js文档规范,但仍遇到此问题。相关代码如下:
const Web3 = require('web3'); const NODE_URL = "https://mainnet.infura.io/v3/d3c5832256754c85be86b4c97de2d3d3" const web3 = new Web3(NODE_URL); const CONTRACT_ADDRESS = "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D"; const CONTRACT_ABI = require('./abi.json'); const contract = new web3.eth.Contract(CONTRACT_ABI, CONTRACT_ADDRESS); async function getEvents() { let latest_block = await web3.eth.getBlockNumber(); let historical_block = latest_block - 10000; //change the value to 'latest' if you have a upgraded rpc console.log("latest: ", latest_block, "historical block: ", historical_block); const events = await contract.events.addLiquidity( { fromBlock: historical_block, toBlock: 'latest' } ); await addLiquidity(events); }; async function getaddLiquidityDetails(data_events) { for (i = 0; i < data_events.length; i++) { let address_tokenA = data_events[i]['returnValues']['address tokenA']; let address_tokenB = data_events[i]['returnValues']['address tokenB']; console.log("address tokenA:",address_tokenA,"address tokenB:",address_tokenB); } }; getEvents(CONTRACT_ABI, CONTRACT_ADDRESS);
解决方案
1. Web3.js版本差异导致调用方式错误
Web3.js v1.x版本中,contract.events.addLiquidity()是事件监听方法,它返回的是EventEmitter实例而非事件数组,不能用await直接获取结果。正确的写法是通过on('data')回调处理事件:
async function getEvents() { let latest_block = await web3.eth.getBlockNumber(); let historical_block = latest_block - 10000; console.log("latest: ", latest_block, "historical block: ", historical_block); contract.events.addLiquidity( { fromBlock: historical_block, toBlock: 'latest' } ) .on('data', (event) => { // 处理单条事件数据 console.log("tokenA:", event.returnValues.tokenA, "tokenB:", event.returnValues.tokenB); }) .on('error', (err) => console.error("监听错误:", err)); };
2. 确认ABI中事件名称的准确性
检查你的abi.json里的事件名称是否为**addLiquidity**(注意大小写),Uniswap Router02的该事件标准定义如下,确保ABI中无拼写错误:
{ "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "sender", "type": "address" }, { "indexed": false, "internalType": "address", "name": "tokenA", "type": "address" }, { "indexed": false, "internalType": "address", "name": "tokenB", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "amountADesired", "type": "uint256" }, { "indexed": false, "internalType": "uint256", "name": "amountBDesired", "type": "uint256" }, { "indexed": false, "internalType": "uint256", "name": "amountAMin", "type": "uint256" }, { "indexed": false, "internalType": "uint256", "name": "amountBMin", "type": "uint256" }, { "indexed": true, "internalType": "address", "name": "to", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "deadline", "type": "uint256" } ], "name": "addLiquidity", "type": "event" }
3. 修复代码中的其他问题
- 原代码调用了未定义的
addLiquidity函数,应改为调用getaddLiquidityDetails - 访问
returnValues时,键名应为tokenA而非address tokenA(ABI中参数名是tokenA) - 循环变量
i未声明,需添加let避免全局变量污染
修复后的完整代码:
const Web3 = require('web3'); const NODE_URL = "https://mainnet.infura.io/v3/d3c5832256754c85be86b4c97de2d3d3" const web3 = new Web3(NODE_URL); const CONTRACT_ADDRESS = "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D"; const CONTRACT_ABI = require('./abi.json'); const contract = new web3.eth.Contract(CONTRACT_ABI, CONTRACT_ADDRESS); async function getEvents() { let latest_block = await web3.eth.getBlockNumber(); let historical_block = latest_block - 10000; console.log("latest: ", latest_block, "historical block: ", historical_block); contract.events.addLiquidity( { fromBlock: historical_block, toBlock: 'latest' } ) .on('data', (event) => { getaddLiquidityDetails([event]); }) .on('error', (err) => console.error(err)); }; async function getaddLiquidityDetails(data_events) { for (let i = 0; i < data_events.length; i++) { let address_tokenA = data_events[i].returnValues.tokenA; let address_tokenB = data_events[i].returnValues.tokenB; console.log("address tokenA:", address_tokenA, "address tokenB:", address_tokenB); } }; getEvents();
内容的提问来源于stack exchange,提问作者Ahmed ben salem
相关产品推荐
相关产品推荐

