web3.jsでデプロイしたコントラクトをReactで使う(前編)
はじめに
今回はデプロイしたコントラクトを実際にwebアプリで扱う方法を紹介したいと思います。(いわゆるDAppと呼ばれるもの)
コントラクトは簡単なものを使用して、web3.jsの使い方にフォーカスを当てたいと思います。
ちなみにフロントはReactを使っていますので、create-react-appでReactが使える準備だけお願いします。
準備
デプロイしたコントラクト
// SPDX-License-Identifier: MIT
pragma solidity >=0.4.21 <0.7.0;
contract Greeting {
string public greeting = "hello";
// greetingを読むだけの関数。初期値は"hello"。
function sayHello() external view returns (string memory) {
return greeting;
}
// 今のgreetingを編集する関数。編集するのでガス代が発生する。
function updateGreeting(string calldata _greeting) external {
greeting = _greeting;
}
}
コントラクトのデプロイ方法は前回の記事をご参考ください。
プロバイダ
ブロックチェーンはノードによって成り立っているので、web3.jsのプロバイダ設定ではどのノードにアクセスして処理を実行させるかを設定します。
const web3 = new Web3(
new Web3.providers.HttpProvider(
"https://ropsten.infura.io/v3/YOUR_INFURA_PROJECT_ID"
)
);
今回はinfuraを使用してRopstenにデプロイしたコントラクトを使用しますので、HttpProviderの中はinfuraのURLを書いてあげます。もしganacheを使ってローカルにデプロイした場合はhttp://localhost:7545になるかと思います。
コントラクトのアドレス
コントラクトをデプロイすると、そのコントラクトのアドレスが割り振られるので、アドレスをコピーしておきます。
const address = "0x4D564C434CfeC2AD44C9012bAD771b315C2738aA";
ABI(Application Binary Interface)
コントラクトのメソッドをJSON形式で表しているものです。
コントラクトをcompileした際に生成されます。
import ABI from "./contracts/Greeting.json";
const abi = ABI.abi;
srcの中にcontractsフォルダを作り、生成されたコントラクトのJSONファイルをそのままコピーして入れましょう。
あとはabi部分を呼び出してあげるだけです。
コントラクトの呼び出し方
これでデプロイしたコントラクトを呼び出す準備ができました。
const contract = new web3.eth.Contract(abi, address);
今の段階の全体のコードはこんな感じです。
import "./App.css";
import Web3 from "web3";
import ABI from "./contracts/Greeting.json";
const web3 = new Web3(
new Web3.providers.HttpProvider(
"https://ropsten.infura.io/v3/YOUR_INFURA_PROJECT_ID"
)
);
const address = "0x4D564C434CfeC2AD44C9012bAD771b315C2738aA";
const abi = ABI.abi;
const contract = new web3.eth.Contract(abi, address);
function App() {
return (
<div className="App">
<h1>How to use web3.js</h1>
</div>
);
}
export default App;
ではコントラクトを呼んでみようと思います。
call
上記のGreetingコントラクトの一つ目の関数、sayHello()はview関数を使用していますので、読み取り専用になります。読み取り専用ということは、関数を実行するのにガス代もかかりません。
読み取り専用の関数(view関数やpure関数)にはcallを使って呼ぶことができます。
const handleCall = async () => {
const greeting = await contract.methods.sayHello().call();
console.log(greeting);
};
return (
<div className="App">
<h1>How to use web3.js</h1>
<button onClick={handleCall}>sayHello</button>
</div>
);
コントラクトの関数を使用すると戻り値がPromiseで返ってくるので、async/awaitを使用しています。コントラクトでgreeting="hello"にしていれば、console.logでhelloが表示されていると思います。
続きます
少し長くなりそうなので今回の記事はここまでにします。
次回は二つ目の関数、updateGreetingで実際にブロックチェーン上のデータを変更する実装を説明したいと思います。ガス代もかかるので、Metamaskも使用します。
Discussion