Hardhat自体はデプロイの機能は提供していませんが、hardhat-deployなどのプラグインを用いるとデプロイのタスクを容易に作成することができます。ここでは、実際のデプロイスクリプトについて解説します。
day17で実装したFundingコントラクトを実装するためのスクリプトを見ていきます。
デプロイスクリプト
早速ですが、実際のデプロイスクリプトの例を見てみます。
// deploy/01-deploy-funding.ts
import { HardhatRuntimeEnvironment } from "hardhat/types"
import { DeployFunction } from "hardhat-deploy/types"
import { developmentChains } from "../helpder-hardhat-config"
import { networkConfig } from "../helpder-hardhat-config"
import verify from "../scripts/verify"
const deployFunding: DeployFunction = async function (
hre: HardhatRuntimeEnvironment,
) {
const { getNamedAccounts, deployments, network } = hre
const { deploy, log } = deployments
const { deployer } = await getNamedAccounts()
log("-----------------------------------------------------")
log("Deploying Funding and waiting for confirmations...")
const funding = await deploy("Funding", {
from: deployer,
args: [],
log: true,
waitConfirmations: networkConfig[network.name].blockConfirmations || 0,
})
log(`Funding deployed at ${funding.address}`)
if (
!developmentChains.includes(network.name) &&
process.env.ETHERSCAN_API_KEY
) {
await verify(funding.address, [])
}
}
export default deployFunding
deployFunding.tags = ["all", "funding"]
このスクリプトでは、Fundingというコントラクトをデプロイしています。デプロイには、deploy関数を使っています。
hre, getNamedAccounts, deployments, network
11行目のコードのhre(HardhatRuntimeEnvironment)はhardhat/typesでエクスポートされているもので、Hardhatの実行環境を表します。このhreという変数を通じて、Hardhatの実行環境で提供される機能にアクセスすることができます。例えば、左側で定義されている3つの変数は、このhreで定義されているプロパティ(機能)を表しています。
// deploy/01-deploy-funding.ts (抜粋)
const { getNamedAccounts, deployments, network } = hregetNamedAccounts:hardhat-deployプラグインが提供する関数で、設定ファイル(hardhat.config.ts)で名前を付けたアカウントのリストを取得します。各ネットワークに対して名前付きアカウントを設定することができ、これを使うことでスクリプトの中でアカウントを簡単に参照することができます。例えば、デプロイするアカウントをdeployerとして設定した場合、getNamedAccountsを使って{ deployer }という形でアカウントを取得できます。deployments:hardhat-deployプラグインが提供するオブジェクトで、デプロイ関連の操作を行うためのメソッドを提供します。具体的には、スマートコントラクトのデプロイ (deployメソッド)、デプロイ済みのスマートコントラクトの取得 (getメソッド)、デプロイ済みのすべてのスマートコントラクトの取得 (allメソッド)、などが可能です。また、デプロイ中の内容をコンソール出力するための関数、logも含まれます。network: は現在選択されているネットワークとその設定に関連する情報や機能を提供します。name(ネットワーク名)、 config(ネットワークの設定: RPC URL, chain idなど。詳細はday21も参照すると分かりやすいです。)
上記を踏まえて、11、12行目を参照すると実際にgetNamedAccounts, deploymentsからそれぞれ、deploy, deployerを取得しています。deployは実際にデプロイを行うための処理を実行する関数で、deployerは、deployを実行する際に利用するユーザーです(そして、このアカウントは、設定ファイルで定義しています。day21の51行目以降のnamedAccountsの箇所)。
// deploy/01-deploy-funding.ts (抜粋)
const { deploy, log } = deployments
const { deployer } = await getNamedAccounts()deploy関数
実際のデプロイは16行目で行われています。これまでで読み込んだdeploy関数が実際に実行されている箇所になります。
// deploy/01-deploy-funding.ts (抜粋)
const funding = await deploy("Funding", {
from: deployer,
args: [],
log: true,
waitConfirmations: networkConfig[network.name].blockConfirmations || 0,
})deploy関数では、次に記載するような引数を取得します。
name: デプロイするコントラクトの名前です。これは一意でなければならず、特定のコントラクトのデプロイメントを参照するために使用されます。from: トランザクションを送信するアカウントのアドレスです。このアカウントがコントラクトのデプロイメントに必要なガスを支払います。args: コントラクトのコンストラクタに渡す引数の配列です。つまり、開発したスマートコントラクトのコンストラクタの仕様に併せて、引数を定義します。log: trueに設定すると、デプロイメントの詳細がコンソールにログとして出力されます。waitConfirmations: ブロックチェーンでは、該当のトランザクションがブロックに含まれ、ネットワークによって検証されると、「確認」されたことになります。この設定項目は、確認の数を指定します(確認が多いほど、そのトランザクションが改ざんされる可能性は低くなります。しかし、多くの確認を待つことは、それだけデプロイメントが完了するまでの時間を長くする)
veirfy
次のソースは、Etherscanに検証を依頼している箇所になります。実際に、検証を依頼しているのは、verify関数の部分になりますが、これは、別のファイルとして、scriptsの下にverify.tsというファイルを配置して使っています。
// deploy/01-deploy-funding.ts (抜粋)
if (
!developmentChains.includes(network.name) &&
process.env.ETHERSCAN_API_KEY
) {
await verify(funding.address, [])
}// scripts/verify.ts
import { run } from "hardhat"
const verify = async (contractAddress: string, args: any[]) => {
console.log("Verifying contract...")
try {
await run("verify:verify", {
address: contractAddress,
constructorArguments: args,
})
} catch (e: any) {
if (e.message.toLowerCase().includes("already verified")) {
console.log("Already verified!")
} else {
console.log(e)
}
}
}
export default verify
7行目のrun関数は、hardhatによって提供されるもので、hardhatのタスクを実行することができます。Hardhatのタスクをプログラム的に実行するための関数です。Hardhatには、コンパイルやテスト、デプロイなどのための標準的なタスクがいくつか含まれており、これらのタスクはhardhatコマンドラインツールを使って手動で実行することができます。しかし、これらのタスクをスクリプト内から直接呼び出すこともできます。それがrun関数の役割です。
基本的な使用方法は以下のような形式となります。上記の例では、検証(verify:verify)タスクを実行しています。引数としては、デプロイしたコントラクトのアドレスとコントラクトのコンストラクターの引数を取ります(17行目でデプロイした結果としてデプロイしたコントラクトを取得していますが(funding)、funding.addressとすることでデプロイしたコントラクトのアドレスが取得できます)。
await hre.run('taskName', taskArguments)run関数を実行する部分は、try~catchで囲われており、tryで試行しているrun関数の実行がうまく行かなかった場合、catch以降でエラーを取得し、コンソールへのエラー出力を行っています。
export
// deploy/01-deploy-funding.ts (抜粋)
export default deployFunding
deployFunding.tags = ["all", "funding"]TypeScriptのexport文は、モジュールから関数、オブジェクト、値、型などをエクスポート(公開)するために使います。これにより、他のモジュールからimport文を使ってエクスポートしたエンティティを利用することができます。上記の例では、先に定義されているdeployFunding関数を公開し、利用できるようにしています。
続けて次の部分では、デプロイを実行する際のオプションを定義しています。オプションとして--tags allとした場合、allのタグがついている関数が実行されます。--tags fundingとした場合、fundingのタグがついている関数が実行されます(例えば、複数のデプロイスクリプトからデプロイが構成されている場合、全て実行するか、特定のデプロイスクリプトだけ実行するかといったことを指定することができます)。
デプロイスクリプトの実行
次に実際にローカルでデプロイを実行してみます。
# console
% yarn hardhat deploy --network hardhat --tags all
yarn run v1.22.19
$ /Users/username/code/token-village/funding/node_modules/.bin/hardhat deploy --tags all
Generating typings for: 1 artifacts in dir: typechain-types for target: ethers-v6
Successfully generated 6 typings!
Compiled 1 Solidity file successfully
-----------------------------------------------------
Deploying Funding and waiting for confirmations...
deploying "Funding" (tx: 0xbc444ca6c542123b21a0f1a3515a8d8f2f43b980f8e747417596779369851eda)...: deployed at 0x5FbDB2315678afecb367f032d93F642f64180aa3 with 538126 gas
Funding deployed at 0x5FbDB2315678afecb367f032d93F642f64180aa3
✨ Done in 6.67s.
%デプロイは次のような形式で実行することができます。
% yarn hardhat deploy --network Network-Name [--tags Tag-Name]networkオプションには、ネットワーク(ローカル(hardhat)、テストネット(sepoliaなど)、メインネット(mainnet))を指定します。mainnet以外のネットワークについては、hardhat.config.tsで定義されている必要があります(設定については、day21参照)。
ご意見をお聞かせください!

この記事、または、web3チュートリアル全体について、是非、あなたのご意見をお聞かせください。
アンケートはこちらからご回答いただけます。
無料相談承ります

オンラインでの無料相談を承っています。ご希望の方は、お問い合わせフォームよりご連絡ください。
ITの専門家があなたのご質問にお答えいたします。

Comments