TL;DR
truffleを使った時にフロントエンドとの連携の手順が多いので、個人的boilerplateを作成した。
ソース:ここ
動機
前までDappsの作成の時は、truffle-contractでgetInstance関数を作って、ReactのコンポーネントごとにgetInstanceを使ってコントラクトとフロントを連携していたが、truffle-contractが非推奨(?)になっているっぽいので、truffle-contractを使用しないDappを作ろうとした。
しかし、web3周りでかなり時間を食ったのでボイラープレートを作成した。
App.js
コピーしたbuildファイル群をimportした後、Appコンポーネントのstateにcontractのインスタンスを設定して、そこから.solファイルの関数を呼ぶ。今回はボタンを押して100を表示させるという非常に簡単な動作だが、もっと動作が煩雑になるとreduxやReact-Hooksを使用した方が良さそう...
// App.js
import React from "react"
import Sample from "./contracts/Sample"
import web3 from './web3/provider'
export default class App extends React.Component{
state = {contract : null,accounts:null,storageValue:null}
componentDidMount = async () => {
const accounts = await web3.eth.getAccounts();
const networkId = await web3.eth.net.getId();
const deployedNetwork = Sample.networks[networkId];
const instance = new web3.eth.Contract(
Sample.abi,
deployedNetwork.address,
{ from: web3.eth.defaultAccount }
);
console.log("Your account:",accounts)
this.setState({contract:instance, accounts:accounts})
console.log("Contract Instance :",this.state.contract)
};
runExample = async () => {
const { accounts, contract } = await this.state;
await contract.methods.setValue(100).send({from:accounts[0]})
const response = await contract.methods.getValue().call();
this.setState({ storageValue: response });
console.log("Response : ",this.state.storageValue)
};
render() {
return (
<div>
<button onClick={() => this.runExample()}>SET</button>
{this.state.storageValue}
</div>
)
}
}
動作
npm run dev
の後にlocalhost:3030にアクセス。
コンポーネントのstateの値をボタンを押して変化させるというだけの動作
SETボタンを押すと、Metamaskが起動して,確認を押すと
100がセットされた

package.json
- web3のバージョンは最新バージョンをインストールすると正体不明のエラーになることがあるので
"web3": "1.0.0-beta.37"
で固定している。 -
truffle migrate --reset
とtruffle compile --all
はよく使うのでscriptsに書いた。 -
npm run artifacts
でjsonファイル群を/src/
に持ってくる。
// package.json
{
"name": "web3-templete",
"version": "1.0.0",
"license": "ISC",
"description": "web3-templete",
"main": "truffle-config.js",
"directories": {
"test": "test"
},
"scripts": {
"dev": "npm run artifacts && yarn start",
"mc":"truffle compile --all && truffle migrate --reset",
"mcr":"truffle compile --all && truffle migrate --network ropsten",
"artifacts": "cp -r ../build/contracts/ ./src/contracts",
"start": "react-scripts start && npm run artifacts",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"dependencies": {
"antd": "^3.12.3",
"react": "^16.6.3",
"react-dom": "^16.6.3",
"react-scripts": "^2.1.5",
"react-toastify": "^4.4.3",
"truffle-hdwallet-provider": "^1.0.2",
"web3": "1.0.0-beta.37"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
]
}
truffle-config.js
truffle-config.js
は普通通りに書いている。
ropstenはinfura使用を想定
var HDWalletProvider = require("truffle-hdwallet-provider");
var mnemonic = process.env.MNEMONIC;
var url = process.env.INFURAURL;
module.exports = {
networks: {
development: {
host: "127.0.0.1",
port: 8545,
network_id: "*" // Match any network id
//gas:4712388
},
ropsten: {
provider: function() {
return new HDWalletProvider(
mnemonic,
url // set your infura url
);
},
network_id: 3,
// gas: 5000000
}
}
}
まとめ
web3のバージョンはできれば固定しましょう。
参考
https://github.com/truffle-box
https://github.com/truffle-box/react-box