目次

Hardhatを使ったスマートコントラクト開発

ほぼ Hardhat オフィシャルのドキュメント通りに Hardhat を使ってみます。

前提

npm をインストールしておいてください。

インストール

:!: 下記「npx hardhat」コマンドを実行すると「What do you want to do?」と聞かれますので、今回は「Create a basic sample project」で作業を進めます。それ以外はデフォルトのままエンターを入力してください。

> mkdir hardhat_project
> cd hardhat_project
hardhat_project> npx hardhat
Need to install the following packages:
  hardhat
Ok to proceed? (y) y
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.9.3
 
? What do you want to do? …
❯ Create a basic sample project
  Create an advanced sample project
  Create an advanced sample project that uses TypeScript
  Create an empty hardhat.config.js
  Quit
 
√ What do you want to do? · Create a basic sample project
√ Hardhat project root: · C:\Users\shinobu\NoNameSeminer\ethereum\hardhat_project
√ Do you want to add a .gitignore? (Y/n) · y
√ Help us improve Hardhat with anonymous crash reports & basic usage data? (Y/n) · true
 
You need to install these dependencies to run the sample project:
  npm install --save-dev "hardhat@^2.9.3" "@nomiclabs/hardhat-waffle@^2.0.0" "ethereum-waffle@^3.0.0" "chai@^4.2.0" "@nomiclabs/hardhat-ethers@^2.0.0" "ethers@^5.0.0"
 
Project created
See the README.md file for some example tasks you can run. 

上記の最後で指定された通り、必要な npm パッケージをインストールします。

hardhat_project> npm install --save-dev "hardhat@^2.9.3" "@nomiclabs/hardhat-waffle@^2.0.0" "ethereum-waffle@^3.0.0" "chai@^4.2.0" "@nomiclabs/hardhat-ethers@^2.0.0" "ethers@^5.0.0"

生成されたファイルを確認してみます。

hardhat_project> ls
 
 
    ディレクトリ: C:\Users\shinobu\NoNameSeminer\ethereum\hardhat_project
 
 
Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----        2022/05/11     13:34                contracts
d-----        2022/05/11     13:43                node_modules
d-----        2022/05/11     13:34                scripts
d-----        2022/05/11     13:34                test
-a----        2022/05/11     13:34             83 .gitignore
-a----        2022/05/11     11:16            572 hardhat.config.js
-a----        2022/05/11     13:43         863535 package-lock.json
-a----        2022/05/11     13:43            249 package.json
-a----        2022/05/11     11:16            467 README.md

Hardhat のバージョンとコマンドの仕様を確認してみます。

hardhat_project> npx hardhat        
Hardhat version 2.9.3
 
Usage: hardhat [GLOBAL OPTIONS] <TASK> [TASK OPTIONS]
 
GLOBAL OPTIONS:
 
  --config              A Hardhat config file.
  --emoji               Use emoji in messages.
  --help                Shows this message, or a task's help if its name is provided
  --max-memory          The maximum amount of memory that Hardhat can use.
  --network             The network to connect to.
  --show-stack-traces   Show stack traces.
  --tsconfig            A TypeScript config file.
  --verbose             Enables Hardhat verbose logging
  --version             Shows hardhat's version.
 
 
AVAILABLE TASKS:
 
  check         Check whatever you need
  clean         Clears the cache and deletes all artifacts
  compile       Compiles the entire project, building all artifacts
  console       Opens a hardhat console
  flatten       Flattens and prints contracts and their dependencies
  help          Prints this message
  node          Starts a JSON-RPC server on top of Hardhat Network
  run           Runs a user-defined script after compiling the project
  test          Runs mocha tests
 
To get help for a specific task run: npx hardhat help [task]

コンパイル

Hardhat セットアップ時に自動的に作成されている contracts/Greeter.sol をコンパイルします。

hardhat_project> npx hardhat compile

テスト

Hardhat セットアップ時に自動的に作成されている test/sample-test.js を使って Greeter スマートコントラクトのテストを行います。

hardhat_project> npx hardhat test
 
 
  Greeter
Deploying a Greeter with greeting: Hello, world!
Changing greeting from 'Hello, world!' to 'Hola, mundo!'
    ✔ Should return the new greeting once it's changed (1328ms)
 
 
  1 passing (1s)

node の起動

Hardhat を Ganache や ganache-cli のように ethereum ブロックチェーン(node)を起動することができます。 ethereum ブロックチェーンにスマートコントラクトをデプロイし、Hardhat 外部からも連携ができるように、ethereum ブロックチェーンを起動します。

