2

I am using getWeb3() to instantiate a contract and make calls with, the transaction says that is confirmed but when I open up developer tools there is the following error MetaMask - RPC Error: Internal JSON-RPC error.

I am not sure what is wrong with my code.. (it is mostly from the Truffle react-box)

import React, { Component } from "react";
import SimpleStorageContract from "./contracts/SimpleStorage.json";
import getWeb3 from "./utils/getWeb3";

import "./App.css";

class App extends Component {
  state = { storageValue: 0, web3: null, accounts: null, contract: null };

  componentDidMount = async () => {
    try {
      // Get network provider and web3 instance.
      const web3 = await getWeb3();
      // Use web3 to get the user's accounts.
      const accounts = await web3.eth.getAccounts();

      // Get the contract instance.
      const networkId = await web3.eth.net.getId();
      const deployedNetwork = SimpleStorageContract.networks[networkId];
      const instance = new web3.eth.Contract(
        SimpleStorageContract.abi,
        deployedNetwork && deployedNetwork.address,
      );

      // Set web3, accounts, and contract to the state, and then proceed with an
      // example of interacting with the contract's methods.
      this.setState({ web3, accounts, contract: instance }, this.runExample);
    } catch (error) {
      // Catch any errors for any of the above operations.
      alert(
        `Failed to load web3, accounts, or contract. Check console for details.`,
      );
      console.error(error);
    }
  };

  componentWillMount() {
    // Get network provider and web3 instance.
    // See utils/getWeb3 for more info.    
    getWeb3()
    .then(results => {
      this.setState({
        web3: results
      })

      // Instantiate contract once web3 provided.
      this.instantiateContract()
    })
    .catch((error) => {      
      console.log(error);
      console.log('Error finding web3.')
    })
  }

  instantiateContract() {
    /*
     * SMART CONTRACT EXAMPLE
     *
     * Normally these functions would be called in the context of a
     * state management library, but for convenience I've placed them here.
     */

    const contract = require('truffle-contract')
    const simpleStorage = contract(SimpleStorageContract)
    simpleStorage.setProvider(this.state.web3.currentProvider)

    // Declaring this for later so we can chain functions on SimpleStorage.
    var simpleStorageInstance

    // Get accounts.
    this.state.web3.eth.getAccounts((error, accounts) => {
      simpleStorage.deployed().then((instance) => {
        simpleStorageInstance = instance

        this.setState(prevState => ({
          ...prevState,
          accounts,
          simpleStorageInstance
        }));

        // Stores a given value, 5 by default.
        return simpleStorageInstance.set(5, {from: accounts[0]})
      }).then((result) => {
        // Get the value from the contract to prove it worked.
        return simpleStorageInstance.get.call(accounts[0])
      }).then((result) => {
        // Update state with the result.
        return this.setState(prevState => ({
          ...prevState,
          storageValue: result.c[0]
        }))
      })
    })
  }

  runExample = async () => {
    const { accounts, contract } = this.state;

    // Stores a given value, 5 by default.
    await contract.methods.set(5).send({ from: accounts[0], gas: 100000 });

    // Get the value from the contract to prove it worked.
    const response = await contract.methods.get().call();

    // Update state with the result.
    this.setState({ storageValue: response });
  };

  addToSimpleStorage() {
    console.log("RUNNING");
    if (this.state.simpleStorageInstance && this.state.accounts) {
      const value = this.storageAmountInput.value;
      this.state.simpleStorageInstance.set(value, {from: this.state.accounts[0]})
        .then((result) => {
          return this.state.simpleStorageInstance.get.call(this.state.accounts[0])
        }).then((result) => {
          this.setState(prevState => ({
            ...prevState,
            storageValue: result.c[0]
          }));
        }).catch((err) => {
          console.log('error');
          console.log(err);
        });
    } else {
      this.setState(prevState => ({
        ...prevState,
        error: new Error('simple storage instance not loaded')
      }))
    }
  }

  render() {
    if (!this.state.web3) {
      return <div>Loading Web3, accounts, and contract...</div>;
    }
    return (
      <div className="App">
        <h1>Good to Go!</h1>
        <p>Your Truffle Box is installed and ready.</p>
        <h2>Smart Contract Example</h2>
        <p>
          If your contracts compiled and migrated successfully, below will show
          a stored value of 5 (by default).
        </p>
        <p>
          Try changing the value stored on <strong>line 40</strong> of App.js.
        </p>
        <div>The stored value is: {this.state.storageValue}</div>
        <form className="pure-form pure-form-stacked">
          <fieldset>
            <label htmlFor="storage">Storage Amount</label>
            <input id="storage" type="number" ref={c => { this.storageAmountInput = c }} />
            <button
              className="pure-button"
              onClick={(e) => {
                e.preventDefault();
                this.addToSimpleStorage()
              }}
            >
              Set Storage
            </button>
          </fieldset>
        </form>
      </div>
    );
  }
}

export default App;
1

Most likely the problem is because you are running a local test-net (Ganache, local geth for dev or similar). And your MetaMask was connected to a different test-network but you are still using the same network configuration. (For example, you used the same configuration with a running instance of Ganache; Then you closed Ganache and run it later).

MetaMask will be confused by the nonce number.

However, the solution is simple, you have to reset your account from MetaMask. Steps from https://metamask.zendesk.com/hc/en-us/articles/360015488891-Resetting-an-Account-New-UI-

  1. Open the “My Account” page by clicking the icon on the upper right corner, and select “Settings”
  2. On the “Setting” page, scroll down to find “Reset Account”.
  3. Click “Reset Account”

enter image description here

enter image description here

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.