Налаштування тестового середовища Solidity: Foundry, Hardhat, Anvil

Проблема: тести падають, довіри немає Уявіть: ви деплоїте контракт у mainnet, але через годину виявляєте reentrancy-вразливість. Користувачі втратили кошти — репутація підірвана, аудит не допоміг. Кожна година простою коштує $5,000, а збиток від reentrancy-атак перевищує $100M. Або типова ситуаці

Напрямки блокчейн-розробки

Часті запитання

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1450
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1309
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1004
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1270
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    719
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    1011

Проблема: тести падають, довіри немає

Уявіть: ви деплоїте контракт у mainnet, але через годину виявляєте reentrancy-вразливість. Користувачі втратили кошти — репутація підірвана, аудит не допоміг. Кожна година простою коштує $5,000, а збиток від reentrancy-атак перевищує $100M. Або типова ситуація: новий розробник витрачає півдня на встановлення залежностей і запуск першого тесту. CI-пайплайн впав, але ніхто не знає чому — логи порожні.

Наша команда з 5-річним досвідом у блокчейн-розробці налаштувала такі середовища для 50+ проєктів, включаючи протоколи з сумарним TVL > $1B. У результаті час деплою скоротився на 40%, а кількість багів у продакшені — на 70%. Це не просто тулчейн — це гарантія стабільності та відтворюваності. Налаштування тестового середовища смарт-контрактів дозволяє швидко виявляти помилки.

Який фреймворк обрати під задачу?

Для Solidity-проєктів зараз два реальні варіанти: Foundry та Hardhat. Вони вирішують різні задачі і часто використовуються разом. Вибір залежить від того, що ви тестуєте: логіку контракту чи інтеграцію з фронтендом.

Параметр Foundry Hardhat
Мова тестів Solidity TypeScript/JavaScript
Швидкість виконання Дуже швидко (revm на Rust) Повільніше (до 5x)
Fuzz-тестування Вбудовано (differential, invariant) Тільки через плагіни
Mainnet fork vm.createFork() --fork-url
Frontend інтеграція Складніше Простіше (ethers.js, Wagmi)
Скрипти деплою Solidity scripts TypeScript + ethers.js
Налагодження транзакцій forge debug console.log() у контракті

Наш стандарт: Foundry для unit та fuzz-тестів, Hardhat для скриптів деплою та інтеграції з frontend. Обидва конфіги співіснують в одному репозиторії — це дозволяє писати тести на Solidity, а деплоїти через TypeScript. Тестове середовище з Foundry скорочує час тестування до 5 разів порівняно з використанням тільки Hardhat.

Як влаштована структура проєкту?

Використовуємо розділення на модулі: contracts/core, contracts/interfaces, test/unit, test/integration, test/invariant, script (Foundry), deploy (Hardhat) та fixtures. Така організація дозволяє відокремити модульні тести (без RPC) від інтеграційних (з форком). Unit-тести мають виконуватися за лічені секунди, а інтеграційні — тільки при мержі в main.

Налаштування локальної мережі, моків та фікстур

Локальна мережа: Anvil замість Ganache

Anvil (входить до Foundry) — локальний EVM-нод на Rust. Швидший за Ganache в 10 разів, активно підтримується. Для розробки запускаємо в режимі форку mainnet або testnet:

# Форк Ethereum mainnet з конкретним блоком (відтворюваність) anvil --fork-url $MAINNET_RPC --fork-block-number 19500000 # Форк з попередньо визначеними акаунтами та балансами anvil --fork-url $MAINNET_RPC --accounts 10 --balance 10000 

Форк-тестування — єдиний спосіб перевірити інтеграцію з Uniswap, Aave, Chainlink без деплою на testnet. Транзакція в локальному форку — миттєво. На Sepolia — 12-15 секунд. Економія часу на кожній ітерації: замість 15 секунд — 0.1 секунди. Використовуйте Ethereum testnets для знайомства з мережами.

Моки та фікстури: ізоляція без крихкості

Для ізоляції тестів використовуємо ієрархію фікстур:

