フルスタックのEthereumとEVM開発の完全ガイド
React、Ethers.js、Solidity、及びHardhatを使ったフルスタックなdAppsの構築
2022年9月11日に更新
このチュートリアルでは、Ethereum Virtual Machine(EVM)を活用することで、Ethereum、Polygon、Avalanche、Celoなど多数のブロックチェーンネットワーク上でフルスタックアプリを構築するためのweb3技術スタックを学びます。
このプロジェクトのコードはこちらにあります。このチュートリアルのビデオコースはこちらにあります。また、Defining the web3 stackもチェックしてみてください。
ブロックチェーンの世界での作業を始めてから、私はSolidityとEVMを使ったスマートコントラクトの開発にますます深く潜り込んできました。Solidityを使ってフルスタックなdAppsを構築するための良いスタックを見つけました:
▶︎ クライアントフレームワーク - React
▶︎ Ethereum開発環境 - Hardhat
▶︎ Ethereum Web クライアントライブラリ - Ethers.js
▶︎ API レイヤー - The Graph Protocol
ただし、学んでいると気づいた問題は、これらについて個別にはかなり良いドキュメントがあったとしても、こうした技術をすべてまとめてどのように機能するかを理解するための情報が実際にはなかったことです。scaffold-ethのような素晴らしいボイラープレートもあります(これにはEthers、Hardhat、The Graphも含まれていますが)、入門者には負担が大きすぎるかもしれません。
私は最新のリソース、ライブラリ、およびツールを使用してEthereumアプリをフルスタックで構築する方法を示す案内書が欲しいと思いました。
私が興味のあった分野は以下の通りです:
- ローカル、テスト、メインネットにEthereumスマートコントラクトを作成、デプロイ、テストする方法
- ローカル、テスト、そして本番環境/ネットワーク間で切り替える方法
- React、Vue、Svelte、Angularのようなフロントエンドから様々な環境を介してコントラクトに接続し、それらとやり取りする方法
これらを全て把握し、自分が本当に満足できるスタックで作業を進められるようになった後、これらのスタックを使ってフルスタックなEthereumアプリを構築し、テストする方法をまとめたものが他の人々にとっても参考になるだろうし、自分自身の将来の参照のためにもなるだろうと思って、この参考資料を書くことにしました。それがこの参考資料です。
パーツ
まず、私たちが使うことになる主なパーツと、それらがスタックの中でどのようにフィットするのかを見ていきましょう。
1. Ethereum開発環境
スマートコントラクトを構築するとき、ライブ環境に対処することなく、コントラクトのデプロイ、テスト、およびSolidityコードのデバッグをする手段が必要です。
また、Solidityコードをクライアント側アプリケーションで実行可能なコードにコンパイルする方法も必要です—我々の場合は、Reactアプリです。この方法については後で詳しく学びます。
Hardhatは、フルスタック開発のために設計されたEthereum開発環境およびフレームワークであり、このチュートリアルで使用するフレームワークです。
エコシステム内の類似のツールには、Ganache、Truffle、Foundryなどがあります。
2. Ethereum Webクライアントライブラリ
Reactアプリ内で、デプロイされたスマートコントラクトとやり取りするための方法が必要になります。データを読む以外にも、新しいトランザクションを送信する方法が必要です。
ethers.jsは、React、Vue、Angular、SvelteなどのクライアントサイドJavaScriptアプリケーションからEthereumブロックチェーンとそのエコシステムとの対話を完全にかつコンパクトに行うためのライブラリを目指しています。これが私たちが使用するライブラリです。
エコシステム内で他に人気のあるオプションには、web3.jsがあります。
3. Metamask
Metamaskは、アカウント管理とユーザーをブロックチェーンに接続するのに役立ちます。MetaMaskを使うと、ユーザーはいくつかの異なる方法でアカウントと鍵を管理でき、それらをサイトのコンテキストから隔離することができます。
ユーザーがMetaMaskウォレットを接続すると、開発者はweb3互換ブラウザのユーザー(MetaMaskユーザーなど)を識別するグローバルに利用可能なEthereum API(window.ethereum
)と対話することができるようになります。トランザクションの署名をリクエストすると、MetaMaskは可能な限り理解しやすい方法でユーザーにプロンプトを表示します。
4. React
Reactはウェブアプリケーション、ユーザーインタフェース、UIコンポーネントを作成するためのフロントエンドJavaScriptライブラリです。Facebookおよび多くの個々の開発者や企業によってメンテナンスされています。
Reactとその大規模なエコシステム、例えばNext.js、Gatsby、Redwood、Blitz.jsは、従来のSPAs、静的サイトジェネレーター、サーバーサイドレンダリング、あるいはそれらの全てを組み合わせたタイプを含むあらゆるデプロイターゲットを可能にします。Reactは引き続き前端分野を支配していると考えられ、少なくとも近い将来まではそう続くと思います。
5. The Graph
Ethereumのようなブロックチェーン上に構築されたほとんどのアプリでは、チェーンから直接データを読み取るのは困難で時間がかかるため、かつては自身の中央集権的なインデックスサーバーを構築し、それらのサーバーからAPIリクエストを処理していました。これは多大なエンジニアリングリソースとハードウェアリソースを要し、分散化に必要なセキュリティプロパティを損ないます。
The Graphは、完全に分散型アプリケーションの作成を可能にするブロックチェーンデータのインデクシングプロトコルであり、この問題を解決し、アプリが消費できる豊富なGraphQLクエリレイヤーを公開しています。このガイドではアプリ用のサブグラフを構築しませんが、将来のチュートリアルでそうする予定です。
Ethereum上でGraphQL APIを構築する方法を学ぶには、Building GraphQL APIs on Ethereumをチェックしてください。
何を構築するか
このチュートリアルでは、基本的なスマートコントラクトをいくつか構築、デプロイ、接続します:
- Ethereumのブロックチェーン上にメッセージを作成して更新するための契約
- トークンを発行した後、契約のオーナーが他者にトークンを送信し、トークン残高を読み取ることができるようにします。そして、新しいトークンのオーナーが他へもそれらを送ることができるようにします。
また、ブロックチェーンにデプロイされたコントラクトから以下を可能にするReactフロントエンドも構築します:
- コントラクトから挨拶を読む
- 挨拶を更新する
- 新しく発行されたトークンを自分のアドレスから別のアドレスに送信する
- 誰かがトークンを受け取った場合、彼らも自分のトークンを他の誰かに送ることができるようにする
- ブロックチェーンにデプロイされたコントラクトからトークン残高を読み取る
前提条件
- あなたのローカルマシンにNode.jsがインストールされていること
- あなたのブラウザにMetaMaskのChrome拡張機能がインストールされていること
このガイド全体にわたって偽物/テストのEtherをテストネットワークで使うため、Ethereumを所有している必要はありません。
はじめに
初めに、新しいReactアプリケーションを作成します:
npx create-react-app react-dapp
次に、新しいディレクトリに移動し、NPMまたはYarnを使用してethers.js
とhardhat
をインストールします:
npm install ethers hardhat @nomiclabs/hardhat-waffle ethereum-waffle chai @nomiclabs/hardhat-ethers
Ethereum開発環境のインストーラと構成
次に、Hardhatによって新しいEthereum開発環境を初期化します:
npx hardhat
README.mdファイルに関するエラーが出た場合、README.mdファイルを削除してコマンドを再実行してください。
これで、以下のアーティファクトがルートディレクトリに作成されるはずです:
hardhat.config.js - Hardhatの設定全部(つまりあなたの設定、プラグイン、カスタムタスク)がこのファイルに含まれています。
scripts - 『sample-script.js』というスクリプトを含むフォルダで、実行時にスマートコントラクトをデプロイします。
test - 例のテストスクリプトを含むフォルダ
contracts - 例のSolidityスマートコントラクトを保持するフォルダ
hardhat.org/metamask-issue.htmlによると、MetaMaskの構成の問題のため、HardHatの設定ではチェーンIDを1337に更新する必要があります。また、コンパイルされたコントラクトのartifactsの場所を、我々のReactアプリのsrcディレクトリ内に更新する必要があります。
これらの更新を行うために、hardhat.config.jsを開いてmodule.exports
を次のように更新します:
module.exports = {
solidity: "0.8.9",
paths: {
artifacts: './src/artifacts',
},
networks: {
hardhat: {
chainId: 1337
}
}
};
私たちのスマートコントラクト
次に、contracts/Greeter.solで与えられた例のコントラクトを見てみましょう:
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
import "hardhat/console.sol";
contract Greeter {
string greeting;
constructor(string memory _greeting) {
console.log("Deploying a Greeter with greeting:", _greeting);
greeting = _greeting;
}
function greet() public view returns (string memory) {
return greeting;
}
function setGreeting(string memory _greeting) public {
console.log("Changing greeting from '%s' to '%s'", greeting, _greeting);
greeting = _greeting;
}
}
これは非常に基本的なスマートコントラクトです。デプロイされたとき、グリーティング変数を設定し、呼び出されたときにグリーティングを返す機能(greet
)を公開します。
また、ユーザー
こちらの記事はdev.toの良い記事を日本人向けに翻訳しています。
https://dev.to/dabit3/the-complete-guide-to-full-stack-ethereum-development-3j13