i am trying to build a simple app (will improve once i get the simple one to work)I created a new Reactapp, added both the contracts and migrations directories and i use ganache and metamaks.
I have truffle installed. and i can successfully compile and migrate my contact on ganache
The Dapp has an input field that takes a string and save in bolckchain and then fetch it back and diplay that on screen.
I get an error form this part.
import SimpleStorageContract from '../build/contracts/SimpleStorage.json'
/src/App.js
Module not found: You attempted to import ../build/contracts/SimpleStorage.json which falls outside of the project src/ directory. Relative imports outside of src/ are not supported. You can either move it inside src/, or add a symlink to it from project's node_modules/.
And if i move build/contracts directory into src i get the following error
TypeError: Cannot read property 'set' of undefined
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;
SimpleStorage.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;
}
}
Best Answer
I think that it's not correct way to import the smart contract into an dApp. The correct way should be as below code snippet
So you need to declare three constant
WEB3.HTTP
is the http end-point of your node, E.x:http://localhost:8545
WEB3.ABI
smart contract abiWEB3.ADDRESS_CONTRACT
smart contract addressHope this help!