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

如何在循环中运行async异步函数 解决web3批量mintNFT报错问题

错误原因

你遇到的replacement transaction underpriced错误核心是循环并行触发交易导致nonce重复:

  • 你写的同步循环会同时执行所有mintNFT函数,几乎同一时间调用web3.eth.getTransactionCount拿到的都是同一个最新nonce,导致多笔交易用了相同nonce提交
  • 链上节点收到相同nonce的多笔交易时,会判定为你要替换已进入内存池的同nonce交易,要求后提交的交易gas价格比之前的至少高10%,你这里gas参数写死没有提价,所以直接抛出错误。

解决方案

方案1:异步串行执行(简单稳妥,适合中小批量)

改造mintNFT返回Promise,循环中等待上一笔交易提交完成再发下一笔,自己维护nonce避免重复查链:

// 改造后的mintNFT,支持传入预计算的nonce,返回Promise
async function mintNFT(tokenURI, nonce) {
  const tx = {
    from: PUBLIC_KEY,
    to: contractAddress,
    nonce: nonce,
    gas: 500000,
    data: nftContract.methods.mintNFT(PUBLIC_KEY, tokenURI).encodeABI(),
  };
  const signedTx = await web3.eth.accounts.signTransaction(tx, PRIVATE_KEY);
  return new Promise((resolve, reject) => {
    web3.eth.sendSignedTransaction(signedTx.rawTransaction, (err, hash) => {
      if (err) {
        console.log(`交易提交失败,tokenURI:${tokenURI},错误信息:`, err);
        reject(err);
      } else {
        console.log(`交易提交成功,哈希:${hash},tokenURI:${tokenURI}`);
        resolve(hash);
      }
    })
  })
}

// 批量串行mint逻辑
async function batchMint(total) {
  // 仅查一次初始nonce
  let currentNonce = await web3.eth.getTransactionCount(PUBLIC_KEY, "latest");
  for (let i = 0; i < total; i++) {
    try {
      await mintNFT(`https://ipfs.io/ipfs/cid/${i}`, currentNonce);
      currentNonce++;
      // 可加短延迟避免节点限流,不需要可以删掉
      await new Promise(resolve => setTimeout(resolve, 50));
    } catch (e) {
      // 交易失败后重试当前笔,重新同步nonce避免错乱
      console.log(`第${i}笔mint失败,正在重试`);
      i--;
      currentNonce = await web3.eth.getTransactionCount(PUBLIC_KEY, "pending");
    }
  }
  console.log("所有交易提交完成");
}

// 调用批量方法,传入要mint的总数
batchMint(10000);

方案2:预计算nonce并行执行(效率更高,适合大批量)

如果觉得串行速度慢,可以提前一次性分配所有交易的nonce,再并行提交:

async function batchMintParallel(total) {
  const startNonce = await web3.eth.getTransactionCount(PUBLIC_KEY, "latest");
  const mintTasks = [];
  for (let i = 0; i < total; i++) {
    mintTasks.push(mintNFT(`https://ipfs.io/ipfs/cid/${i}`, startNonce + i));
  }
  // 等待所有交易完成,不管成功失败都会返回结果
  await Promise.allSettled(mintTasks);
  console.log("所有批次交易处理完成");
}

注意事项

  • 大批量mint建议不要写死gas参数,可通过web3.eth.getGasPrice()动态获取当前链上gas价格,避免拥堵时交易失败
  • 如果遇到nonce持续错乱的情况,可调用web3.eth.getTransactionCount(PUBLIC_KEY, "pending")获取包含内存池交易的最新nonce重新同步

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 19:45:02