Web3js

Metamask 交易已確認但“內部 JSON RPC 錯誤”

  • December 8, 2020

我正在使用 getWeb3() 實例化契約並撥打電話,交易說已確認但當我打開開發人員工具時出現以下錯誤MetaMask - RPC Error: Internal JSON-RPC error.

我不確定我的程式碼有什麼問題..(主要來自 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;

問題很可能是因為您正在執行本地測試網(Ganache,本地 geth for dev 或類似的)。並且您的 MetaMask 已連接到不同的測試網路,但您仍在使用相同的網路配置。(例如,您在執行中的 Ganache 實例中使用了相同的配置;然後您關閉了 Ganache 並稍後執行它)。

MetaMask 會被這個nonce數字弄糊塗。

但是,解決方案很簡單,您必須從 MetaMask 重置您的帳戶。來自https://metamask.zendesk.com/hc/en-us/articles/360015488891-Resetting-an-Account-New-UI-的步驟

  1. 點擊右上角的圖示打開“我的賬戶”頁面,選擇“設置”
  2. 在“設置”頁面,向下滾動找到“重置帳戶”。
  3. 點擊“重置賬戶”

在此處輸入圖像描述

在此處輸入圖像描述

調試時我注意到消息:“eth-json-rpc-errors@2.0.2:包重命名:https://www.npmjs.com/package/eth-rpc-errors”

所以錯誤得到解決執行npm install --save eth-rpc-errors

引用自:https://ethereum.stackexchange.com/questions/66330