Web3如何获取指定智能合约近24小时的历史交易记录
合约近24小时历史交易查询实现方案
该需求完全可以实现,以下是两种基于Web3.js的常用实现方案:
方案1:高效查询(基于eth_getLogs接口)
适合查询合约触发过事件的交易,查询效率远高于逐块遍历,对节点压力小:
// 1. 获取当前最新区块,计算24小时对应的起始区块高度 const latestBlock = await this.web3.eth.getBlock("latest"); const latestBlockNum = Number(latestBlock.number); // 以太坊平均出块时间约12s,24h对应区块数约7200,其他EVM链可根据实际出块速度调整 const BLOCKS_PER_DAY = 7200; const fromBlock = latestBlockNum - BLOCKS_PER_DAY > 0 ? latestBlockNum - BLOCKS_PER_DAY : 0; // 2. 直接过滤目标合约的所有事件日志 const logs = await this.web3.eth.getLogs({ address: "替换为你的合约地址", fromBlock: fromBlock, toBlock: latestBlockNum }); // 3. 从日志提取交易哈希,去重后查询完整交易信息 const txHashes = [...new Set(logs.map(log => log.transactionHash))]; const targetTxList = await Promise.all(txHashes.map(hash => this.web3.eth.getTransaction(hash)));
方案2:全量交易遍历(逐块拉取)
可以拿到所有to地址为目标合约的交易,包括未触发任何事件的转账等交易,兼容性最好:
const latestBlock = await this.web3.eth.getBlock("latest"); const latestBlockNum = Number(latestBlock.number); const BLOCKS_PER_DAY = 7200; const fromBlock = latestBlockNum - BLOCKS_PER_DAY > 0 ? latestBlockNum - BLOCKS_PER_DAY : 0; const targetTxList = []; const contractAddr = "替换为你的合约地址".toLowerCase(); // 分批查询避免触发节点限流,每次拉取100个区块 for (let i = fromBlock; i <= latestBlockNum; i += 100) { const batchEnd = Math.min(i + 99, latestBlockNum); const blockPromises = []; for (let j = i; j <= batchEnd; j++) { // getBlock第二个参数传true可直接返回区块内的完整交易列表 blockPromises.push(this.web3.eth.getBlock(j, true)); } const blocks = await Promise.all(blockPromises); blocks.forEach(block => { // 匹配交易接收方为目标合约的交易,统一转小写避免大小写匹配失败 const matchedTxs = block.transactions.filter(tx => tx.to?.toLowerCase() === contractAddr); targetTxList.push(...matchedTxs); }); // 可按需添加延迟,避免请求频率过高被节点拒绝 await new Promise(resolve => setTimeout(resolve, 100)); }
注意事项
- 如果你使用的是BSC、Polygon等其他EVM兼容链,需要根据对应链的平均出块时间调整
BLOCKS_PER_DAY的数值 - 部分公共节点对
eth_getLogs的单次返回数量有上限,遇到报错时可以把查询区块区间拆得更小,分批查询 - 如果需要获取合约触发的内部转账交易,原生Web3接口无法直接获取,需要节点支持trace类扩展API才能查询
内容的提问来源于stack exchange,提问作者Sowam
相关产品推荐
相关产品推荐

