Налаштування Hardhat для розробки
Hardhat без налаштування — це просто компілятор Solidity з локальним вузлом. Hardhat з правильною конфігурацією — це повноцінна середовище, де розробник не витрачає час на рутину: компіляція інкрементальна, тесты запускаються паралельно, деплой ідемпотентний, CI/CD знає що робити без ручних інструкцій.
Базова конфігурація
Мінімальний hardhat.config.ts для production-проекту:
import { HardhatUserConfig } from "hardhat/config";
import "@nomicfoundation/hardhat-toolbox"; // ethers, waffle, chai, gas reporter
import "@openzeppelin/hardhat-upgrades";
import "hardhat-deploy";
import "hardhat-contract-sizer";
const config: HardhatUserConfig = {
solidity: {
version: "0.8.24",
settings: {
optimizer: { enabled: true, runs: 200 },
viaIR: true, // зменшує gas, потрібен для складних контрактів
},
},
networks: {
hardhat: {
forking: { url: process.env.ALCHEMY_MAINNET_URL! },
chainId: 1,
},
polygon: {
url: process.env.ALCHEMY_POLYGON_URL!,
accounts: [process.env.DEPLOYER_PRIVATE_KEY!],
gasPrice: "auto",
},
},
gasReporter: {
enabled: process.env.REPORT_GAS === "true",
currency: "USD",
coinmarketcap: process.env.CMC_API_KEY,
},
};
viaIR: true важливий для контрактів, які компілятор Solidity не може скомпілювати без нього (Stack too deep). З IR-компілятором цієї помилки немає, але час компіляції зростає на 30-50%.
Плагіни, які реально потрібні
hardhat-deploy — управління деплоями з підтримкою named accounts, fixtures, і тегування. Деплойні скрипти зберігають artifacts у deployments/ і ідемпотентні: повторний запуск не деплоїть уже задеплоєне. Незамінний при роботі з кількома мережами.
hardhat-contract-sizer — перевірка розміру контракту. EIP-170 обмежує bytecode 24576 байтами. Отримати це обмеження неочікувано на mainnet-деплої — неприємно. Плагін показує розмір після кожної компіляції.
@nomicfoundation/hardhat-toolbox — мета-плагін, який включає hardhat-ethers, hardhat-waffle, hardhat-chai-matchers, hardhat-network-helpers, hardhat-verify. Одна залежність замість шести.
@openzeppelin/hardhat-upgrades — якщо проект використовує UUPS або Transparent Proxy. Плагін перевіряє storage compatibility при апгрейді до деплоя: якщо новий контракт порушує storage layout, ви дізнаєтесь про це до того, як потеряєте дані на mainnet.
Організація тестів і fixtures
Повільні тесты — це наслідок неправильних fixtures. Паттерн loadFixture з hardhat-network-helpers дозволяє зробити снапшот стану мережі після деплоя і відкатитися до нього перед кожним тестом замість повторного деплоя:
async function deployTokenFixture() {
const [owner, alice, bob] = await ethers.getSigners();
const Token = await ethers.getContractFactory("MyToken");
const token = await Token.deploy(ethers.parseEther("1000000"));
return { token, owner, alice, bob };
}
it("transfers tokens", async () => {
const { token, alice } = await loadFixture(deployTokenFixture);
// стан завжди чистий, без повторного деплоя
});
На великому тест-сьюті (200+ тестів) різниця між loadFixture і beforeEach з деплоєм — 5 хвилин vs 30 секунд.
Інтеграція CI/CD
GitHub Actions для автоматичного запуску тестів і верифікації:
- name: Run tests
run: npx hardhat test --network hardhat
env:
ALCHEMY_MAINNET_URL: ${{ secrets.ALCHEMY_URL }}
- name: Verify contract
run: npx hardhat verify --network polygon ${{ steps.deploy.outputs.address }}
env:
POLYGONSCAN_API_KEY: ${{ secrets.POLYGONSCAN_KEY }}
Верифікація у CI вимагає, щоб аргументи constructor були детермінованими або зберігалися як артефакти деплоя. hardhat-deploy зберігає аргументи у deployments/polygon/ContractName.json автоматично.
Налаштування займає 2-3 години. Вартість розраховується індивідуально.







