Waffle:使用 Hardhat 和 ethers 的“hello world”教程
waffle
智能合同
Solidity
测试
hardhat
ethers.js
初学者
MiZiet
2020年10月16日
5 分钟阅读
在本 Waffleopens in a new tab 教程中,我们将学习如何使用 hardhatopens in a new tab 和 ethers.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 888888 888 888 888 888888 888 888 888 8888888888888 8888b. 888d888 .d88888 88888b. 8888b. 888888888 888 "88b 888P" d88" 888 888 "88b "88b 888888 888 .d888888 888 888 888 888 888 .d888888 888888 888 888 888 888 Y88b 888 888 888 888 888 Y88b.888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888👷 欢迎来到 Hardhat v2.0.3 👷? 你想做什么?…❯ 创建一个示例项目 创建一个空的 hardhat.config.js 退出显示全部选择 Create a sample project(创建示例项目)。
我们的项目结构应如下所示:
1MyWaffleProject2├── contracts3│ └── Greeter.sol4├── node_modules5├── scripts6│ └── sample-script.js7├── test8│ └── sample-test.js9├── .gitattributes10├── .gitignore11├── hardhat.config.js12└── package.json显示全部现在让我们来谈谈其中一些文件:
- Greeter.sol - 我们用 Solidity 编写的智能合约;
1contract Greeter {2string greeting;34constructor(string memory _greeting) public {5console.log("Deploying a Greeter with greeting:", _greeting);6greeting = _greeting;7}89function greet() public view returns (string memory) {10return greeting;11}1213function setGreeting(string memory _greeting) public {14console.log("Changing greeting from '%s' to '%s'", greeting, _greeting);15greeting = _greeting;16}17}显示全部我们的智能合约可以分为三个部分:
- 构造函数 - 我们在其中声明一个名为
greeting的字符串类型变量, - 函数
greet- 调用时将返回greeting的函数, - 函数
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!")56 await greeter.deployed()7 expect(await greeter.greet()).to.equal("Hello, world!")89 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!")45 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。
页面最后更新: 2023年12月8日