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

lesson-2_スマートコントラクトを実行してみよう

👶 スマートコントラクトを作成してみよう

前回、あらかじめ設定されていたテストのコントラクトを実行できました。

ではいよいよ自分でコントラクトを作成していきましょう。

packages/contract/contractsディレクトリの下にDomains.solという名前のファイルを作成してください。

Hardhatを使用する場合、ファイル構造は非常に重要ですので、注意する必要があります。ファイル構造が下記のようになっていれば大丈夫です 😊

packages
└── contract
└── contracts
└── Domains.sol

次に、コードエディタでプロジェクトのコードを開きます。

ここでは、VS Codeの使用をお勧めします。ダウンロードは こちら から。

VS Codeをターミナルから起動する方法は こちら をご覧ください。

  • ターミナル上で、code .コマンドを実行

今後VS Codeを起動するのが一段と楽になるので、ぜひ導入してみてください。

コーディングのサポートツールとして、VS Code上でSolidityの拡張機能をダウンロードすることをお勧めします。

ダウンロードは こちら から。

それでは、これからDomains.solの中身の作成していきます。

Domains.solをVS Codeで開き、下記を入力します。

// SPDX-License-Identifier: UNLICENSED

pragma solidity ^0.8.17;

import "hardhat/console.sol";

contract Domains {
constructor() {
console.log("THIS IS MY DOMAINS CONTRACT. NICE.");
}
}

コードを詳しくみていきましょう。

// SPDX-License-Identifier: UNLICENSED

これは「SPDXライセンス識別子」と呼ばれ、ソフトウェア・ライセンスの種類が一目でわかるようにするための識別子です。

詳細については、こちら を参照してみてください。

pragma solidity ^0.8.17;

これは、コントラクトで使用するSolidityコンパイラのバージョンです。

上記のコードでは、このコントラクトを実行するときはSolidityコンパイラのバージョン0.8.17のみを使用しそれ以下のものは使用しません、という宣言をしています。

コンパイラのバージョンがhardhat.config.jsで同じであることを確認してください。

もし記載されているSolidityのバージョンが0.8.17でなかった場合は、Domains.solの中身をhardhat.config.jsに記載されているバージョンに変更しましょう。

import "hardhat/console.sol";

コントラクトを実行する際、コンソールログをターミナルに出力するためにHardhatのconsole.solのファイルをインポートしています。

これは、今後スマートコントラクトのデバッグが発生した場合に、とても役立つツールです。

contract Domains{
constructor() {
console.log("THIS IS MY DOMAIN CONTRACT. NICE.");
}
}

contractは、ほかの言語でいうところの「class」のようなものなのです。

このcontractを初期化すると、constructorが実行されてconsole.logの中身がターミナル上に表示されます。

classの概念については、こちら を参照してください。

🔩 constructor とは

constructorはオプションの関数で、contractの状態変数を初期化するために使用されます。

これから詳しく説明していくので、constructorに関しては、まず以下の特徴を理解してください。

  • contractは1つのconstructorしか持つことができません。
  • constructorは、スマートコントラクトの作成時に一度だけ実行され、contractの状態を初期化するために使用されます。
  • constructorが実行された後、コードがブロックチェーンにデプロイされます。

😲  コントラクトを実行しましょう

さぁ、スマートコントラクトを作成しました。

しかし、まだそれが機能するかどうかはわかりません。

実際に実行してみましょう。次のような手順となります。

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

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

前に挙げた3つのステップを処理するスクリプトを作成します。

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

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

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

const main = async () => {
const domainContractFactory = await hre.ethers.getContractFactory("Domains");
const domainContract = await domainContractFactory.deploy();
await domainContract.deployed();
console.log("Contract deployed to:", domainContract.address);
};

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

runMain();

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

const domainContractFactory = await hre.ethers.getContractFactory("Domains");

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

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

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

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

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

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

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

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

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

const domainContract = await domainContractFactory.deploy();

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

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

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

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

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

await domainContract.deployed();

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

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

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

console.log("Contract deployed to:", domainContract.address);

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

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

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

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

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

💨  実行してみよう

ターミナル上で、下記を実行してみましょう。

yarn contract run:script

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

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

Compiled 1 Solidity file successfully
THIS IS MY DOMAINS CONTRACT. NICE.
Contract deployed to: 0x5FbDB2315678afecb367f032d93F642f64180aa3

🎩 Hardhat Runtime Environment について

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

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

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

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

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

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

🙋‍♂️ 質問する

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

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

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

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