day22では、デプロイまで実行しました。このガイドでは、デプロイされたコントラクトへの操作を実際に行い、正しくデプロイされていることを確認していきます。
デプロイ結果の確認
確認するためには、以下のものが必要となります。
- ローカルネット: hardhatによって提供されるローカルネットワーク環境です。hardhatのコマンドを実行するとすぐに利用可能な状態になります。2のデジタルウォレットからこのネットワークにある情報を閲覧できるようにするために、ローカルネット向けのRPCノードの設定をMetamaskで行います。
- デジタルウォレット(Metamask): ローカルネットは擬似的なアカウントが用意されます。各アカウントのETH残高を確認するためにデジタルウォレットにアカウント情報をインポートします。これによって、各操作の結果、ETH残高がどのように推移するかを確認することができます。
- 確認用スクリプト: 開発したコントラクトの関数を呼び出すためのスクリプトで、hardhatから実行することが可能です。Fundingコントラクトを例にすると、fund(投資)を実行したり、withdraw(引き出し)を実行したりするためのものです。
確認のためのローカル環境設定
まずは、前項の1, 2の設定(確認環境の準備)を行います。
ローカルネット向けRPCノードの設定
利用しているブラウザのMetamaskのプラグインから、設定 > ネットワーク > ネットワークを追加
を順番に選択します。
続けて表示される画面でネットワークを手動で追加を選択し、次の画像のような情報を入力します。これらはローカルネットにおけるRPCノードの設定情報になります。URLはローカルネットのRPCノードのURL、チェーンIDも同様にローカルネット上のものです。
ローカルネットの起動
ローカルネットは、hardhatによって提供されます。次の形式のコマンドをコンソール上で実行すると、起動します。
% yarn hardhat node
ローカルネットのアカウント情報のimport
ローカルネットを起動すると、次の画像のように複数のアカウントが自動でセットアップされます。これらのアカウントの情報を見るすべはこのままではないので、Metamaskから見れるようにする必要があります。
そのためには、コンソールに表示されるアカウントのプライベートキーをMetamask上でインポートする必要があります。例えば、Account #0および#1のPrivate Keyの値をインポートします。
確認用スクリプト
ここでは、2つの確認用スクリプトを開発します。
対象のコントラクトは、day17で実装したものになります。
- fund.ts:
fund
関数を実行するスクリプト。実行するアカウントの残高がfundの金額分引かれる。 - withdraw.ts:
withdraw
関数を実行するスクリプト。コントラクトをデプロイしたオーナーのみ実行でき、コントラクトの残高をすべて引き落とすことができる。
fund.ts
// scripts/fund.ts
const { ethers, getNamedAccounts, deployments } = require("hardhat");
async function main() {
const {user} = await getNamedAccounts()
console.log(deployer)
const funding = await ethers.getContract("Funding", user)
const fundingAddress = await funding.getAddress()
console.log(`Got contract Funding at ${fundingAddress}`)
console.log("Funding contracct...")
const txnResponse = await funding.fund({
value: ethers.parseEther("1"),
})
await txnResponse.wait()
console.log("Funded!")
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error)
process.exit(1)
})
// scripts/fund.ts(抜粋)
const { user} = await getNamedAccounts()
day22同様に、importしたgetNamedAccounts
関数を使って、hardhat.config.tsに設定されているアカウント情報を取得します。今回は、userの方を取得します(アカウントリストの1番目が設定されています)。
// scripts/fund.ts(抜粋)
const funding = await ethers.getContract("Funding", user)
const fundingAddress = await funding.getAddress()
getContract
関数は、コントラクト名と実行ユーザーの2つの引数を取ります。すでにday22でデプロイしたFunding
コントラクトのインスタンスをuser
アカウントで実行するために取得します。
このコントラクトのアドレスを取得した場合は、取得したコントラクトfunding
変数からgetAddress
を実行すると得ることができます。
// scripts/fund.ts(抜粋)
const txnResponse = await funding.fund({
value: ethers.parseEther("1"),
})
await txnResponse.wait()
取得したコントラクトのインスタンス(funding
変数)からは、元々のスマートコントラクトで定義されている関数やメンバーを呼ぶことができます。fund
関数は、day17にもある通り、Funding.solで定義されている関数になります。
ここで{ value: ethers.parseEther("1") }
は、fund
関数に送られるEtherの量を指定します。このコードでは、1 Etherをfund
関数に送っています。ethers.parseEther()
関数は、Etherの数をWei(Etherの最小単位)の形のBigNumberに変換します。
txnResponse.wait()
は、トランザクションがマイニングされるのを待つことを表します。
※ Funding.solのfund
関数では引数は定義されていないですが、送金額をこのように指定することが可能です。これは、Solidityにおいては、msg.sender(送信者)やmsg.value(送信する金額)といった変数は、グローバル変数として定義されているためです。そのため、関数を定義する際には、これらの変数は明示的に定義する必要はありません。
// scripts/fund.ts(抜粋)
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error)
process.exit(1)
})
この部分のコードは、main()
関数の実行が成功したかどうかに応じてプロセスの終了コードを決定するものです。
main().then(() => process.exit(0))
: これは、main()
関数が成功裏に終了した場合に実行されます。ここでは、終了コード0
を返しています。シェルスクリプトやコマンドラインアプリケーションでは、終了コード0
は成功を意味します。main().catch((error) => { console.error(error); process.exit(1); })
: これは、main()
関数が何らかの理由でエラーを投げた場合に実行されます。エラー情報はコンソールに出力され、その後終了コード1
でプロセスが終了します。終了コード1
は一般的にエラーを示します。
withdraw.ts
// scripts/withdraw.ts
import { error } from "console"
const { ethers, getNamedAccounts } = require("hardhat")
async function main() {
const {deployer} = await getNamedAccounts()
const funding = await ethers.getContract("Funding", deployer)
const fundingAddress = await funding.getAddress()
console.log(`Get contract funding at ${fundingAddress}`)
console.log("Withdrawing from contract...")
const txnResponse = await funding.withdraw()
await txnResponse.wait()
console.log("Got it back!")
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.log(error)
process.exit(1)
})
コードとしては、fund.tsと同じ機能を使ったものばかりになります。実行する際は、deployerアカウント(コントラクトをデプロイしたオーナーと同一)を使っています。
確認スクリプトの実行
ローカルネットを起動させた状態で、同じくVS Codeのコンソールからスクリプトを実行します。
- fund.tsを実行する(user(アカウント#1)から1 ETHがコントラクトに送付される)。
アカウント#1の残高が減少している(実行の前後でMetamaskで残高を確認する) - withdraw.tsを実行する(deployer(アカウント#0)によってコントラクトからコントラクトの残高が引き出される)。
アカウント#0の残高が増加している(実行の前後でMetamaskで残高を確認する)
スクリプトの実行は以下のような形式で行うことができます。runに続けて、スクリプト名を指定し、また、networkオプションに続けてネットワーク名を指定します。ここでは、ローカルネットでの実行なので、ローカルホストを指定します。
yarn hardhat run scripts/withdraw.ts --network localhost
以下に、fund.tsの実行例を示します。
ご意見をお聞かせください!
この記事、または、web3チュートリアル全体について、是非、あなたのご意見をお聞かせください。
アンケートはこちらからご回答いただけます。
無料相談承ります
オンラインでの無料相談を承っています。ご希望の方は、お問い合わせフォームよりご連絡ください。
ITの専門家があなたのご質問にお答えいたします。
Comments