Перейти к основному содержанию

Руководство Waffle «Hello world» с использованием Hardhat и ethers

Waffle
Умные контракты
Solidity
тестирование
Hardhat
ethers.js
Beginner
MiZiet
16 октября 2020 г.
4 минута прочтения

В этом руководстве по Waffleopens in a new tab мы научимся настраивать простой проект умного контракта «Hello world» с использованием Hardhatopens in a new tab и ethers.jsopens in a new tab. Затем мы узнаем, как добавить новую функциональность в наш умный контракт и как протестировать ее с помощью 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

Следующий шаг — создание образца проекта Hardhat путем запуска npx 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
👷 Добро пожаловать в Hardhat v2.0.3 👷‍
? Что вы хотите сделать? ...
❯ Создать образец проекта
Создать пустой hardhat.config.js
Выйти
Показать все

Выберите Создать образец проекта

Структура нашего проекта должна выглядеть так:

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. конструктор — где мы объявляем строковую переменную с именем greeting,
  2. функция greet — функция, которая возвращает greeting при вызове,
  3. функция 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 и дождаться появления следующего сообщения.

✓ Должен возвращать новое приветствие после его изменения

Пока все выглядит отлично, давайте немного усложним наш проект

Представьте ситуацию, когда кто-то добавляет пустую строку в качестве приветствия. Это было бы не очень теплое приветствие, правда?
Давайте убедимся, что этого не произойдет:

Мы хотим использовать revert из Solidity, когда кто-то передает пустую строку. Хорошо то, что мы можем легко протестировать эту функциональность с помощью матчера to.be.revertedWith() из Waffle Chai.

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 для тестирования ваших умных контрактов, обратитесь к официальной документации Waffleopens in a new tab.

Последнее обновление страницы: 8 декабря 2023 г.

Было ли это руководство полезным?