メインコンテンツへスキップ

WaffleでHardhatとethersを使って「Hello world!」と出力するチュートリアル

WaffleスマートコントラクトSolidityテストHardhatethers.js
初級
MiZiet
2020年10月16日
5 分の読書 minute read

このWaffle(opens in a new tab)チュートリアルでは、Hardhat(opens in a new tab)ethers.js(opens in a new tab)を使用して、「Hello world」と表示するシンプルなスマートコントラクトのプロジェクトを作成する方法を学びます。 さらに、Waffle上で作成したスマートコントラクトに新たな機能を追加し、テストする方法を学びます。

まずはじめに新しいプロジェクトを作成しましょう。

yarn init

あるいは、

npm init

必要なパッケージをインストールします:

yarn add -D hardhat @nomiclabs/hardhat-ethers ethers @nomiclabs/hardhat-waffle ethereum-waffle chai

以下を実行してもよいです:

npm install -D hardhat @nomiclabs/hardhat-ethers ethers @nomiclabs/hardhat-waffle ethereum-waffle chai

次に、npx hardhatを実行して、サンプルのHardhatプロジェクトを作成します。

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.0.3 👷‍
? What do you want to do? …
❯ Create a sample project
Create an empty hardhat.config.js
Quit
すべて表示

Create a sample projectを選択します。

プロジェクトの構造は、以下のようになっているはずです:

1MyWaffleProject
2├── contracts
3│ └── Greeter.sol
4├── node_modules
5├── scripts
6│ └── sample-script.js
7├── test
8│ └── sample-test.js
9├── .gitattributes
10├── .gitignore
11├── hardhat.config.js
12└── package.json
すべて表示

次に、これらのファイルのいくつかを説明します。

  • Greeter.solは、このチュートリアルで使用するSolidityで書かれたスマートコントラクトです。
1contract Greeter {
2string greeting;
3
4constructor(string memory _greeting) public {
5console.log("Deploying a Greeter with greeting:", _greeting);
6greeting = _greeting;
7}
8
9function greet() public view returns (string memory) {
10return greeting;
11}
12
13function setGreeting(string memory _greeting) public {
14console.log("Changing greeting from '%s' to '%s'", greeting, _greeting);
15greeting = _greeting;
16}
17}
すべて表示
コピー

このスマートコントラクトは、以下の3つの要素に分解できます:

  1. コンストラクタ:greetingという名前の文字列型の変数を宣言する場所です。
  2. greet関数:greetingを返す関数です。
  3. setGreeting関数:greetingの値を変更する関数です。
  • sample-test.js:テストを実行するファイルです。
1describe("Greeter", function () {
2 it("Should return the new greeting once it's changed", async function () {
3 const Greeter = await ethers.getContractFactory("Greeter")
4 const greeter = await Greeter.deploy("Hello, world!")
5
6 await greeter.deployed()
7 expect(await greeter.greet()).to.equal("Hello, world!")
8
9 await greeter.setGreeting("Hola, mundo!")
10 expect(await greeter.greet()).to.equal("Hola, mundo!")
11 })
12})
すべて表示
コピー

次に、コントラクトをコンパイルし、テストを実行します。

Waffleでは、Mocha(テスト用フレームワーク)およびChai(アサーションライブラリ)を使ってテストを実行します。 npx hardhat testを実行して、以下のメッセージが表示されるまで待つだけです。

✓ Should return the new greeting once it's changed

今のところ順調ですので、プロジェクトにもう少し機能を付け加えてみましょう

他のユーザーが、挨拶の代わりに空の文字列を追加したと想定してみましょう。 無言の挨拶は嬉しくありませんね!
ですから、このようなことが起こらないようにします:

空の文字列が渡された場合に、Solidityのrevert機能を利用できるようにします。 この機能は、Waffleのchaiマッチャーであるto.be.revertedWith()で簡単にテストできます。

1it("Should revert when passing an empty string", async () => {
2 const Greeter = await ethers.getContractFactory("Greeter")
3 const greeter = await Greeter.deploy("Hello, world!")
4
5 await greeter.deployed()
6 await expect(greeter.setGreeting("")).to.be.revertedWith(
7 "Greeting should not be empty"
8 )
9})
すべて表示
コピー

このテストには、合格しなかったようです。

Deploying a Greeter with greeting: Hello, world!
Changing greeting from 'Hello, world!' to 'Hola, mundo!'
✓ Should return the new greeting once it's changed (1514ms)
Deploying a Greeter with greeting: Hello, world!
Changing greeting from 'Hello, world!' to ''
1) Should revert when passing an empty string
1 passing (2s)
1 failing
すべて表示

さっそくこの機能を、先ほど作成したスマートコントラクトに追加しましょう:

1require(bytes(_greeting).length > 0, "Greeting should not be empty");
コピー

これにより、setGreeting関数は以下のようになっているはずです:

1function setGreeting(string memory _greeting) public {
2require(bytes(_greeting).length > 0, "Greeting should not be empty");
3console.log("Changing greeting from '%s' to '%s'", greeting, _greeting);
4greeting = _greeting;
5}
コピー

もう一度、テストを実行してみましょう:

✓ Should return the new greeting once it's changed (1467ms)
✓ Should revert when passing an empty string (276ms)
2 passing (2s)

おめでとうございます! テストが完成しました :)

まとめ

Waffle、Hardhat、およびethers.jsを使った簡単なプロジェクトを作成しました。 このチュートリアルでは、プロジェクトを開始し、テストを追加し、さらに新たな機能を実装する方法について学びました。

スマートコントラクトのテストに大活躍するChaiマッチャーについてさらに知りたい場合は、Waffleの公式文書(opens in a new tab)を参照してください。

このチュートリアルは役に立ちましたか?