如何解决Hedera测试网批量部署合约时的间歇性nonce重复错误?
并行部署智能合约到Hedera测试网时间歇性出现NONCE_EXPIRED错误
当同时向Hedera测试网部署2个智能合约时,会间歇性出现以下错误(概率约20%):
nonce has already been used [ See: https://links.ethers.org/v5-errors-NONCE_EXPIRED ]
错误出现无明确规律,目前无法确定触发的固定条件。
部署代码
我的部署代码如下:
const deploymentSigner: Signer = (await hre.ethers.getSigners())[0]; // console.log('Deployment signer address', (await deploymentSigner.getAddress())); const scDeploymentPromises: Promise<Contract>[] = []; for (let idx = 0; idx < scNamesToDeploy.length; ++idx) { const scName = scNamesToDeploy[idx]; const scFactory: ContractFactory = await hre.ethers.getContractFactory(scName); console.log(`Deploying ${scName} on ${networkName} ...`); const sc: Contract = await scFactory.deploy(); // NOTE deployment with constructor params not needed for these particular SCs const scDeploymentPromise: Promise<Contract> = sc.deployed(); scDeploymentPromises.push(scDeploymentPromise); } // NOTE collect deployment promises without `await`-ing them, // so as to be able to run them in parallel. const deployedScs: Contract[] = await Promise.all(scDeploymentPromises); deployedScs.forEach((sc, idx) => { const scName = scNamesToDeploy[idx]; console.log(`Deployed ${scName} on ${networkName} at ${sc.address}`); });
其中scNamesToDeploy是预初始化的字符串数组,包含需要部署的智能合约名称。
关键观察
如果修改循环内代码,改为:
await sc.deployed()
并移除后续的Promise.all并行逻辑,错误就不会出现。由此推测问题源于第二个部署交易在第一个提交后过快发起,但理论上应该支持并行提交交易,甚至在同一个“逻辑区块”内完成(Hedera实际无区块概念,此处为表述方便)。
详细信息
版本信息
使用的工具版本:
- hardhat:
hardhat@2.13.0 - ethers.js:
ethers@5.7.2(通过@nomicfoundation/hardhat-toolbox@2.0.2引入)
完整错误详情
nonce has already been used [ See: https://links.ethers.org/v5-errors-NONCE_EXPIRED ] (error={"name":"ProviderError","_stack":"ProviderError: [Request ID: 356c0cee-949f-4f52-b936-25bbba9ef603] Nonce too low at HttpProvider.request (/Users/user/code/hedera/hedera-scratch/chain/node_modules/hardhat/src/internal/core/providers/http.ts:88:21) at processTicksAndRejections (node:internal/process/task_queues:95:5) at async EthersProviderWrapper.send (/Users/user/code/hedera/hedera-scratch/chain/node_modules/@nomiclabs/hardhat-ethers/src/internal/ethers-provider-wrapper.ts:13:20)","code":32001,"_isProviderError":true}, method="sendTransaction", transaction=undefined, code=NONCE_EXPIRED, version=providers/5.7.2)
网络配置
hardhat.config.js中networks部分的配置如下:
hederatestnet: { chainId: 296, url: 'https://testnet.hashio.io/api', // gasPrice: Math.floor(rskTestnetMinimumGasPrice * 1.1), gasMultiplier: hederaTestnetGasMultiplier, accounts, }, hederatestnetrelay: { chainId: 296, url: 'http://localhost:7546', // gasPrice: Math.floor(rskTestnetMinimumGasPrice * 1.1), gasMultiplier: hederaTestnetGasMultiplier, accounts, },
注:实际使用的是hederatestnetrelay,即连接Hedera测试网的本地hedera-json-rpc-relay实例,因为它比直接连接公共RPC端点更稳定,直接连接会出现其他间歇性错误(“Unknown error invoking RPC”)。
内容的提问来源于stack exchange,提问作者bguiz
相关产品推荐
相关产品推荐

