You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Web3.js@1.7.5如何检测交易Pending状态?求加速交易可靠方案

可靠检测Pending交易并实现加速交易的方案

核心思路

加速交易的本质是替换同nonce、更高gasPrice的交易,前提是精准判断原交易是否处于Pending状态。以下是经过验证的可行方法:

1. 直接查询交易哈希的状态(最可靠)

通过web3.eth.getTransaction(txHash)直接获取交易详情,根据blockNumber字段判断状态:

  • blockNumber === null:交易处于Pending状态(已进入节点内存池,未上链)
  • blockNumber !== null:交易已上链,可进一步通过交易收据确认是否成功

代码示例:

async function checkTransactionStatus(txHash) {
  try {
    const tx = await web3.eth.getTransaction(txHash);
    if (!tx) return 'unknown'; // 交易暂未被节点接收

    if (tx.blockNumber === null) {
      return 'pending';
    } else {
      // 验证上链后的交易结果
      const receipt = await web3.eth.getTransactionReceipt(txHash);
      return receipt.status ? 'success' : 'failed';
    }
  } catch (err) {
    console.error('查询交易状态失败:', err);
    return 'error';
  }
}

这个方法不依赖节点内存池的同步状态,只要交易被任何节点接收,就能精准判断Pending状态,是最稳定的方案。

2. 正确使用Web3.js的Pending交易过滤器

之前的过滤器用法可能有误,正确的Pending交易监听方式如下:

// 创建Pending交易过滤器
const pendingFilter = web3.eth.filter('pending');

// 监听新进入内存池的交易
pendingFilter.watch((error, txHash) => {
  if (!error) {
    // 判断是否是目标交易
    if (txHash === yourTargetTxHash) {
      console.log('目标交易进入Pending状态');
      // 这里可以触发加速逻辑
    }
  }
});

// 停止监听(记得在组件卸载时调用)
// pendingFilter.stopWatching();

注意:该方法要求连接的节点支持内存池访问,部分免费公共节点(如Infura免费版)会限制此功能,建议使用付费节点或自行部署的以太坊节点。

3. 直接调用节点的txpool_content RPC方法

如果使用的节点开启了内存池API,可以通过txpool_content直接查询内存池中的所有交易:

async function isTxInPendingPool(txHash) {
  try {
    const response = await web3.currentProvider.send({
      jsonrpc: '2.0',
      method: 'txpool_content',
      params: [],
      id: Math.floor(Math.random() * 1000)
    });

    // 遍历Pending队列查找目标交易
    const pendingTxs = response.result.pending;
    for (const account in pendingTxs) {
      for (const nonce in pendingTxs[account]) {
        const tx = pendingTxs[account][nonce];
        if (tx.hash === txHash) {
          return true;
        }
      }
    }
    return false;
  } catch (err) {
    console.error('查询内存池失败:', err);
    return false;
  }
}

此方法适合自行部署的节点,公共节点大概率不支持该RPC调用。

4. 加速交易的实现逻辑

确认交易处于Pending状态后,通过相同nonce、更高gasPrice重新发送交易即可实现加速:

async function accelerateTx(originalTxHash, newGasPriceGwei) {
  const originalTx = await web3.eth.getTransaction(originalTxHash);
  if (!originalTx || originalTx.blockNumber !== null) {
    throw new Error('交易不处于Pending状态,无法加速');
  }

  // 构建新交易:nonce必须与原交易一致,gasPrice需高于原交易(建议高10%-20%)
  const newTxParams = {
    from: originalTx.from,
    to: originalTx.to,
    value: originalTx.value,
    data: originalTx.input, // 原交易的调用数据
    nonce: originalTx.nonce,
    gasPrice: web3.utils.toWei(newGasPriceGwei.toString(), 'gwei'),
    gasLimit: originalTx.gas // 可保持原gasLimit或适当提高
  };

  // 通过MetaMask签名并发送交易
  const acceleratedTxHash = await web3.eth.sendTransaction(newTxParams);
  return acceleratedTxHash;
}

常见问题说明

  • 之前getBlock('pending')不可靠的原因:不同节点的内存池交易列表不一致,MetaMask发送的交易可能未同步到你连接的节点,导致无法在pending区块中查到。
  • 交易收据的status字段:true表示交易成功,false表示失败,仅当交易上链后才会返回,无法判断Pending状态。

内容的提问来源于stack exchange,提问作者mynameisConan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 07:09:19