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 } = hre
getNamedAccounts
: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