// BaseFixture.sol — спільні залежності abstract contract BaseFixture is Test { MockERC20 token; MockChainlinkOracle oracle; function setUp() public virtual { token = new MockERC20("Test", "TST", 18); oracle = new MockChainlinkOracle(2000e8); // $2000 price } } // ProtocolFixture.sol — деплой тестованого протоколу contract ProtocolFixture is BaseFixture { Protocol protocol; function setUp() public override { super.setUp(); protocol = new Protocol(address(token), address(oracle)); } } 

Не використовуємо vm.mockCall для основних залежностей — це крихко і не перевіряє інтерфейс. Створюємо повноцінні mock-контракти з мінімальною реалізацією. Такий підхід знижує кількість хибних спрацьовувань на 30%.

Покрокове налаштування та CI/CD

Детальна інструкція
  1. Встановіть Foundry: curl -L https://foundry.paradigm.xyz | bash.
  2. Створіть конфігурацію: forge init та налаштуйте foundry.toml під ваш проєкт.
  3. Додайте Hardhat: npm install --save-dev hardhat та згенеруйте hardhat.config.ts.
  4. Запустіть локальний нод: anvil в окремому терміналі.
  5. Напишіть перший тест: використовуйте шаблон із fixture вище.
  6. Налаштуйте CI: додайте GitHub Actions workflow (див. нижче).

CI/CD: автоматизація без сюрпризів

Конфігурація GitHub Actions для Foundry:

name: Tests on: [push, pull_request] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Install Foundry uses: foundry-rs/foundry-toolchain@v1 - name: Run unit tests run: forge test --match-path "test/unit/*" -vvv - name: Run integration tests run: forge test --match-path "test/integration/*" --fork-url ${{ secrets.MAINNET_RPC }} - name: Coverage check run: forge coverage --min-line-coverage 80 

Розділяємо unit та integration тести — unit-тести мають працювати без RPC-ключів. Інтеграційні — тільки на PR у main. Це скорочує час фідбеку до 2 хвилин, що в 15 разів швидше за ручне тестування.

Testnet та обсяг робіт

Підтримка кількох мереж

Налаштовуємо multi-network конфіг у Hardhat:

networks: { sepolia: { url: process.env.SEPOLIA_RPC, accounts: [process.env.DEPLOYER_KEY], chainId: 11155111, }, polygon_amoy: { url: process.env.AMOY_RPC, accounts: [process.env.DEPLOYER_KEY], chainId: 80002, }, } 
Testnet Chain ID Faucet Block Time
Sepolia 11155111 Alchemy / Chainlink 12 sec
Polygon Amoy 80002 Official Polygon 2 sec
BNB Testnet 97 Binance Faucet 3 sec

Обсяг робіт та терміни

Зазначимо, що входить у налаштування:

  • Конфігурація Foundry та Hardhat (foundry.toml, hardhat.config.ts)
  • Набір mock-контрактів (ERC-20, Chainlink Oracle)
  • Ієрархія фікстур під ваш протокол
  • Локальний EVM-нод (Anvil) з форк-режимом
  • CI-пайплайн (GitHub Actions) з розділенням unit/integration тестів
  • Налаштування testnet (Sepolia, Polygon Amoy, BNB Chain testnet)
  • Документація щодо запуску та розширення
  • Навчання команди (1-2 години)
  • Підтримка протягом 2 тижнів після налаштування

Терміни: базове налаштування — 1 робочий день. З кастомними моками та фікстурами — 1-2 дні. Для проєктів з кількома чейнами (EVM + Solana) — 2-3 дні. Результат: скорочення часу на тестування до 60%, виявлення вразливостей на ранніх стадіях, стабільний CI. Інвестиція в тестове середовище окупається за 2 місяці, зберігаючи $10,000 на місяць.

Замовлення налаштування тестового середовища

Зв'яжіться з нами — ми проведемо безкоштовний аудит вашого поточного процесу та запропонуємо конфігурацію під ваш протокол. Отримайте консультацію з оптимізації тестового оточення. Гарантуємо: після налаштування кожен коміт проходитиме перевірку без сюрпризів. Замовте налаштування сьогодні — почніть тестувати з упевненістю.