1

I am working with web3.js since sometime now , but now i am stuck with nonce too low error , the nonce is proper also i have checked private key and other addresses , they also seem to proper , however when i call addNum function is gives nonce too low error

var Web3 = require('web3');
let tx = require('ethereumjs-tx');

var Web3 =  new Web3(new Web3.providers.HttpProvider("https://rinkeby.infura.io/kG4Z6EC5EsknbOqki4mz")); 

let abi = [
    {
        "constant": false,
        "inputs": [
            {
                "name": "x",
                "type": "uint256"
            }
        ],
        "name": "addNum",
        "outputs": [],
        "payable": false,
        "stateMutability": "nonpayable",
        "type": "function"
    },
    {
        "constant": true,
        "inputs": [],
        "name": "getSum",
        "outputs": [
            {
                "name": "sum",
                "type": "uint256"
            }
        ],
        "payable": false,
        "stateMutability": "view",
        "type": "function"
    }
];


let contract = Web3.eth.contract(abi);
let contractAddress = "0xc8fe6f104a5076a8d3b1284cd1a48095d6f5b5cd";
let contractInstance = contract.at(contractAddress);

let defaultAccount = '0x262b76df1dcb6542aa4a19296a824f0fdd1b4b04'; 
let privatekey = 'ba456ad306a69c3830eed33f690e8f5b93e36cea3cd37ed9604f71b95a5ae1e3';



    var num = 2;

    var data = contractInstance.addNum.getData(num);
            sendRaw(data, function(err, hash){
                if(err)
                {
                   console.log("err "+err);
                }
                else
                {
                    console.log("hash "+hash);
                }
            });



/**
 * Function to signed and call function in solidity  
 * param data
 * return (err, transactionhash)
 */
var count = Web3.eth.getTransactionCount(defaultAccount);

function sendRaw(data, callback) 
{
    var rawTx  = {
        nonce: Web3.toHex(++count),
        from: Web3.toHex(defaultAccount),
        gasLimit: Web3.toHex(300000),
        gasPrice: Web3.toHex(Web3.toWei('20', 'gwei')),
        to: Web3.toHex(contractAddress),
        value: 0,
        data: data
    };
    var privateKey = new Buffer(privatekey, 'hex');
    var transaction = new tx(rawTx);
    transaction.sign(privateKey);
    var serializedTx = transaction.serialize().toString('hex');
    Web3.eth.sendRawTransaction(
    '0x' + serializedTx, function(err, result) {
        if(err) 
        {
            callback(err, '');
        } 
        else 
        {
            callback('', result);
        }
    });
}

Also i am testing upgradable smart contract so the address is of proxy contract and abi is of logic contract

  • Try changing count++ to ++count. Otherwise, you'll just keep trying it with the value returned by Web3.eth.getTransactionCount, which is the current nonce. – goodvibration Sep 15 '18 at 18:33
  • and why do you use Web3.toHex in many place? I think it's not necessary! – Ha ĐANG Sep 15 '18 at 18:35
  • @goodvibration changing to ++ count does not help – Ether Sep 15 '18 at 18:59
  • why are you incrementing the count++ , is this the second transaction you are sending? If not, just set nonce to the number returned by getTransactionCount(). The blockchain will increment the transaction count for you, when your transaction is mined. Unless you are sending multiple transactions, you don't need to increment anything. – Nulik Sep 15 '18 at 19:09
1

This line:

var count = Web3.eth.getTransactionCount(defaultAccount,'pending');

You're starting your count at the number of outstanding/pending transactions the node is aware of. That's the wrong queue.

You could start here:

var count = Web3.eth.getTransactionCount(defaultAccount);

This will drop the next transaction on the nonce that follows the last known confirmed transaction.

It's not a good pattern, generally, to rely on the node's transaction count to set the nonce. Ideally, the software client will be aware of every transaction sent from the account and will know the correct number without asking.

Have a look over here for more info: Why does sendSignedTransaction return a tx hash BUT does not post to the Rinkeby network (React, Metamask, web3, infura)

And here: Concurrency patterns for account nonce

Hope it helps.

  • Changing to var count = Web3.eth.getTransactionCount(defaultAccount); does not help – Ether Sep 15 '18 at 19:01
  • Maybe post your account address and let us know which network it's on. Bottom line is the next nonce needs to be the one that comes after the last confirmed nonce. – Rob Hitchens - B9lab Sep 15 '18 at 20:24
  • i have updated the code above to with suggested changes , also have now made private key visible , the contracts and address are on testnet , so please feel free to use the code , still stuck with nonce too low – Ether Sep 16 '18 at 5:12
  • Also i think although it says nonce too low , it is not related to nonce... there is something silly mistake that i am missing – Ether Sep 16 '18 at 5:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.