メインコンテンツまでスキップ

lesson-3_コントラクトをローカル環境でコンパイルして実行しよう

🔥 スマートコントラクトをローカル環境で実行しよう

前回のレッスンでは、WavePortal.solというスマートコントラクトを作成しました。

今回のレッスンでは下記を実行します。

  1. WavePortal.solをコンパイルします。
  2. WavePortal.solをローカル環境でブロックチェーン上にデプロイします。
  3. 上記が完了したら、console.logの中身がターミナル上に表示されることを確認します。

このプロジェクトの最終ゴールは、あなたのスマートコントラクトをブロックチェーン上にのせ、あなたのWebアプリケーションを介して世界中の人々がそのスマートコントラクトにアクセスできる状態を実現することです。

まずは、上記の作業をローカル環境で行います。

📝 コントラクトを実行するためのプログラムを作成する

scriptsディレクトリに移動し、run.jsという名前のファイルを作成してください。

run.jsはローカル環境でスマートコントラクトのテストを行うためのプログラムです。

run.jsの中身に、以下を記入しましょう。

const main = async () => {
const waveContractFactory = await hre.ethers.getContractFactory("WavePortal");
const waveContract = await waveContractFactory.deploy();
const wavePortal = await waveContract.deployed();

console.log("WavePortal address: ", wavePortal.address);
};

const runMain = async () => {
try {
await main();
process.exit(0);
} catch (error) {
console.log(error);
process.exit(1);
}
};

runMain();

それでは、1行ずつコードの理解を深めましょう。

const waveContractFactory = await hre.ethers.getContractFactory("WavePortal");

これにより、WavePortalコントラクトがコンパイルされます。

コントラクトがコンパイルされたら、コントラクトを扱うために必要なファイルがartifactsディレクトリの直下に生成されます。

✍️: hre.ethers.getContractFactoryについて getContractFactory関数は、デプロイをサポートするライブラリのアドレスとWavePortalコントラクトの連携を行っています。

hre.ethersは、Hardhat プラグインの仕様です。

✍️: const main = async ()awaitについて Javascript でコードを書いていると、コードの上から順に実行されなくて困ることがあります。これを非同期処理に関する問題といいます。

解決法の一つとして、ここではasync / awaitを使用します。

これを使うと、awaitが先頭についている処理が終わるまで、main関数の他の処理は行われません。

つまり、hre.ethers.getContractFactory('WavePortal')の処理が終わるまで、main関数の中に記載されている他の処理は実行されないということです。

次に、下記の処理を見ていきましょう。

const waveContract = await waveContractFactory.deploy();

HardhatがローカルのEthereumネットワークを、コントラクトのためだけに作成します。

そして、スクリプトの実行が完了した後、そのローカル・ネットワークを破棄します。

つまり、コントラクトを実行するたびに、毎回ローカルサーバーを更新するかのようにブロックチェーンが新しくなります。

  • 常にゼロリセットとなるので、エラーのデバッグがしやすくなります。

次に下記の処理を見ていきましょう。

const wavePortal = await waveContract.deployed();

ここでは、WavePortalコントラクトが、ローカルのブロックチェーンにデプロイされるまで待つ処理を行っています。

Hardhatは実際にあなたのマシン上に「マイナー」を作成し、ブロックチェーンを構築してくれます。

constructorは、コントラクトがデプロイされるときに初めて実行されます。

最後に、下記の処理を見ていきましょう。

console.log("WavePortal address:", wavePortal.address);

最後に、デプロイされると、wavePortal.addressはデプロイされたコントラクトのアドレスを出力します。

このアドレスから、ブロックチェーン上でコントラクトを見つけることができますが、今回はローカルのイーサリアムネットワーク(=ブロックチェーン)に実装しているため、世界中の人がアクセスできるわけでありません。

一方、イーサリアムメインネット上のブロックチェーンにデプロイしていれば、世界中の誰でもコントラクトにアクセスできます。

実際のブロックチェーン上には、すでに何百万ものスマートコントラクトがデプロイされています。

アドレスさえわかれば、世界中どこにいても、私たちが興味を持っているコントラクトに簡単にアクセスできます。

🪄 実行してみよう

packages/contract/package.jsonscript部分を以下のように編集してください。

  "scripts": {
"run:script": "npx hardhat run scripts/run.js",
"test": "npx hardhat test",
"deploy": "npx hardhat run scripts/deploy.js --network sepolia"
},

その後ルートディレクトリにいることを確認して、ターミナル上で下記を実行してみましょう。

yarn contract run:script

ターミナル上でconsole.logの中身とコントラクトアドレスが表示されていることを確認してください。

例)ターミナル上でのアウトプット:

Compiled 2 Solidity files successfully
Here is my first smart contract!
WavePortal address: 0x5FbDB2315678afecb367f032d93F642f64180aa3

上記のようなアウトプットターミナルに表示されていればテストは成功です。

🎩 Hardhat Runtime Environment について

run.jsの中で、hre.ethersが登場します。

しかし、hreはどこにもインポートされていません。それはなぜでしょうか?

それは、ずばり、HardhatがHardhat Runtime Environment(HRE)を呼び出しているからです。

HREは、Hardhatが用意したすべての機能を含むオブジェクト(=コードの束)です。

hardhatで始まるターミナルコマンドを実行するたびに、HREにアクセスしているので、hrerun.jsにインポートする必要はありません。

詳しくは、Hardhat 公式ドキュメント(英語) にて確認できます。

🙋‍♂️ 質問する

ここまでの作業で何かわからないことがある場合は、Discordの#ethereumで質問をしてください。

ヘルプをするときのフローが円滑になるので、エラーレポートには下記の3点を記載してください ✨

1. 質問が関連しているセクション番号とレッスン番号
2. 何をしようとしていたか
3. エラー文をコピー&ペースト
4. エラー画面のスクリーンショット

ターミナル上にconsole.logの中身とコントラクトアドレスを出力できたら、次のレッスンに進んでください 🎉