Hardhatを使う[Astar Network]
概要
- Astar NetworkとEVM
- Hardhatとは何か
- Hardhatでローカルノードにコントラクトをデプロイする
- HardhatでShibuyaテストネットにコントラクトをデプロイする
Astar NetworkとEVM
Astar Networkはレイヤー1のパブリックブロックチェーンです。Polkadotのエコシステムに属しており、Polkadotのパラチェーンとしてリレーチェーンに接合されています。Astar Networkはスケーラビリティ問題の解決を目指すチェーンです。現状2つのバーチャルマシンをサポートし、レイヤー2ソリューションをサポートします。
Astar Networkでは二つのバーチャルマシンをサポートしています。一つはWASMであり、もう一つはEVMです。Astar NetworkのEVMではEthereumのEVMと同じツール、すなわち、MetamaskやHardhatが使えるようにサポートされています。
Hardhatとは何か
以下はHardhatの公式ページの説明を翻訳したものになります。
HardhatはdAppsをコンパイルし、テストし、デバッグするための開発環境です。スマートコントラクトやdApps開発固有の繰り返えされるタスクを管理し、自動化するだけでなく、そのワークフローをより使いやすくします。これによってスマートコントラクトのコンパイル、実行、テストに集中することが出来ます。
HardhatにはHardhatNetworkが内包されています。それは開発のために設計されたローカルなEthereumネットワークです。このネットワークは、Solidityのデバッグ、スタックトレース、console.log()のサポート、トランザクション失敗時の明示的なエラー表示する機能が実装されています。詳細な情報はこちらをご参照下さい。
使ってみた自分の感想を込めて記載すると、EVMでの開発において「慣れるとこれ以外使いたくない」です。最初まだSolidityを書き始めた時はRemixを使っていました。視覚的で非常に分かり易いです。しかし、自分のdAppをある程度本気で実装しようとすると、コマンドラインベースで操作出来、デバッグ機能が豊富に揃っているものが欲しくなります。それがHardhatだと思っています。
Hardhatでローカルノードにコントラクトをデプロイする
まず、環境を作っていきます。OS環境はLinuxベースのコンピュータである前提です。今回の私のチュートリアルはMacOS Monterey 12.1です。
環境構築
まず今回テスト用に使用するディレクトリを作成します。
mkdir hardhat_test
cd hardhat_test
次にHardhatはnpmのアプリなので、npm環境を初期化します。
npm init -y
実行すると以下のような出力がされます。
Wrote to /Users/shin.takahashi/develop/work/work/hardhat_test/package.json:{
"name": "hardhat_test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
次にHardhatをインストールしていきます。
npx hardhat install
上記のような画面が出ますので、一番上の「Create a basic sample project」を選択して、サンプルプロジェクトを作ってみます。
色々と確認が出ますが、基本全てYesで回答して問題ありません。
「Project Created」と出力されれば作成は完了になります。
ローカル用の秘密鍵の設定
ローカルでは開発用のデフォルトの設定で動作するので、特別に設定する必要はないのですが、わかりやすくするために、あえて設定を追加していこうと思います。
以下のファイルを開きます。
vim hardhat.config.js
そして、以下のように設定を追加して下さい。
shin.takahashi@shintakahashinoMacBook-Pro hardhat_test % cat hardhat.config.js
require("@nomiclabs/hardhat-waffle");// This is a sample Hardhat task. To learn how to create your own go to
// https://hardhat.org/guides/create-task.html
task("accounts", "Prints the list of accounts", async (taskArgs, hre) => {
const accounts = await hre.ethers.getSigners();for (const account of accounts) {
console.log(account.address);
}
});// You need to export an object to set up your config
// Go to https://hardhat.org/config/ to learn more// !!!!追加!!!!
const { privateKey } = require('./private.json');/**
* @type import('hardhat/config').HardhatUserConfig
*/
module.exports = {
solidity: "0.8.4",
// !!!!追加!!!!
networks: {
localhost: {
url:"http://localhost:8545",
chainId:31337,
accounts: [privateKey],
}
}};
出来ましたら、次に使用する秘密鍵を定義します。今回は開発用なので、Hardhatがデフォルトで用意している秘密鍵を使います。(当たり前ですが、この秘密鍵にご自身のメインネットの資産を送金したりはしないで下さいね。)
touch private.json
vim private.json
以下のように記載して下さい。
{"privateKey":"0xde9be858da4a475276426320d5e9262ecfc3ba460bfac56360bfa6c4c28b4ee0"}
サンプルコントラクトをデプロイする
準備ができましたので、コントラクトをデプロしていきたいと思いますが、その前にローカルノードを起動しましょう。
npx hardhat node
上記のように秘密鍵が表示されれば起動成功です。
ここで一旦、metamaskを確認してみましょう。先ほど設定した秘密鍵をmetamaskにインポートして下さい。そして、ネットワーク設定を「localhost8545」に接続してみて下さい。10000ETHが確認出来れば、成功です。
デプロイするコントラクトを確認してみましょう。コントラクトはいかにあります。
cat ./contracts/Greeter.sol
非常にシンプルなコントラクトですね。
- constructorの引数で最初の挨拶文を設定します。
- greet関数はチェーン上に保存された挨拶文を出力する関数であり、setGreetingはパラメータに設定した挨拶文をチェーン上に保存する関数ですね。
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;import "hardhat/console.sol";contract Greeter {
string private 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;
}
}
ではデプロイしていきます。サンプルプロジェクトではデプロイ用のスクリプトも用意してくれていますので、それを確認して実行していきます。※以下のファイルはコメントが長いので外してあります。
shin.takahashi@shintakahashinoMacBook-Pro hardhat_test % cat ./scripts/sample-script.js
const hre = require("hardhat");async function main() {
const Greeter = await hre.ethers.getContractFactory("Greeter");
const greeter = await Greeter.deploy("Hello, Hardhat!");await greeter.deployed();console.log("Greeter deployed to:", greeter.address);
}main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
- “Hello Hardhat”を引数にしてconstructorを呼び出しています。
- その後デプロイした結果のコントラクトアドレを出力しています。
以下のコマンドでデプロイします。
npx hardhat run --network localhost scripts/sample-script.js
以下のような出力になります。
hardhat npx node側のコンソールを見ると、デプロイ時のログが出力されているのも確認出来ます。
これでコントラクトのデプロイまで完了しました。
コントラクトを操作してみる
UIを実装していないとコントラクトの操作が出来ないので、Remixが便利だなとやり始めた当初は思ったのですが、Hardhatではコマンドラインから操作が出来ます。
npx hardhat console --network localhost
まず、デプロイ時に登録した挨拶文を表示するところまでやってみます。attachのパラメータはご自身がデプロイしたコントラクトのアドレスを指定して下さい。
const Greet = await ethers.getContractFactory("Greeter");
const greet = await Greet.attach("0x850EC3780CeDfdb116E38B009d0bf7a1ef1b8b38");
await greet.greet();
正常に動作すると以下の画面のようになります。
さらに、setGreeting関数を呼んでブロックチェーンに保存されている挨拶文を変更しましょう。
await greet.setGreeting("Astar Network is so coooooooooool");
await greet.greet();
ローカルノードの操作はここまでで終わりです。ご自身のコントラクトを./contracts配下にSolidityファイルで実装すれば、認識してくれるので、とても便利です。色々やってみて下さい。
HardhatでShibuyaテストネットにコントラクトをデプロイする
今度は今まで使ってきたGreeterコントラクトをShibuyaテストネットにデプロイして動かしていきたいと思います。
まずはじめに設定ファイルを変更して、Shibuyaのテストネットの情報を設定していきます。
Astar Networkのネットワーク情報はこちらに纏まっています。
vim hardhat.config.js
以下のように編集して追加して下さい。
require("@nomiclabs/hardhat-waffle");task("accounts", "Prints the list of accounts", async (taskArgs, hre) => {
const accounts = await hre.ethers.getSigners();for (const account of accounts) {
console.log(account.address);
}
});const { privateKey } = require('./private.json');module.exports = {
solidity: "0.8.4",
networks: {
localhost: {
url:"http://localhost:8545",
chainId:31337,
accounts: [privateKey],
},
// !!!!追加!!!!
shibuya: {
url:"https://rpc.shibuya.astar.network:8545",
chainId:81,
accounts: [privateKey],
}
}};
次にmetamaskの設定をします。
先ほどリンクを掲載したAstar Networkのネットワーク情報を参照して以下のように設定して下さい。
次にコントラクトを操作するためにガス代が必要なので、公式のfaucetからテストネットトークンをもらいましょう。
- 上記で作成したテスト用のアカウントのアドレスをmetamaskからコピーして下さい。
- 次にAstarのDiscordに行きます。
- Discordの「TESTNET-shibuya-faucet」にいき、以下のフォーマットで入力します。
- 「/drip shibuya EOAアドレス」
- /dripまで入力すると、保管機能があるので、それに従って入力してみて下さい。
上記の画面のようになれば成功です。成功したらmetamaskで残高を確認して下さい。
ガス代の準備が出来たので、コントラクトをデプロイしていきたいと思います。
npx hardhat run --network shibuya scripts/sample-script.js
npx hardhat console --network shibuyaconst Greet = await ethers.getContractFactory("Greeter");
const greet = await Greet.attach("0x1ACcBD355245AbA93CE46D33ab1D0152CE33Fd00");
await greet.greet();await greet.setGreeting("Shibuya Testnet is great!");
ローカル時に確認した時と同様の確認が出来ることを確認します。
テストネットなので、Subscanでの確認が可能ですので、コントラクトアドレスから確認してみたいと思います。正直に告白するとSubscanでどこまで確認可能かまだ分かってないのですが、テスト用のアドレスにアクセスして、コントラクトが実行されていることまでは確認できました。
まとめ
今回はHardhatを使って、サンプルのコントラクトをローカルネットワーク、shibuyaテストネットにデプロイするところまでを実施しました。私自身も今Hardhatを使ってEVMのdAppを実装していますが、テストコードの実装機能、デバッグ機能等が充実しており、さらにコマンドラインでの操作が出来て、非常に便利だなと思っています。その辺りの実践編についても今後記事にできたらと思っていますので、引き続きよろしくお願い致します。
ご意見お寄せ下さい
Astar NetworkではAstar Hubという情報サイトを運用しており、各言語であらゆる情報が得られることを目指しています。私は開発者側の情報をもっと充実させ、日本語圏の人がより簡単にAstar Network上の開発に着手出来るようにしたいと考えています。開発関連について「こんなことを知りたい」「こんな手順が知りたい」等ございましたら、ご意見頂けますと優先的に対応させて頂きたいと考えています。(ご期待に添えない場合は申し訳ございません。)
Twitter:@realtakahashi1
Discord:s.takahashi#2365
Telegram:@stakahashi
Astarについて
Astar Network(以前のPlasm Network)はPolkadot上のdAppのハブであり、Ethereum、WebAssembly、Zk-Rollupsのようなレイヤー2ソリューションをサポートします。Astarは複数のブロックチェーンと複数のバーチャルマシンをサポートするマルチチェーン対応のスマートコントラクトプラットフォームになることを目指しています。PolkadotのRelayChainはスマートコントラクトをサポートしません。それこそがPolkadotエコシステム内でdAppを開発したいと願う開発者がスマートコントラクトをサポートしたParaChainを必要とする本質的な理由です。Astarは全ての開発者にEVMをサポートし、かつ、EVMとWASMのスマートコントラクトが共存し互いにコミュニケーション出来るParaChainを作ることによって、最良のソリューションを提供します。