Web3.js – Resolving UnhandledPromiseRejectionWarning: Nonce Too Low

contract-deploymentjavascriptnodejsropstenweb3js

I am trying to deploy some contracts on Ropsten network. Here is my code

async function finalDeploy(r){

  for(i=0; i<constructorParams.length; i++) {

    const options = {
      data: '0x' + myBin[r]+constructorParams[i],
      gas: 5000000,
  };
  const signed = await web3.eth.accounts.signTransaction(options, privateKey1);
  const receipt = await web3.eth.sendSignedTransaction(signed.rawTransaction); // here error occured 
  console.log("Contract: " +r+" is deployed at  " +receipt.contractAddress);
  contractAddressess.push(receipt.contractAddress)

  }

}

The above code is working perfectly on Ganache UI, but when i changed its provider from localhost to Web3.providers.HttpProvider("https://ropsten.infura.io/v3/7fb0bdc97cbe419..."); then i am receiving this error ;

UnhandledPromiseRejectionWarning: Error: Returned error: nonce too low
    at Object.ErrorResponse (C:\Users\aa\node_modules\web3-core-helpers\src\errors.js:29:16)
    at C:\Users\aa\node_modules\web3-core-requestmanager\src\index.js:140:36
    at XMLHttpRequest.request.onreadystatechange (C:\Users\aa\node_modules\web3-providers-http\src\index.js:102:13)
    at XMLHttpRequestEventTarget.dispatchEvent (C:\Users\aa\node_modules\xhr2-cookies\dist\xml-http-request-event-target.js:34:22)
    at XMLHttpRequest._setReadyState (C:\Users\aa\node_modules\xhr2-cookies\dist\xml-http-request.js:208:14)
    at XMLHttpRequest._onHttpResponseEnd (C:\Users\aa\node_modules\xhr2-cookies\dist\xml-http-request.js:318:14)
    at IncomingMessage.<anonymous> (C:\Users\aa\node_modules\xhr2-cookies\dist\xml-http-request.js:289:61)
    at IncomingMessage.emit (events.js:203:15)
    at endReadableNT (_stream_readable.js:1143:12)
    at process._tickCallback (internal/process/next_tick.js:63:19)
(node:3816) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:3816) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Best Answer

Run it again.

More generally, run it inside a try/catch block until success.

For your specific error, it is possible that the node is not synchronized with your account's current nonce, so you may want to add this to your options object:

nonce: await web3.eth.getTransactionCount(0xYourAccountAddress)

Since you may also encounter other types of errors, I suggest that you try this:

async function scan(message) {
    process.stdout.write(message);
    return await new Promise(function(resolve, reject) {
        process.stdin.resume();
        process.stdin.once("data", function(data) {
            process.stdin.pause();
            resolve(data.toString().trim());
        });
    });
}

async function getTransactionReceipt(web3) {
    while (true) {
        const hash = await scan("Enter transaction-hash or leave empty to retry: ");
        if (/^0x([0-9A-Fa-f]{64})$/.test(hash)) {
            const receipt = await web3.eth.getTransactionReceipt(hash);
            if (receipt)
                return receipt;
            console.log("Invalid transaction-hash");
        }
        else if (hash) {
            console.log("Illegal transaction-hash");
        }
        else {
            return null;
        }
    }
}

async function send(web3, account, data, gas) {
    while (true) {
        try {
            const options = {
                nonce: await web3.eth.getTransactionCount(account.address),
                data: "0x" + data,
                gas: gas
            };
            const signed = await web3.eth.accounts.signTransaction(options, account.privateKey);
            const receipt = await web3.eth.sendSignedTransaction(signed.rawTransaction);
            return receipt;
        }
        catch (error) {
            console.log(error.message);
            const receipt = await getTransactionReceipt(web3);
            if (receipt)
                return receipt;
        }
    }
}

async function finalDeploy(r) {
    const account = web3.eth.accounts.privateKeyToAccount(privateKey1);
    for (let i = 0; i < constructorParams.length; i++) {
        const receipt = await send(web3, account, myBin[r] + constructorParams[i], 5000000);
        console.log("Contract: " + r + " is deployed at " + receipt.contractAddress);
        contractAddressess.push(receipt.contractAddress)
    }
}
Related Topic