新たなターミナル(PowerShell等)を起動し、以下のコマンドで node を起動してください。

hardhat_project> npx hardhat node

Hardhat の node には固定で以下のアカウントが自動作成されます。これは毎回同じアドレスであるため、以下の情報も毎回利用できます。

Accounts
========

WARNING: These accounts, and their private keys, are publicly known.
Any funds sent to them on Mainnet or any other live network WILL BE LOST.

Account #0: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 (10000 ETH)
Private Key: 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80

Account #1: 0x70997970c51812dc3a010c7d01b50e0d17dc79c8 (10000 ETH)
Private Key: 0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d

Account #2: 0x3c44cdddb6a900fa2b585dd299e03d12fa4293bc (10000 ETH)
Private Key: 0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a

Account #3: 0x90f79bf6eb2c4f870365e785982e1f101e93b906 (10000 ETH)
Private Key: 0x7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6

Account #4: 0x15d34aaf54267db7d7c367839aaf71a00a2c6a65 (10000 ETH)
Private Key: 0x47e179ec197488593b187f80a00eb0da91f1b9d0b13f8733639f19c30a34926a

Account #5: 0x9965507d1a55bcc2695c58ba16fb37d819b0a4dc (10000 ETH)
Private Key: 0x8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba

Account #6: 0x976ea74026e726554db657fa54763abd0c3a0aa9 (10000 ETH)
Private Key: 0x92db14e403b83dfe3df233f83dfa3a0d7096f21ca9b0d6d6b8d88b2b4ec1564e

Account #7: 0x14dc79964da2c08b23698b3d3cc7ca32193d9955 (10000 ETH)
Private Key: 0x4bbbf85ce3377467afe5d46f804f221813b2bb87f24d81f60f1fcdbf7cbf4356

Account #8: 0x23618e81e3f5cdf7f54c3d65f7fbc0abf5b21e8f (10000 ETH)
Private Key: 0xdbda1821b80551c9d65939329250298aa3472ba22feea921c0cf5d620ea67b97

Account #9: 0xa0ee7a142d267c1f36714e4a8f75612f20a79720 (10000 ETH)
Private Key: 0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6

Account #10: 0xbcd4042de499d14e55001ccbb24a551f3b954096 (10000 ETH)
Private Key: 0xf214f2b2cd398c806f84e317254e0f0b801d0643303237d97a22a48e01628897

Account #11: 0x71be63f3384f5fb98995898a86b02fb2426c5788 (10000 ETH)
Private Key: 0x701b615bbdfb9de65240bc28bd21bbc0d996645a3dd57e7b12bc2bdf6f192c82

Account #12: 0xfabb0ac9d68b0b445fb7357272ff202c5651694a (10000 ETH)
Private Key: 0xa267530f49f8280200edf313ee7af6b827f2a8bce2897751d06a843f644967b1

Account #13: 0x1cbd3b2770909d4e10f157cabc84c7264073c9ec (10000 ETH)
Private Key: 0x47c99abed3324a2707c28affff1267e45918ec8c3f20b8aa892e8b065d2942dd

Account #14: 0xdf3e18d64bc6a983f673ab319ccae4f1a57c7097 (10000 ETH)
Private Key: 0xc526ee95bf44d8fc405a158bb884d9d1238d99f0612e9f33d006bb0789009aaa

Account #15: 0xcd3b766ccdd6ae721141f452c550ca635964ce71 (10000 ETH)
Private Key: 0x8166f546bab6da521a8369cab06c5d2b9e46670292d85c875ee9ec20e84ffb61

Account #16: 0x2546bcd3c84621e976d8185a91a922ae77ecec30 (10000 ETH)
Private Key: 0xea6c44ac03bff858b476bba40716402b03e41b8e97e276d1baec7c37d42484a0

Account #17: 0xbda5747bfd65f08deb54cb465eb87d40e51b197e (10000 ETH)
Private Key: 0x689af8efa8c651a91ad287602527f3af2fe9f6501a7ac4b061667b5a93e037fd

Account #18: 0xdd2fd4581271e230360230f9337d5c0430bf44c0 (10000 ETH)
Private Key: 0xde9be858da4a475276426320d5e9262ecfc3ba460bfac56360bfa6c4c28b4ee0

Account #19: 0x8626f6940e2eb28930efb4cef49b2d1f2c9c1199 (10000 ETH)
Private Key: 0xdf57089febbacf7ba0bc227dafbffa9fc08a93fdc68e1e42411a14efcf23656e

