Solidity

帶有 React 的簡單 dapp “可靠性問題”

  • November 23, 2021

我正在嘗試建構一個簡單的應用程序(一旦我得到簡單的工作就會改進)我創建了一個新的 Reactapp,添加了契約和遷移目錄,我使用了 ganache 和 metamaks。我安裝了松露。我可以在 ganache 上成功編譯和遷移我的聯繫人

Dapp 有一個輸入欄位,它接受一個字元串並保存在 bolckchain 中,然後將其取回並在螢幕上顯示。

我從這部分得到一個錯誤。

import SimpleStorageContract from '../build/contracts/SimpleStorage.json'

/src/App.js

未找到模組:您嘗試導入項目 src/ 目錄之外的 ../build/contracts/SimpleStorage.json。不支持 src/ 之外的相對導入。你可以將它移到 src/ 中,或者從項目的 node_modules/ 中添加一個符號連結。

如果我將 build/contracts 目錄移動到 src 我得到以下錯誤

TypeError:無法讀取未定義的屬性“集”

完整程式碼

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
//import SimpleStorageContract from '../build/contracts/SimpleStorage.json'
import SimpleStorageContract from './build/contracts/SimpleStorage.json'
import getWeb3 from './utils/getWeb3'
import truffleContract from "truffle-contract";
class App extends Component {


   constructor(props) {
       super(props)

       this.state = {
           account: null,
           web3: null,
           firstName:null,
           fName:null,
       }
   }

   componentWillMount() {

   getWeb3.then(results => {
   this.setState({ web3: results.web3

   })

       this.instantiateContract()
   })
       .catch(() => {
   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(truffleContract)
   const simpleStorage = contract(SimpleStorageContract)
   simpleStorage.setProvider(this.state.web3.currentProvider)

   // Get accounts.
   this.state.web3.eth.getAccounts((error, accounts) => {
       simpleStorage.deployed().then((instance) => {
           this.simpleStorageInstance = instance;
           this.setState({ account: accounts[0] });
           // Get the value from the contract to prove it worked.
           return this.simpleStorageInstance.get.call(accounts[0])
       })
   })
}
     handleSubmit = ()=> {

         const response = this.simpleStorageInstance.get().call();
         this.setState({fName: response.c[0]});
     }






   handleChange = (event)=> {
       const value = event.target.value;

       this.simpleStorageInstance.set(value , {from: this.state.account}).then((r) => {
           return this.setState({ firstName: value })
   })
   }


   render() {
   return (
     <div className="App">
       <header className="App-header">
         <img src={logo} className="App-logo" alt="logo" />
         <h1 className="App-title">Welcome to React</h1>
       </header>
       <p className="App-intro">

             <div>
                 <form onSubmit= {this.handleSubmit}>
                 <input type="text" onChange={this.handleChange}/>
                 <input type="submit"/>

             </form></div>
           <p>{this.state.firstName}</p>
           <p>{this.state.fName}</p>
       </p>


     </div>
   );
 }
}

export default App;

簡單儲存.sol

pragma solidity 0.4.24;

contract SimpleStorage {
   string firstName;

   function set(string x) public {
       firstName = x;
   }

   function get() public view returns (string) {
       return firstName;
   }
}

我認為將智能合約導入 dApp 不是正確的方法。正確的方法應該如下程式碼片段

   let web3 = new Web3(new Web3.providers.HttpProvider(WEB3.HTTP))

   const SimpleStorage = web3.eth.contract(WEB3.ABI)
   const contract = SimpleStorage(WEB3.ADDRESS_CONTRACT)

所以你需要聲明三個常量

  1. WEB3.HTTP是您節點的 http 端點,例如:http://localhost:8545
  2. WEB3.ABI智能合約 abi
  3. WEB3.ADDRESS_CONTRACT智能合約地址

希望這有幫助!

問題是 create-react-app 禁止在src/目錄之外導入任何內容。

您可以通過執行來解決它,eject但您可能不希望這樣做,因為之後您將無法利用對 create-react-app 腳本的更新。如果您想嘗試,請在此處了解更多資訊:https ://stackoverflow.com/a/44115058/203704

我採用的方法是重新配置 Truffle 以將腳本編譯到src/abi目錄而不是預設的build/contracts. 為此,(根據文件)您只需在文件中添加contracts_build_directory條目truffle.js

module.exports = {
   contracts_build_directory: "./src/abi",
   networks: {...}
};

但是,我發現這有不一致的行為,具體取決於我是compile之前執行migrate還是只是讓migrate -reset重新編譯和遷移,其結果是它會抱怨找不到src/abi文件夾。

我發現其他人也看到了同樣的問題,解決方法是:

const path = require('path');
module.exports = {
   contracts_build_directory: path.join(__dirname, "/src/abi"),
   networks: {...}
   }
};

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