Проектирование архитектуры dApp
Недавно к нам обратилась команда DeFi-протокола: их фронтенд делал 20 отдельных RPC-вызовов при каждой загрузке страницы, что приводило к задержке в 5–7 секунд. Проблема была в том, что смарт-контракты не были спроектированы с учётом frontendability: отсутствовали view-функции и богатые Events. Мы перепроектировали архитектуру, добавили Multicall3 и снизили количество запросов до одного — время загрузки упало до 400 мс. Проектирование dApp начинается не с выбора фреймворка, а с анализа того, как пользователь будет взаимодействовать с приложением. Типичная ошибка — разрабатывать фронтенд в отрыве от контрактов. Мы гарантируем, что каждый слой — от смарт-контрактов до UX-потоков — работает как единое целое.
Как мы проектируем безопасную архитектуру dApp?
Первый шаг — выбор стандартов и паттернов для смарт-контрактов. Используем Solidity 0.8.x с защитой от переполнения, явные require и revert с сообщениями, а также проверенные библиотеки (OpenZeppelin). Каждый контракт аудируем статическим анализатором Slither и fuzzer'ом Echidna. Это снижает риск reentrancy, flash loan атак и других уязвимостей. Типичная экономия газа после оптимизации — 30–50% по сравнению с наивной реализацией.
Почему 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 событий в секунду. Для одного из клиентов мы настроили индекс, который за 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" }, ], }); Wallet connection
Настраиваем 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) |
| Стоимость | Бесплатно (подписка) | Инфраструктура |
| Агрегация данных | Средняя | Высокая |
Процесс работы над проектом
- Аналитика — изучение бизнес-логики, пользовательских сценариев.
- Проектирование — контрактная архитектура, спецификация событий, data flow диаграммы.
- Реализация — написание контрактов (Solidity/Rust), фронтенда (React + wagmi + RainbowKit), indexer'ов.
- Тестирование — unit-тесты (Foundry), fuzzing, интеграционные тесты (Tenderly, Hardhat).
- Деплой — развёртывание с verify на Etherscan, настройку Tenderly Dashboard.
- Поддержка — мониторинг транзакций, обновление контрактов через 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 дня.







