Frontend: Load Contracts to React¶
Now it's time to load the contracts into the frontend. We haven't touched it yet, so let's get started by modifying the App.js file.
Let's modify the client/App.js file and add in the right contracts to import:
import React, { Component } from "react";
import MyToken from "./contracts/MyToken.json";
import MyTokenSale from "./contracts/MyTokenSale.json";
import KycContract from "./contracts/KycContract.json";
import getWeb3 from "./getWeb3";
import "./App.css";
class App extends Component {
//more code ...
MetaMask / Ganache Problems (or Changes)
Two problems here:
-
There is a problem with
this.web3.eth.net.getId();
using MetaMask. See deprecated features from MetaMask. Instead we need to use the ChainId. The Code below is already fixed! -
Ganache has sometimes the wrong ChainId https://github.com/trufflesuite/ganache-core/issues/575. This means, at the time of writing this, we need to use ganache-cli with custom network id and chain id. Start ganache cli with
ganache-cli --networkId 1337 --chainId 1337
Then change the state variable, as well as the componentDidMount function to load all the Smart Contracts using web3.js:
state = { loaded: false };
componentDidMount = async () => {
try {
// Get network provider and web3 instance.
this.web3 = await getWeb3();
// Use web3 to get the user's accounts.
this.accounts = await this.web3.eth.getAccounts();
// Get the contract instance.
//this.networkId = await this.web3.eth.net.getId(); <<- this doesn't work with MetaMask anymore
this.networkId = await this.web3.eth.getChainId();
this.myToken = new this.web3.eth.Contract(
MyToken.abi,
MyToken.networks[this.networkId] && MyToken.networks[this.networkId].address,
);
this.myTokenSale = new this.web3.eth.Contract(
MyTokenSale.abi,
MyTokenSale.networks[this.networkId] && MyTokenSale.networks[this.networkId].address,
);
this.kycContract = new this.web3.eth.Contract(
KycContract.abi,
KycContract.networks[this.networkId] && KycContract.networks[this.networkId].address,
);
// Set web3, accounts, and contract to the state, and then proceed with an
// example of interacting with the contract's methods.
this.setState({ loaded:true });
} 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);
}
};
Finally change the bottom part to listen for "loaded" instead of web3:
render() {
if (!this.state.loaded) {
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>
</div>
);
}
Start the development server and see if there are any obvious errors being thrown:
cd client && npm run start
First, if installed, MetaMask should ask you if you want to connect:
If you say "Connect" then you should be able to see this page:
Let's start by developing our KYC Rules...