帶有 React 的簡單 dapp “可靠性問題”
我正在嘗試建構一個簡單的應用程序(一旦我得到簡單的工作就會改進)我創建了一個新的 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)
所以你需要聲明三個常量
WEB3.HTTP
是您節點的 http 端點,例如:http://localhost:8545
WEB3.ABI
智能合約 abiWEB3.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: {...} } };