WARNING: These accounts, and their private keys, are publicly known.
Any funds sent to them on Mainnet or any other live network WILL BE LOST.

デプロイ

Hardhat セットアップ時に自動的に作成されている scripts/sample-script.js を使って Greeter スマートコントラクトを ethereum ブロックチェーンにデプロイします。

先ほど立ち上げた node にデプロイするために「–network localhost」オプションを指定します。

hardhat_project> npx hardhat run scripts/sample-script.js --network localhost
Deploying a Greeter with greeting: Hello, Hardhat!
Greeter deployed to: 0x5FbDB2315678afecb367f032d93F642f64180aa3

上記の場合だと「0x5FbDB2315678afecb367f032d93F642f64180aa3」が Greeter スマートコントラクトのアドレスですので、メモしておいてください。

コンソールでスマートコントラクトの実行

「npx hardhat console」でコンソールが起動します。 先ほど立ち上げた node に接続するために「–network localhost」オプションを指定します。

hardhat_project> npx hardhat console --network localhost
Welcome to Node.js v16.13.1.
> const Greeter = await ethers.getContractAt('Greeter', '0x5fbdb2315678afecb367f032d93f642f64180aa3');    
undefined
> await Greeter.greet();
'Hello, Hardhat!'
> await Greeter.setGreeting('Hello, World! World is fun!!!');
{
  hash: '0x3868b3b8f7a87a5fd8453444eba9f17193e1835be6ea6cd90ce1b31e41a03b16',
  type: 2,
  accessList: [],
  blockHash: '0x481f987f494e634543be25dbc0e262504709acdf0f00fa9f7ad80d2cf344a4f4',
  blockNumber: 2,
  transactionIndex: 0,
  confirmations: 1,
  from: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',
  gasPrice: BigNumber { _hex: '0x2dd9cf7c', _isBigNumber: true },
  maxPriorityFeePerGas: BigNumber { _hex: '0x00', _isBigNumber: true },
  maxFeePerGas: BigNumber { _hex: '0x3a07aa98', _isBigNumber: true },
  gasLimit: BigNumber { _hex: '0x8c47', _isBigNumber: true },
  to: '0x5FbDB2315678afecb367f032d93F642f64180aa3',
  value: BigNumber { _hex: '0x00', _isBigNumber: true },
  nonce: 1,
  data: '0xa41368620000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001d48656c6c6f2c20576f726c642120576f726c642069732066756e212121000000',
  r: '0x240d275144cca8e5e06e0e46e181c19d8b24605211e0e03af72f9159a24b1a7c',
  s: '0x6953c1d27ef130ce4330d95191c7d861b85b338ae2d44a1c27fb3ed94acab803',
  v: 0,
  creates: null,
  chainId: 31337,
  wait: [Function (anonymous)]
}
> await Greeter.greet();
'Hello, World! World is fun!!!'

別の node に接続する

hardhat.config.js に ethereum ブロックチェーン(node) の設定を追加することで、メインネットや Ropsten や Ganache の node に接続することができます。

以下、Ganache を設定して console 接続する例です。

hardhat.config.js の module.exports に以下を追加。

module.exports = {
  solidity: "0.8.4",
  networks: {
    ganache: {
      url: "http://localhost:7545",
    }
  },
};

ganache にコンソール接続

hardhat_project> npx hardhat console --network ganache
Welcome to Node.js v16.13.1.
Type ".help" for more information.
> const signers = await ethers.getSigners();
undefined
> signers[0].address
'0x9A99681B214e78152a3b6D851852E2C295f89E09'

hardhat console でアカウントの切り替え

TODO: もっと良い方法があるはず!

Hardhat はデフォルトでアカウント一覧の先頭のアカウントが使用される。 hardhat console でトランザクションが発生するような処理を行った場合、上記のアカウントが sender として使用されることになる。

hardhat.config.js の network 設定で「アカウント一覧」を絞ることで「先頭のアカウント」を変更し、トランザクションの sender を変更する。

> code hardhat.config.js

hardhat.confg.js の network 設定に以下を追記。

networks: {
    localhost_account2: {
      url: 'http://127.0.0.1:8545',
      //from: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
      accounts: [
        '0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d',
        '0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a',
      ],
    },

hardhat console 使用時に以下のように「localhost_account2」を選択すれば、上記 accounts の先頭が sender として使用される。

> npx hardhat console --network localhost_account2