Проектування архітектури dApp: від смарт-контрактів до UX

Проектування архітектури dApp Нещодавно до нас звернулась команда DeFi-протоколу: їхній фронтенд робив 20 окремих RPC-викликів при кожному завантаженні сторінки, що призводило до затримки в 5–7 секунд. Проблема полягала в тому, що смарт-контракти не були спроектовані з урахуванням frontendability

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

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

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

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

Проектування архітектури dApp

Нещодавно до нас звернулась команда DeFi-протоколу: їхній фронтенд робив 20 окремих RPC-викликів при кожному завантаженні сторінки, що призводило до затримки в 5–7 секунд. Проблема полягала в тому, що смарт-контракти не були спроектовані з урахуванням frontendability: були відсутні view-функції та багаті Events. Ми перепроектували архітектуру, додали Multicall3 і зменшили кількість запитів до одного — час завантаження впав до 400 мс (у 20 разів швидше). Проектування dApp починається не з вибору фреймворку, а з аналізу того, як користувач буде взаємодіяти з додатком. Типова помилка — розробляти фронтенд у відриві від контрактів. Ми гарантуємо, що кожен шар — від смарт-контрактів до UX-потоків — працює як єдине ціле.

Проектування безпечної архітектури dApp

Перший крок — вибір стандартів та патернів для смарт-контрактів. Використовуємо Solidity 0.8.x із захистом від переповнення, явні require та revert з повідомленнями, а також перевірені бібліотеки (OpenZeppelin). Кожен контракт аудируємо статичним аналізатором Slither та fuzzer'ом Echidna. Це знижує ризик reentrancy, flash loan атак та інших вразливостей. Типова економія газу після оптимізації — 30–50% порівняно з наївною реалізацією, що зменшує витрати на $5000 на місяць для активних протоколів.

Чому frontendability критична для DeFi?

Контракти мають бути зручні для фронтенду. Це означає:

  • Багаті Events для кожної значущої дії (переказ, зміна балансу, зміна параметрів).
  • View-функції для читання без газу (наприклад, totalAssets, balanceOf).
  • Сумісність з Multicall3 — щоб фронтенд міг отримувати десятки значень за один RPC-запит.

Data fetching архітектура

Ми використовуємо багаторівневу систему завантаження даних:

  • Realtime: WebSocket до RPC або Alchemy SDK.
  • Recent history: The Graph (subgraph).
  • Historical analytics: Self-hosted PostgreSQL indexer.
  • Prices: CoinGecko API + Chainlink on-chain.

За даними документації The Graph, субграфи можуть обробляти до 1000 подій на секунду — в 10 разів швидше ніж self-hosted indexer. Для одного з клієнтів ми налаштували індекс, який за 2 хвилини обробляв 3 мільйони подій.

Як ми реалізуємо transaction flow UX?

Користувацький досвід при відправці транзакції — часте джерело помилок. Ми проектуємо чотири стани:

  • IDLE: кнопка готова.
  • WAITING_WALLET: користувач підтверджує в гаманці.
  • CONFIRMING: транзакція в мемпулі.
  • SUCCESS або ERROR: фінальний стан.

Приклад з wagmi:

Код прикладу
function DepositButton({ amount }: { amount: bigint }) { const { data: hash, writeContract, isPending } = useWriteContract(); const { isLoading: isConfirming, isSuccess } = useWaitForTransactionReceipt({ hash }); const status = isPending ? "WAITING_WALLET" : isConfirming ? "CONFIRMING" : isSuccess ? "SUCCESS" : "IDLE"; return ( <button onClick={() => writeContract({ address: POOL, abi, functionName: "deposit", args: [amount] })} disabled={status !== "IDLE"} > {status === "WAITING_WALLET" && "Confirm in wallet..."} {status === "CONFIRMING" && "Confirming..."} {status === "SUCCESS" && "Deposited!"} {status === "IDLE" && "Deposit"} </button> ); } 

