Посібник Waffle «Привіт, світе» з Hardhat та Ethers
У цьому посібнику з Waffleopens in a new tab ми дізнаємося, як налаштувати простий проєкт смарт-контракту «Привіт, світе», використовуючи 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 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ВийтиПоказати всеВиберіть Створити зразок проєкту
Структура нашого проєкту має виглядати так:
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("Розгортання Greeter з привітанням:", _greeting);6greeting = _greeting;7}89function greet() public view returns (string memory) {10return greeting;11}1213function setGreeting(string memory _greeting) public {14console.log("Зміна привітання з '%s' на '%s'", greeting, _greeting);15greeting = _greeting;16}17}Показати всеНаш смарт-контракт можна розділити на три частини:
- конструктор — у ньому ми оголошуємо змінну типу string під назвою
greeting, - функція greet — функція, яка під час виклику повертає
greeting, - функція 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!")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 і дочекатися появи наступного повідомлення.
✓ Має повертати нове привітання після його зміниПоки що все чудово, додамо трохи складності до нашого проєкту
Уявіть ситуацію, коли хтось додає порожній рядок як привітання. Це було б не дуже тепле привітання, чи не так?
Переконаємося, що цього не станеться:
Ми хочемо використовувати revert з Solidity, коли хтось передає порожній рядок. Добре, що ми можемо легко протестувати цю функціональність за допомогою зіставлення to.be.revertedWith() з Chai від Waffle.
1it("Має скасовувати операцію в разі передавання порожнього рядка", 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 "Привітання не повинно бути порожнім"8 )9})Показати всеСхоже, наш новий тест не пройшов:
Розгортання Greeter з привітанням: Hello, world!Зміна привітання з 'Hello, world!' на 'Hola, mundo!' ✓ Має повертати нове привітання після його зміни (1514ms)Розгортання Greeter з привітанням: Hello, world!Зміна привітання з 'Hello, world!' на '' 1) Має скасовувати операцію в разі передавання порожнього рядка 1 пройдено (2с) 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 пройдено (2с)Вітаємо! Ви впоралися :)
Висновок
Ми створили простий проєкт за допомогою Waffle, Hardhat та ethers.js. Ми дізналися, як налаштовувати проєкт, додавати тест і реалізовувати нову функціональність.
Щоб знайти більше чудових зіставлень Chai для тестування ваших смарт-контрактів, перегляньте офіційну документацію Waffleopens in a new tab.
Останні оновлення сторінки: 8 грудня 2023 р.