Web3js
Metamask 交易已確認但“內部 JSON RPC 錯誤”
我正在使用 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-的步驟
- 點擊右上角的圖示打開“我的賬戶”頁面,選擇“設置”
- 在“設置”頁面,向下滾動找到“重置帳戶”。
- 點擊“重置賬戶”
調試時我注意到消息:“eth-json-rpc-errors@2.0.2:包重命名:https://www.npmjs.com/package/eth-rpc-errors”
所以錯誤得到解決執行
npm install --save eth-rpc-errors