24

I'm trying to call the leafPicked() function in my contract from web3 which launches Metamask as intended. After pressing accept the transaction shows as failed along with the error message pictured below.

What am I doing wrong?

Contract Function:

function leafPicked(uint numPicked) public returns (uint, uint){
    require(numPicked < remaining_leaves);
    uint number_before_picking = remaining_leaves;
    remaining_leaves -= numPicked;
    leafWasPicked(remaining_leaves, numPicked);
    return (remaining_leaves, number_before_picking);
}

Web3 function:

  web3.eth.getAccounts(function(error, accounts) {
    if (error) {
    console.log(error);
    }

    var account = accounts[0];
    console.log(account);

    App.contracts.Plant.deployed().then(function(instance) {
      plantInstance = instance;

      // This function is not executing as intended
      return plantInstance.leafPicked(parseInt(leafNum), {from: account});

    }).then(function(result) {
      console("Result from leaf picking: ", result);
      return App.SetContractValues();
    }).catch(function(err) {
      console.log(err.message);
    });
  });

enter image description here

6
  • According to the screenshot you have the wrong nonce in your transaction, rather than an out of gas error. You can check if you are you using in the code the same account as MetaMask.
    – gisdev_p
    Commented Nov 16, 2017 at 14:56
  • How can you retrieve the nonce?
    – Charles
    Commented Nov 16, 2017 at 15:06
  • web3.eth.getTransactionCount(account) gives you the nonce for the next transaction
    – gisdev_p
    Commented Nov 16, 2017 at 15:30
  • Ok. so web3.eth.getTransactionCount(account); does give 4 which is inline with the error. The tx however is set to 15 - how do I get them to match?
    – Charles
    Commented Nov 16, 2017 at 15:46
  • Question already at: stackoverflow.com/questions/45585735/… Commented Jul 22, 2018 at 9:59

13 Answers 13

17

I had the same issue with ganache, obviously re-installing metamask is not trivial, thank goodness changing the networkId of ganache put a stop to the nonce issue in metamask.

I believe you can also "reset" your account in metamask. This will set your nonce back to Zero. You can find this option under settings.

2
  • 1
    for me also changing from localhost to ropsten and back to localhost solved the issue Commented Aug 30, 2018 at 1:57
  • Performing "Reset Account" in the advanced settings solved my issue! Thanks!
    – mike
    Commented Sep 6, 2022 at 9:55
18

There are two common problems people have when using MetaMask on private networks.

If you're running a private network, you have to be sure to set your chainId to the same as your networkId. This is for EIP 155 compatibility.

If you're running a test blockchain that you've shut down and restarted from a blank state with MetaMask connected to it, you can get MetaMask confused, because it caches some information about the network it is currently connected to, including completed transactions, which it uses to derive the correct nonce. You can clear this cache by selecting a different network in MetaMask, and then your local server again.

2
  • 3
    Hi Dan, I keep getting this error when connecting to the truffle RPC. Switching server does not solve it, only reinstalling Metamask works. Do you have another solution I can try?
    – Charles
    Commented Nov 17, 2017 at 9:21
  • Try starting TestRPC with a different Network ID. MetaMask uses the current network ID to keep track of successful transactions, and uses those to compute its nonce. If you keep re-using the same network ID, MetaMask will assume it's still on the same network. We'll have it auto-fix this soon, as discussed in this issue: github.com/MetaMask/metamask-extension/issues/1999
    – DanF
    Commented Nov 18, 2017 at 0:04
13

There is a new feature in Metamask for this:

https://consensys.zendesk.com/hc/en-us/articles/360004177531-Resetting-an-Account-New-UI-

1
  • 2
    link not working Commented Aug 22, 2018 at 20:48
5

It seems this is an ongoing Metamask issue when testing on the private networks.

It is described here: Nonce calculation is broken for private networks

And here: Truffle develop static network id interferes with MetaMask

The current solution is to reinstall Metamask - it worked for me.

1
  • You can also simply disable and re-enable Metamask in Chrome.
    – Stan James
    Commented Jan 6, 2018 at 19:04
5

Starting from MetaMask v3.14.1 you can reset your account as follow:

Resetting an Account In the Settings menu, MetaMask has a "Reset Account" button. This button wipes the current account's transaction history, which is used to calculate the current account nonce.

enter image description here

Normal users should never have a reason to use this feature.

This is useful for developers who reset a test network but want to continue using the same account, forcing MetaMask to believe this network ID is a clean network in a fresh state.

Ref: http://metamask.helpscoutdocs.com/article/36-resetting-an-account

Copied from https://stackoverflow.com/a/47429502/8303489

4

I answered this in a stackoverflow post, however, since this post comes up on top in google search, so here we go

Check your truffle.js or truffle-config.js

if you are using the HDWalletProvider like below, it seems that this is what causing the error

var HDWalletProvider = require("truffle-hdwallet-provider");
var mnemonic = "your mnemonic";

module.exports = {
  networks: {
    development: {
      provider: function() {
        return new HDWalletProvider(mnemonic, "http://127.0.0.1:8545/", 0, 50);
      },
      network_id: '*',
      gas: 9999999
    }
  },
  compilers: {
    solc: {
      version: "^0.4.25"
    }
  }
};

