Ми часто стикаємося з проблемою: смарт-контракти не зберігають історію стану у зручному для запитів вигляді. eth_getLogs з фільтром за подіями — це грубий інструмент: немає сортування, немає агрегації, немає зв'язків між подіями різних контрактів. В результаті фронтенд або тягне тонни даних і обробляє їх на клієнті, або команда піднімає власний індексуючий бекенд. The Graph вирішує це завдання стандартним способом — ви описуєте, що індексувати, а мережа робить це за вас. Наша команда розробила понад 20 subgraph для DeFi-протоколів та NFT-маркетплейсів, накопичивши досвід в оптимізації та налагодженні. Отримайте консультацію щодо вашого проєкту — допоможемо спроєктувати схему та вибрати стек.
Subgraph — це по суті декларація: які контракти слухати, які події обробляти, як трансформувати дані в entities. Написати його правильно з першого разу складніше, ніж здається.
Як оптимізувати schema для GraphQL-запитів?
Схема повинна проєктуватися виходячи з того, які запити потрібні фронтенду — не зі структури подій контракту. Типова помилка: робити entities один-до-одному з подіями. Це веде до того, що фронтенд робить N+1 запитів. Денормалізовані entities з предагрегованими даними скорочують кількість запитів у 3–5 разів.
Правильний підхід — денормалізовані entities з предагрегованими даними:
type Pool @entity { id: ID! # address пула token0: Token! token1: Token! feeTier: BigInt! totalVolumeUSD: BigDecimal! # накопичувальний обсяг — оновлюємо в кожному Swap totalValueLockedUSD: BigDecimal! txCount: BigInt! swaps: [Swap!]! @derivedFrom(field: "pool") } type Swap @entity { id: ID! # txHash + logIndex pool: Pool! sender: Bytes! recipient: Bytes! amount0: BigDecimal! amount1: BigDecimal! amountUSD: BigDecimal! timestamp: BigInt! blockNumber: BigInt! } @derivedFrom — віртуальний зв'язок, не зберігає масив ID в записі Pool. Це важливо для продуктивності: пул з тисячами свапів не буде рости в розмірі запису. Приклад запиту, який фронтенд може виконувати:
{ pools(first: 10) { id totalVolumeUSD swaps(first: 5) { amountUSD timestamp } } } Чому AssemblyScript небезпечний для розробників TypeScript?
AssemblyScript — строго типізована мова, компілюється в WebAssembly. Звички з TypeScript тут небезпечні:
// НЕПРАВИЛЬНО — null reference в AS викликає паніку let pool = Pool.load(event.address.toHexString()) pool.txCount = pool.txCount.plus(BigInt.fromI32(1)) // pool може бути null // ПРАВИЛЬНО let poolId = event.address.toHexString() let pool = Pool.load(poolId) if (pool === null) { pool = new Pool(poolId) pool.txCount = BigInt.fromI32(0) pool.totalVolumeUSD = BigDecimal.fromString("0") } pool.txCount = pool.txCount.plus(BigInt.fromI32(1)) pool.save() BigDecimal для фінансових значень — обов'язково. BigInt з контракту потрібно конвертувати з урахуванням decimals токена:
function convertTokenToDecimal(tokenAmount: BigInt, exchangeDecimals: BigInt): BigDecimal { if (exchangeDecimals == BigInt.fromI32(0)) { return tokenAmount.toBigDecimal() } return tokenAmount.toBigDecimal().div( BigInt.fromI32(10).pow(exchangeDecimals.toI32() as u8).toBigDecimal() ) } Як налагодити повільну синхронізацію?
Якщо subgraph синхронізується повільніше очікуваного, виконайте перевірку:
- Порахуйте кількість callHandlers — замініть на eventHandlers де можливо. eventHandlers в 5–10 разів швидші.
- Переконайтеся, що startBlock не занадто ранній. Ідеально — блок деплою контракту.
- Перевірте кількість eth_call в handlers — кожен виклик контракту з мапінгу додає RPC-запит.
- Використовуйте ipfs.cat мінімально — це повільна операція.
| Тип обробника | Швидкість | Застосування |
|---|---|---|
| eventHandlers | Швидко (2000–5000 блоків/хв) | Будь-які події, емітовані контрактом |
| callHandlers | Повільно (в 5–10 разів повільніше) | Якщо контракт не емітує подій |
| blockHandlers | Дуже повільно | Тільки коли немає альтернативи, з filter: { kind: once } |
Типові помилки в обробниках:
- Забувають перевірити null перед Pool.load
- Вказують startBlock = 0
- Використовують callHandlers замість eventHandlers там, де можна навпаки
- Не конвертують BigInt в BigDecimal з урахуванням decimals
Як вибрати між Hosted Service та Decentralized Network?
Для production протоколів рекомендується децентралізована мережа: вона забезпечує censorship resistance та стійкість до відключення. Hosted Service безкоштовний, але підходить тільки для розробки та тестування. Порівняння:
| Hosted Service | Decentralized Network | |
|---|---|---|
| Вартість | Безкоштовно (сервіс закривається) | GRT токени (Indexer fees) |
| Latency | Низька | Вище (~100–500ms) |
| Censorship resistance | Ні (centralized) | Так |
| SLA | Без гарантій | Залежить від Indexers |
| Підходить для | Розробка, тестування | Production з вимогою decentralization |
Для деплою в децентралізовану мережу використовуйте Graph Studio:
graph auth --studio <deploy-key> graph codegen && graph build graph deploy --studio <subgraph-name> Детальніше про архітектуру можна прочитати в документації The Graph. Зв'яжіться з нами для консультації з вибору мережі та оптимізації схеми.
Процес розробки subgraph: етапи та терміни
Ми працюємо за наступною схемою:
- Аналіз ABI контрактів та визначення списку подій і викликів для індексації.
- Проектування GraphQL-схеми під конкретні запити фронтенду (з акцентом на денормалізацію).
- Написання AssemblyScript-обробників з урахуванням обробки null, конвертації BigInt та оптимізації продуктивності.
- Локальне тестування за допомогою graph-cli та дебагінг повільних місць.
- Деплой у вибрану мережу та налаштування моніторингу синхронізації.
Терміни залежать від складності контрактів та кількості сутностей: від 3 до 10 робочих днів. Вартість розраховується індивідуально після аналізу вашого проєкту.
Що входить у нашу роботу з розробки subgraph
- Аналіз ABI контрактів та визначення потрібних events/calls
- Проектування schema під конкретні запити фронтенду
- Написання та тестування AssemblyScript handlers
- Оптимізація продуктивності (економія до 40% на RPC-запитах за рахунок денормалізації)
- Деплой та моніторинг синхронізації
- Документація GraphQL endpoints та приклади запитів
Наша команда має багаторічний досвід у розробці блокчейн-рішень, понад 30 успішних проектів на Ethereum, Polygon, BNB Chain, Solana. Замовте розробку subgraph у професіоналів та отримайте швидку індексацію без компромісів.