State management та Batching

Для читання даних використовуємо TanStack Query з refetchInterval (30 секунд для чутливих даних) та Multicall3 для об'єднання запитів:

import { multicall } from "viem/actions"; const results = await multicall(client, { contracts: [ { address: TOKEN_A, abi: ERC20_ABI, functionName: "balanceOf", args: [user] }, { address: TOKEN_B, abi: ERC20_ABI, functionName: "balanceOf", args: [user] }, { address: POOL, abi: POOL_ABI, functionName: "totalAssets" }, ], }); 

Підключення гаманця

Налаштовуємо RainbowKit з підтримкою основних мереж та гаманців:

import { getDefaultConfig, RainbowKitProvider } from "@rainbow-me/rainbowkit"; import { arbitrum, mainnet, base } from "wagmi/chains"; const config = getDefaultConfig({ appName: "MyDApp", projectId: WALLETCONNECT_PROJECT_ID, chains: [mainnet, arbitrum, base], wallets: [ { groupName: "Popular", wallets: [metaMaskWallet, coinbaseWallet, walletConnectWallet] }, ], }); 

Порівняння підходів до архітектури

Параметр Монолітна архітектура Модульна (наша)
Зв'язність шарів Висока, зміни зачіпають все Низька, кожен шар незалежний
Тестованість Складно, потрібен мок всієї системи Просто, можна тестувати контракти ізольовано
Повторне використання Низьке Високе (контракти, indexer, UI-компоненти)
Час впровадження змін Довгий Короткий, до 2 днів на шар

Порівняння методів індексації

Критерій The Graph Self-hosted indexer
Швидкість синхронізації До 1000 подій/сек Залежить від заліза
Гнучкість запитів Обмежена (GraphQL) Повна (SQL)
Вартість Безкоштовно (підписка) Інфраструктура
Агрегація даних Середня Висока

Процес роботи над проектом

  1. Аналітика — вивчення бізнес-логіки, користувацьких сценаріїв.
  2. Проектування — контрактна архітектура, специфікація подій, data flow діаграми.
  3. Реалізація — написання контрактів (Solidity/Rust), фронтенду (React + wagmi + RainbowKit), indexer'ів.
  4. Тестування — unit-тести (Foundry), fuzzing, інтеграційні тести (Tenderly, Hardhat).
  5. Деплой — розгортання з verify на Etherscan, налаштування Tenderly Dashboard.
  6. Підтримка — моніторинг транзакцій, оновлення контрактів через proxy, оптимізація газу.

Терміни та що входить в роботу

Терміни: від 2 до 6 тижнів залежно від складності. Вартість розраховується індивідуально — зв'яжіться з нами, щоб отримати оцінку. Входить:

  • Архітектурна документація (схеми, специфікації).
  • Вихідний код контрактів з коментарями.
  • Фронтенд-стек з конфігурацією (wagmi, RainbowKit).
  • Доступи до Tenderly проекту та алерти.
  • Навчання команди роботі з кодом.

Типові помилки при проектуванні dApp

  • Відсутність Multicall3 — фронтенд робить 10–20 окремих запитів, збільшуючи час завантаження в 3–5 разів.
  • Слабкі Events — без деталей про перекази балансів складно будувати аналітику.
  • Ігнорування UX транзакцій — користувач не бачить проміжних станів і натискає кнопку повторно, викликаючи дублюючі транзакції.
  • Вибір невідповідного indexer'а — The Graph швидкий для мільйонів подій, але для кастомної агрегації краще self-hosted.

Досвід нашої команди — 5+ років у Web3, 10+ реалізованих проектів (DeFi, NFT, геймінг). Гарантуємо чистоту коду та дотримання найкращих практик. Отримайте консультацію з архітектури вашого dApp — пишіть на пошту або в Telegram. Зв'яжіться з нами для обговорення вашого проекту — ми підготуємо архітектурну документацію за 2 дні.