remove the HDWalletProvider like below, it solves mine

module.exports = {
  networks: {
    development: {
      host: "127.0.0.1",     // Localhost
      port: 8545,            // Standard Ganache UI port
      network_id: "*", 
      gas: 4600000
    }
  },
  compilers: {
    solc: {
      version: "0.5.2"
    }
  }
};
1
  • This question is unrelated to Truffle.
    – Ismael
    Commented May 16, 2019 at 16:18
2

Genash uses the same networkId as ropsten network, and for costum url's metamask uses the same network params as the last network, so change your network to ropsten1 and back to localhost.

Thanks CodingYourLife for the solution.


1 or whatever network your local client is running on.

2

I really don't know why or how, but nothing here worked for me.. I opened the console and saw a warning ethereum.enable() is deprecated, please use eth_requestAccounts

So I just copied the code from the docs and now it works like a charm. Here's the link to the docs: https://docs.metamask.io/guide/rpc-api.html#eth-requestaccounts

And here is the link to the example: https://docs.metamask.io/guide/rpc-api.html#example

This is how I implemented the code:

if ( window.ethereum ) {
    const web3 = new Web3( window.ethereum );

    try {
        // Request account access if needed
        let handleAccountsChanged;
        await window.ethereum
            .request( {
                method: 'eth_requestAccounts'
            } )
            .then( handleAccountsChanged )
            .catch( ( error ) => {
                if ( error.code === 4001 ) {
                    // EIP-1193 userRejectedRequest error
                    console.log( 'Please connect to MetaMask.' );
                } else {
                    console.error( error );
                }
            } );
    } catch ( error ) {
        // handle error
    }
}
3
  • 1
    Hi Jonas, Welcome. +1 for the answer, It would be great you add examples from the link as well. Commented Jun 1, 2021 at 11:27
  • 2
    Thanks! I usually don't add my code if there is an example in the link, because the example in the docs may change. I added my code now, and the link to the example.
    – BonisTech
    Commented Jun 2, 2021 at 6:43
  • 1
    Sure, great. your code example would be useful to anyone facing a similar issue. Commented Jun 2, 2021 at 7:22
1

I would like to add one more solution as none of these had worked for me.

I clicked on the Metamask chrome extension then went to My Accounts > Settings > Advanced > Reset Account. This resets the accounts transaction history but won't change the balances or require you to re-enter your seed phrase.

1

In the MetaMask setting > go to advanced setting > turn on custom nonce.

MetaMask-Advance_setting-custom-nonce

After turning on Custom nonce, you can add your custom nonce before making any transaction.

MetaMask-custom-Nonce

The custom nonce should be the account nonce. Here in this case it is 4. (you can get the account nonce in the error)

If this works for anyone please let me know.

1
  • Thanks! This is way easier than resetting the account each time
    – Milk
    Commented Apr 2, 2021 at 21:59
0

You should reset your metamask account by going to setting option and reset account. Please check the metamask docs.

0

I had the same problem solved by:

  1. As advised by Phillip Gibb in the above, I changed the Ganache network id to 5778. Ganache will restart.

  2. Re-connect MetaMask to Ganache.

    check your account. If only Account 1, this is a good sign. You can manually import other accounts. But if more than one account still exist, that's not a good sign. You may have to change to other Ganache network id and reconnect MetaMask.

  3. Migrate contract

truffle migrate --reset --network development

  1. Contract deployed. Test new transactions ok.
0

I faced the same issue but I am using ethers version 6 (6.2.3) and Ganache To solve this I am waiting for confirmation blocks as below

//Deploying contract
 const contract = await contractFactory.deploy();
 const deployTxn = await contract.deploymentTransaction().wait(2); //this is the solution you can change wait to 1 block also it will work 

// Calling contract functions  
 const transactionResponse = await contract.store('7');
 const transactionReceipt = await transactionResponse.wait(1); // You can remove this line if you don't want to wait post txn

Complete code for deployment and calling functions

const { ethers, JsonRpcProvider } = require('ethers');
const fs = require('fs-extra');
async function main() {
  const provider = new JsonRpcProvider('http://127.0.0.1:7545');

  const wallet = new ethers.Wallet(
    'private key here',
    provider
  );

  const abi = fs.readFileSync('./SimpleStorage_sol_SimpleStorage.abi', 'utf8');
  const binary = fs.readFileSync(
    './SimpleStorage_sol_SimpleStorage.bin',
    'utf8'
  );
  const contractFactory = new ethers.ContractFactory(abi, binary, wallet);
  console.log('Deploying, Please wait...');
  const contract = await contractFactory.deploy();
  const deployTxn = await contract.deploymentTransaction().wait(2);
  const transactionResponse = await contract.store('7');
  const transactionReceipt = await transactionResponse.wait(1);
  const favNum = await contract.retrieve();
  console.log(favNum.toString());
}

main()
  .then(() => process.exit(0))
  .catch((error) => {
    console.error(error);
    process.exit(1);
  });

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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