如何用ethers.js追踪特定钱包的所有Mint事件及交易?
用ethers.js追踪特定钱包的所有Mint事件及交易事件查询
一、追踪所有名称为Mint的事件(无论参数差异)
以太坊的事件签名是「事件名+参数类型列表」的Keccak256哈希,不同参数的Mint事件会生成不同的签名哈希,因此无法通过单个过滤器直接匹配所有Mint事件。以下是两种可行方案:
方案1:枚举常见Mint事件签名,创建多过滤器
如果能覆盖大部分常见的Mint事件参数组合,可以将这些签名的哈希列出来,同时监听多个过滤器:
// 枚举常见的Mint事件签名 const mintSignatures = [ "Mint(address,uint256)", "Mint(uint256,address)", "Mint(address,uint256,uint256)", "Mint(address,address,uint256)", // 可根据需求添加更多常见签名 ]; // 生成对应的事件哈希数组 const mintEventHashes = mintSignatures.map(sig => ethers.utils.id(sig)); // 为每个哈希创建过滤器并监听 mintEventHashes.forEach(hash => { const filter = { topics: [hash, null, ethers.utils.hexZeroPad(targetAddress, 32)] }; provider.on(filter, (log, event) => { console.log("捕获到Mint事件:", event); // 处理事件逻辑 }); });
方案2:监听所有日志,事后解析事件名
如果无法枚举所有可能的Mint签名,可以监听链上所有日志,逐一解析事件名并检查是否涉及目标钱包:
provider.on("logs", async (logs) => { for (const log of logs) { // 先检查日志是否涉及目标钱包 const targetAddrPadded = ethers.utils.hexZeroPad(targetAddress, 32); const involvesTarget = log.topics.includes(targetAddrPadded) || (log.data && log.data.includes(targetAddrPadded.slice(2))); if (!involvesTarget) continue; try { // 获取合约ABI(可从本地缓存、合约发布平台等渠道获取) const contract = new ethers.Contract(log.address, contractABI, provider); // 解析日志为事件对象 const event = contract.interface.parseLog(log); // 检查事件名是否为Mint if (event.name === "Mint") { console.log("捕获到Mint事件:", event); // 处理事件逻辑 } } catch (err) { // 无法解析的日志直接跳过 continue; } } });
注意:这种方式会监听所有链上日志,性能消耗较大,建议配合区块范围过滤或在私链/测试链上使用。
二、追踪特定钱包的所有交易并查询触发的事件
可通过查询历史交易或监听新交易两种方式实现:
方式1:查询钱包历史交易及对应事件
async function getWalletMintEvents(targetAddress) { // 获取钱包的交易历史 const transactions = await provider.getHistory(targetAddress); for (const tx of transactions) { // 获取交易收据(包含所有触发的日志) const receipt = await provider.getTransactionReceipt(tx.hash); if (!receipt || !receipt.logs) continue; // 遍历所有日志,解析并筛选Mint事件 for (const log of receipt.logs) { try { // 需提前获取对应合约的ABI const contract = new ethers.Contract(log.address, contractABI, provider); const event = contract.interface.parseLog(log); if (event.name === "Mint") { console.log(`交易 ${tx.hash} 触发Mint事件:`, event); } } catch (err) { continue; } } } } // 调用函数 getWalletMintEvents(targetAddress);
方式2:监听新块中的目标钱包交易
provider.on("block", async (blockNumber) => { // 获取当前块的所有交易 const block = await provider.getBlockWithTransactions(blockNumber); if (!block || !block.transactions) return; // 筛选出目标钱包发起的交易 const targetTransactions = block.transactions.filter(tx => tx.from.toLowerCase() === targetAddress.toLowerCase() ); for (const tx of targetTransactions) { // 等待交易确认,获取收据 const receipt = await provider.waitForTransaction(tx.hash); if (!receipt || !receipt.logs) continue; // 解析并筛选Mint事件 for (const log of receipt.logs) { try { const contract = new ethers.Contract(log.address, contractABI, provider); const event = contract.interface.parseLog(log); if (event.name === "Mint") { console.log(`新交易 ${tx.hash} 触发Mint事件:`, event); } } catch (err) { continue; } } } });
内容的提问来源于stack exchange,提问作者ethadvocate123
相关产品推荐
相关产品推荐

