【Solidity】Hardhatの環境構築(入門)
はじめに
突然ですが、今週のETH Global Tokyo頑張りましょう!ということで…
Solidityのスマートコントラクト開発でHardhatをよく利用しますよね🚧
毎回流れ作業になってるんですが、2週間ぐらい空くと「えー…っと」と手が止まって、Notionの個人用に残してる開発ノートを見返さなきゃいけなくなります。ノート自体があまり整理されていないので探すのが面倒です。
したがって、今回は自分の整理も含めて、パパっと開発環境を整えるメモを残しておこうと思います。
コードの説明ではなく、手順の方法を記載していきますので、はじめての方でも参考になると思います!(ならなかったらごめんなさい🙇)
前提
前提知識
下記の知識はあるものとして説明します。バージョンが合わない場合は、それぞれバージョンを確認してみてください。
- WSL2
- EVM
- Node.js
- npm
$ npm -v
$ node -v
Node.jsとnpmの導入
もしNode.jsもnpmもインストールされていない!って方はこちらの記事が参考になります!
環境構築
1. ディレクトリ作成
test-contract
というディレクトリを作成してみます。
mkdir test-contract
cd test-contract
2. 初期化
初期化を行って、package.json
を準備します。今回はデフォルト値を使います。
npm init -y
3. Hardhatの導入
- npmでhardhatパッケージをインストールする
npm install hardhat --save-dev
- インストールが終わったら下記のコマンドを実行する
npx hardhat
- プロジェクトを作成する
今回はJavaScriptを採用し、すべてエンターを押していきます。各自選択してください。
888 888 888 888 888
888 888 888 888 888
888 888 888 888 888
8888888888 8888b. 888d888 .d88888 88888b. 8888b. 888888
888 888 "88b 888P" d88" 888 888 "88b "88b 888
888 888 .d888888 888 888 888 888 888 .d888888 888
888 888 888 888 888 Y88b 888 888 888 888 888 Y88b.
888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888
Welcome to Hardhat v2.13.0
? What do you want to do? …
▸ Create a JavaScript project
Create a TypeScript project
Create an empty hardhat.config.js
Quit
✔ What do you want to do? · Create a JavaScript project
✔ Hardhat project root: · /home/username/test-contract
✔ Do you want to add a .gitignore? (Y/n) · y
✔ Do you want to install this sample project's dependencies with npm (@nomicfoundation/hardhat-toolbox)? (Y/n) · y
- ファイルを確認する
ここまでで下記のような構造ができていると思います。
test-contract
├── contracts
│ └── Lock.sol
├── node_modules
├── scripts
│ └── deploy.js
├── test
│ └── Lock.js
├── .gitignore
├── hardhat.config.js
├── package-lock.json
├── package.json
└── README.md
- コンパイルしてテストを実行する
動作を確認してみます。
$ npx hardhat compile
Compiled 1 Solidity file successfully
$ npx hardhat test
Lock
Deployment
✔ Should set the right unlockTime (1248ms)
✔ Should set the right owner
✔ Should receive and store the funds to lock
✔ Should fail if the unlockTime is not in the future
Withdrawals
Validations
✔ Should revert with the right error if called too soon
✔ Should revert with the right error if called from another account
✔ Shouldn't fail if the unlockTime has arrived and the owner calls it
Events
✔ Should emit an event on withdrawals
Transfers
✔ Should transfer the funds to the owner
9 passing (1s)
4. .envファイルの設定
テストネットへデプロイする際にウォレットの秘密鍵やノードプロバイダーのAPI KEYが必要になりますので、.env
ファイルにて環境変数を管理していきます。
- npmでdotenvパッケージをインストールする
npm install dotenv --save-dev
- Hardhatプロジェクト直下に
.env
ファイルを作成する
test-contract
├── artifacts
├── cache
├── contracts
│ └── Lock.sol
├── scripts
│ └── deploy.js
├── test
│ └── Lock.js
├── .env <--- Creation
├── .gitignore
├── hardhat.config.js
├── package-lock.json
├── package.json
└── README.md
-
.env
ファイルに必要な項目を入力する
PRIVATE_KEY
には利用するウォレットの秘密鍵を入力します。次に、ノードプロバイダーは今回はalchemyを採用しますので、ALCHEMY_KEY
にはHTTPSのAlchemy API URLを入力します。ついでに.env
ファイルの設定の例を記入する.env.example
ファイルも作成しておくと便利です。
PRIVATE_KEY = "YOUR_PRIVATE_KEY"
ALCHEMY_KEY = "https://network.g.alchemy.com/v2/your-api-key"
PRIVATE_KEY = ""
ALCHEMY_KEY = ""
Create and Deploy your Smart Contract using Hardhat
5. hardhat.config.jsファイルの設定
hardhat.config.js
を開き、Goerliを想定する設定を記入していきます。各自、利用するネットワークを記入してください。
solidity
のバージョンはコントラクトで指定したバージョンを記入します。
また、ライブラリを導入した際に設定をこちらに記入していくことになります。
require("@nomicfoundation/hardhat-toolbox");
/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
solidity: "0.8.18",
networks: {
goerli: {
url: process.env.ALCHEMY_KEY,
accounts: [process.env.PRIVATE_KEY],
},
},
};
ライブラリの導入
その他、必要なライブラリを導入していきます。
hardhat-gas-reporterの導入
スマートコントラクトをデプロイする際のガス代やそれぞれの関数を実行した際のガス代を計測してくれるHardhat用のガスレポーターです。
npx hardhat test
を実行するとガス使用料を計算してくれます。とても便利です。
npm install hardhat-gas-reporter --save-dev
OpenZeppelinの導入
OpenZeppelinは精査された安全なスマートコントラクトを提供するオープンなライブラリです。必要に応じてインストールします。ご覧の通り、利用も非常に簡単です。
npm install @openzeppelin/contracts
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
デプロイ
scripts/deploy.js
を書き上げて、ネットワークに合わせて下記のコマンドを実行します。
npx hardhat run scripts/deploy.js --network your-network
npx hardhat run scripts/deploy.js --network goerli
npx hardhat run scripts/deploy.js --network mainnet
検証
GoerliのEtherscanを想定してみます。下記の画面のように緑のチェックマークがEtherscanで表示されれば成功です。
1. hardhat-etherscanの導入
npm install @nomiclabs/hardhat-etherscan
2. Etherscanで検証する
- Etherscan.ioからAPIを取得する
-
.env
ファイルにETHERSCAN_KEY
として記載する
PRIVATE_KEY = ""
ALCHEMY_KEY = ""
ETHERSCAN_KEY = "YOUR_ETHERSCAN_API_KEY"
-
hardhat.config.js
ファイルに設定を追記する
module.exports = {
networks: {
mainnet: { ... }
},
etherscan: {
// Your API key for Etherscan
// Obtain one at https://etherscan.io/
apiKey: process.env.ETHERSCAN_KEY
}
};
- 下記に従って検証のコマンドを実行する
A. 対象となるコントラクトのconstructor
がない、もしくは引数がない場合
B. 対象となるコントラクトのconstructor
に引数がある場合
contract TypeA is ERC721 {
constructor() ERC721("Gm NFT", "GMNFT") {}
...
}
contract TypeB is ERC721 {
constructor(string memory name_, string memory symbol_) ERC721(name_, symbol_) {}
...
}
A. constructorがない、もしくは引数がない場合
npx hardhat verify --network goerli your-contract-address
npx hardhat verify --network goerli 0x8a90CAb2b38dba80c64b7734e58Ee1dB38B8992e
B. constructorに引数がある場合
-
args.js
ファイルを作成する
test-contract
├── artifacts
├── cache
├── contracts
│ └── Lock.sol
├── scripts
│ └── deploy.js
├── test
│ └── Lock.js
├── .env
├── .gitignore
├── args.js <---
├── hardhat.config.js
├── package-lock.json
├── package.json
└── README.md
- スマートコントラクトの
constructor
に対応する引数を入力する
module.exports = [
"Argument 1",
"Argument 2",
"Argument 3",
]
- 検証のコマンドを実行する
npx hardhat verify --network goerli your-contract-address --constructor-args args.js
npx hardhat verify --network goerli 0x8a90CAb2b38dba80c64b7734e58Ee1dB38B8992e --constructor-args args.js
まとめ
初心者でもかなり簡単にスマートコントラクトをデプロイすることができたと思います!
今週はETH Global Tokyoがありますので、皆さんでガシガシコードを書いて頑張っていきましょう!
会場で見かけたらぜひ声をかけてくださーい!@yuk6ra
参考文献
Discussion