跳至主要内容

使用 hardhat 和 ethers 的 Waffle hello world 教學

waffle
smart contracts
solidity
testing
hardhat
ethers.js
新手
MiZiet
2020年10月16日
5 分鐘閱讀

在本 Waffleopens in a new tab 教學中,我們將學習如何使用 hardhatopens in a new tabethers.jsopens 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("正在部署帶有問候語的 Greeter:", _greeting);
6greeting = _greeting;
7}
8
9function greet() public view returns (string memory) {
10return greeting;
11}
12
13function setGreeting(string memory _greeting) public {
14console.log("正在將問候語從「%s」變更為「%s」", greeting, _greeting);
15greeting = _greeting;
16}
17}
顯示全部

我們的智能合約可以分為三個部分:

  1. constructor - 我們在這裡宣告一個名為 greeting 的字串類型變數,
  2. function greet - 一個在被呼叫時會回傳 greeting 的函式,
  3. function setGreeting - 一個讓我們可以變更 greeting 值的函式。
  • sample-test.js - 我們的測試檔案
1describe("Greeter", function () {
2 it("變更後應回傳新的問候語", 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,並等待以下訊息出現即可。

✓ 變更後應回傳新的問候語

目前為止一切看起來都很好,讓我們為專案增加一點複雜性吧

想像一下,有人將一個空字串作為問候語新增進來。 那不會是個熱情的問候,對吧?
讓我們確保這種情況不會發生:

當有人傳入空字串時,我們希望使用 solidity 的 revert。 好消息是,我們可以用 Waffle 的 chai 匹配器 to.be.revertedWith() 輕鬆地測試此功能。

1it("傳入空字串時應還原", 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 "問候語不應為空"
8 )
9})
顯示全部

看來我們的新測試沒有通過:

正在部署帶有問候語的 Greeter:Hello, world!
正在將問候語從 'Hello, world!' 變更為 'Hola, mundo!'
✓ 變更後應回傳新的問候語 (1514ms)
正在部署帶有問候語的 Greeter:Hello, world!
正在將問候語從 'Hello, world!' 變更為 ''
1) 傳入空字串時應還原
1 個通過 (2s)
1 個失敗
顯示全部

讓我們在智能合約中實作此功能:

1require(bytes(_greeting).length > 0, "問候語不應為空");

現在,我們的 setGreeting 函式看起來像這樣:

1function setGreeting(string memory _greeting) public {
2require(bytes(_greeting).length > 0, "問候語不應為空");
3console.log("正在將問候語從「%s」變更為「%s」", greeting, _greeting);
4greeting = _greeting;
5}

讓我們再執行一次測試:

✓ 變更後應回傳新的問候語 (1467ms)
✓ 傳入空字串時應還原 (276ms)
2 個通過 (2s)

恭喜! 您做到了 :)

結論

我們用 Waffle、Hardhat 和 ethers.js 建立了一個簡單的專案。 我們學會了如何設定專案、新增測試和實作新功能。

想了解更多用於測試智能合約的強大 chai 匹配器,請查看 Waffle 的官方文件opens in a new tab

頁面最後更新時間: 2023年12月8日

這個使用教學對你有幫助嗎?