Розробка кастомного індексатора блокчейну під ключ

Проєктуємо та розробляємо блокчейн-рішення повного циклу: від архітектури смарт-контрактів до запуску DeFi-протоколів, NFT-маркетплейсів та криптобірж. Аудит безпеки, токеноміка, інтеграція з наявною інфраструктурою.
Показано 1 з 1Усі 1305 послуг
Розробка кастомного індексатора блокчейну під ключ
Складний
~1-2 тижні
Часті запитання

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

Етапи блокчейн-розробки

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

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

Розробка кастомного індексатора блокчейну

The Graph вирішує 80% задач індексації. Решта 20% — це коли потрібна складна агрегація даних на льоту, крос-чейн індексація з об'єднанням стану, доступ до даних, які не потрапили в події (storage slots, trace calls), субсекундна латентність або повний контроль над інфраструктурою без vendor lock-in. Саме для цих випадків будується кастомний індексатор блокчейну. Якщо ваш DeFi-протокол обробляє тисячі транзакцій на годину і потребує миттєвої консистентності — типові рішення не справляються. Реорганізації глибиною 1–2 блоки трапляються щодня на Ethereum mainnet, і без їх коректної обробки баланси в UI будуть невірними.

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

Сценарії для кастомного індексатора блокчейну

Стандартні інструменти на зразок The Graph не справляються, коли потрібно:

  • складна агрегація з об'єднанням даних з кількох контрактів та ланцюжків;
  • доступ до storage slots або внутрішніх транзакцій (traces);
  • субсекундна латентність для торгових ботів або DeFi-протоколів;
  • повний контроль над інфраструктурою та відсутність vendor lock-in.

У цих випадках кастомний індексатор блокчейну — єдине рішення.

Архітектурні рішення перед початком

Перш ніж писати код, потрібно відповісти на три питання:

Джерело даних. Logs/events — найдешевший спосіб, але лише те, що контракт явно емітує. Traces (internal transactions) — потрібен archive node з trace_ namespace або Erigon з --tracing. Storage proofs — для стану, який ніколи не емітувався в події. Вибір джерела визначає вимоги до ноди та складність парсингу.

Модель консистентності. Чи потрібна точна консистентність (обробка реорганізацій) чи eventual достатньо? Для фінансових даних реорганізація — не рідкість. На Ethereum mainnet реорги глибиною 1-2 блоки трапляються кілька разів на день. Глибина фінальності для safe confirmation — 12-15 блоків на PoS Ethereum.

Вимоги до латентності. Реалтайм (< 1 сек від блоку) — потрібен WebSocket + streaming. Аналітика (хвилини/години) — batch processing достатній.

Як влаштований кастомний індексатор?

Інгестія даних (Data Ingestion Layer)

Три патерни отримання даних з ноди:

JSON-RPC polling — найпростіший варіант. eth_getLogs з фільтром по address і topics, eth_getBlockByNumber. Затримка = polling interval (зазвичай 500мс-2сек). Проблема: при високому RPS нода починає throttle.

WebSocket subscriptions — eth_subscribe("newHeads") і eth_subscribe("logs", filter). Latency близька до часу блоку. Проблема: при реконнекті можна пропустити блоки, потрібна логіка catch-up.

Direct P2P — підключення до Ethereum P2P мережі через devp2p/libp2p, отримання блоків безпосередньо без RPC. Мінімальна латентність, але висока складність реалізації. Практично тільки якщо індексатор фізично близько до валідаторів.

Для production рекомендую WebSocket + catch-up механізм:

async def subscribe_blocks(ws_url: str, from_block: int):
    # Спочатку доганяємо до поточного блоку
    current = await rpc.eth_block_number()
    for block_num in range(from_block, current):
        block = await rpc.eth_get_block_by_number(block_num)
        await process_block(block)
    
    # Потім підписуємося на нові
    async with websockets.connect(ws_url) as ws:
        await ws.send(json.dumps({
            "method": "eth_subscribe",
            "params": ["newHeads"]
        }))
        async for message in ws:
            head = json.loads(message)
            await process_new_head(head)

Декодування ABI

Raw log — це масив topics (bytes32) і data (bytes). Декодування через ABI:

import { decodeEventLog, parseAbi } from 'viem';

const abi = parseAbi([
  'event Transfer(address indexed from, address indexed to, uint256 value)'
]);

const decoded = decodeEventLog({
  abi,
  data: log.data,
  topics: log.topics,
});
// decoded.args.from, decoded.args.to, decoded.args.value

Indexed параметри кодуються в topics (topic[0] = keccak256 сигнатури, topic[1..3] = indexed args). Non-indexed — в data через ABI encoding.

Проблеми при декодуванні:

  • Anonymous events — нема topic[0], matching тільки по address
  • Proxy контракти — ABI implementation, а не proxy. Потрібно резолвити через implementation() slot (EIP-1967)
  • Upgrade події — після апгрейду ABI змінюється, потрібна версіонованість

Обробка реорганізацій

Це найнеприємніша частина кастомного індексатора. Реорг означає, що блоки, які ви вже обробили, більше не канонічні.

Патерн: кожен запис у базі містить block_hash і block_number. При обробці нового блоку перевіряємо батька:

-- Виявлення реоргу
SELECT block_hash, block_number 
FROM processed_blocks 
WHERE block_number = $1 AND block_hash != $2;

-- Атомарна обробка блоку
BEGIN;
  DELETE FROM events WHERE block_hash = $orphaned_hash;
  DELETE FROM processed_blocks WHERE block_hash = $orphaned_hash;
  INSERT INTO processed_blocks (block_number, block_hash, ...) VALUES (...);
  INSERT INTO events (...) VALUES (...);
COMMIT;

Для цього потрібна атомарна обробка блоку — всі зміни від одного блоку застосовуються в одній транзакції БД з block_hash як ідентифікатором.

Шар зберігання

Вибір БД визначається патернами запитів:

Сценарій Технологія Причина
Time-series дані (ціни, об'єми) TimescaleDB Гіпертаблиці, автокомпресія, continuous aggregates
Граф-запити (зв'язки між акаунтами) PostgreSQL + ltree або Neo4j Рекурсивні запити або граф-нативна БД
Повнотекстовий пошук по метаданих NFT PostgreSQL + GIN index jsonb + GIN індекси для JSON-полів
OLAP аналітика ClickHouse Колонкове зберігання, векторизоване виконання
Кеш актуального стану Redis Hash-структури для балансів, pub/sub для стримінгу

Для більшості DeFi індексаторів: PostgreSQL для основних даних + Redis для hot cache.

API шар

GraphQL через Hasura (автогенерація з PostgreSQL схеми) або вручну через Apollo Server. REST для простих випадків.

Критична оптимізація: DataLoader для батчінгу запитів. Якщо GraphQL-запит просить transfers { from { balance } } — без DataLoader отримаємо N+1 запитів до БД. DataLoader групує запити за один tick event loop.

Subscriptions для реалтайм даних: PostgreSQL LISTEN/NOTIFY → WebSocket → GraphQL subscription.

Чому кастомний індексатор швидше The Graph?

The Graph використовує WASM-обробку в Subgraphs, що дає затримки при підкачуванні станів. Кастомний індексатор працює напряму з нодою через WebSocket, обробляє блоки пулом воркерів і пише дані батчами — це знижує latency до субсекунд і збільшує throughput в 10-50x. Крім того, ви контролюєте індекси та схеми БД, що дозволяє оптимізувати запити під конкретні дані.

Продуктивність та масштабування

Вузькі місця в порядку частоти зустрічальності:

Паралельна обробка блоків. Блоки незалежні, якщо немає cross-block стану (зазвичай немає). Worker pool по N потоків, кожен обробляє свій діапазон блоків. Обережно: порядок запису в БД має бути детермінованим.

Batch insert. Не INSERT кожну подію окремо. PostgreSQL COPY або INSERT...VALUES — різниця в 10-50x по throughput.

# Погано: N окремих INSERT
for event in events:
    await db.execute("INSERT INTO events VALUES ($1, $2, ...)", event)

# Добре: один batch INSERT
await db.executemany(
    "INSERT INTO events VALUES ($1, $2, ...)",
    [(e.block, e.tx_hash, ...) for e in events]
)

Індекси vs insert speed. Кожен індекс уповільнює INSERT. Для історичної синхронізації: створити таблицю без індексів, завантажити дані, потім CREATE INDEX CONCURRENTLY. Прискорення в 3-10x порівняно з індексами під час завантаження.

Технологічний стек

Компонент Варіанти
Мова інгестії TypeScript/Node.js (viem/ethers), Python (web3.py), Rust (alloy)
Черга Redis Streams, Apache Kafka (при > 10k подій/сек)
База даних PostgreSQL 16 + TimescaleDB
API Hasura (швидкий старт) або custom GraphQL
Моніторинг Prometheus + Grafana, alerting по lag метриці
Деплой Docker Compose (dev), Kubernetes (prod)

Rust (alloy crate) дає найкращу продуктивність для високонавантажених індексаторів: парсинг ABI, десеріалізація блоків, робота з bytes — все це швидше ніж в Node.js в 5-20x.

Моніторинг та операційна робота

Ключові метрики:

  • Indexer lag — різниця між latest_block в БД та eth_blockNumber. Алерт при > 10 блоків.
  • Reorg count — кількість реорганізацій за період. Різке зростання = проблеми з нодою або RPC.
  • Events per block — аномалії вказують на нестандартну активність або баги в парсингу.
  • DB write latency — деградація означає потребу у vacuum, bloat, або шардуванні.
# Приклад Prometheus alert
- alert: IndexerLagHigh
  expr: eth_latest_block - indexer_processed_block > 50
  for: 2m
  annotations:
    summary: "Indexer is falling behind by {{ $value }} blocks"

Як ми розробляємо кастомний індексатор?

  1. Проектування (3-5 днів). Визначення джерел даних, схеми БД, вимог до реалтайму. Вибір між кастомною розробкою та розширенням існуючих рішень (Ponder, Substreams).
  2. Розробка ядра (5-10 днів). Інгестія + декодування + обробка реорганізацій + зберігання. Це критичний шлях, тестується на історичних даних.
  3. API та інтеграції (3-5 днів). GraphQL/REST схема, subscriptions, документація.
  4. Навантажувальне тестування та оптимізація (2-3 дні). Синхронізація з genesis, навантажувальне тестування API, налаштування пулів з'єднань, індексів.
  5. Деплой та моніторинг (1-2 дні). Docker Compose / Kubernetes, налаштування алертів, runbook для чергових.

Разом: 1-2 тижні для індексатора одного протоколу на одній мережі. Мультичейн з агрегацією — ближче до 3-4 тижнів. Зв'яжіться з нами для точної оцінки термінів вашого проекту.

Як забезпечити нульову втрату подій при реорганізаціях?

Ключ — атомарність запису з block_hash. Якщо реорг виявлено, всі дані від точки розходження відкочуються в одній транзакції і потім перезаписуються канонічними блоками. Додатково ми використовуємо confirmations: чекаємо 12-15 блоків перед записом в основний шар. Для реалтайм-даних застосовується eventual consistency з гарантією, що фінальний запис завжди коректний.

Що входить в розробку

  • Архітектурна документація
  • Вихідний код індексатора (з коментарями)
  • GraphQL/REST API з документацією (Swagger/GraphiQL)
  • Налаштування моніторингу (Prometheus + Grafana, дашборди)
  • Інструкція з розгортання (Docker Compose/Kubernetes)
  • 1 місяць підтримки після запуску (виправлення багів, консультації)

Вартість розробки розраховується індивідуально після оцінки проекту. Економія на інфраструктурі при використанні нашого рішення може досягати 40% за рахунок оптимізації запитів та кешування. Скорочення часу на розробку порівняно з самостійною реалізацією — до 50% за рахунок готових архітектурних шаблонів. Замовте розробку під ключ — зв'яжіться, щоб оцінити ваш проект.

Розгортання блокчейн-інфраструктури: як уникнути простоїв?

Subgraph впав о 3:47 ночі. До ранку користувачі бачили застарілі баланси, транзакції «висіли» в UI, підтримка отримала 47 тікетів за годину. Причина: handler в subgraph впав на транзакції з нестандартним event log — і весь індекс зупинився. Ми стикалися з такими ситуаціями десятки разів. Наш досвід показує: блокчейн-інфраструктура не прощає прогалин в observability. Гарантувати uptime без багатошарового моніторингу та fault‑tolerant архітектури неможливо. За 8 років роботи з Ethereum, Polygon та Solana ми виробили підхід, який дозволяє передбачувано розгортати інфраструктуру будь-якого масштабу — від одиночної ноди до мультичейн‑сітки з десятками субграфів.

Архітектура RPC-шару

Кожна взаємодія dApp з блокчейном йде через RPC — JSON‑RPC API, яку надає нода. Три варіанти:

Managed providers — Alchemy, QuickNode, Infura, Ankr. Мінімальні операційні витрати, SLA, вбудований моніторинг. Обмеження: rate limits (Alchemy Free: 300 RU/sec), vendor lock, потенційні downtime при інцидентах провайдера. Для більшості проектів — правильний вибір на старті.

Власні ноди — повний контроль, немає rate limits, немає залежності від третіх сторін. Вартість: архівна нода Ethereum займає 2.5–3TB SSD, потребує потужний сервер та DevOps‑підтримку. Sync з нуля на Ethereum через Geth/Nethermind — 3–7 днів. Виправдано при високому навантаженні або вимогах до latency.

Гібрид — власна нода як primary, managed provider як fallback. Стандарт для протоколів з високим TVL. Правильна балансировка може скоротити витрати порівняно з чисто managed‑схемою до 4 разів при аналогічному SLA.

Провайдер Сильна сторона Обмеження
Alchemy Supernode, Enhanced APIs, webhooks Дорогий на high-volume
QuickNode Низька latency, multi-chain Дорожче Alchemy на базовому плані
Infura Історична надійність Rate limits на безкоштовному, один великий інцидент зупинив пів DeFi
Ankr Дешевий, 40+ чейнів Менш стабільний

Як налаштувати RPC-шар без єдиної точки відмови?

Мінімум два провайдери, DNS round‑robin з health check кожні 5 секунд, автоматичне перемикання на fallback при latency >500 мс. На практиці це дає 99.99% доступності при будь-якому збої провайдера. Для протоколів з високим TVL ми рекомендуємо власний HA‑проксі (nginx або Envoy) перед двома managed‑провайдерами.

Чому гібридна RPC-схема вигідніша за чисто managed?

При великій кількості запитів на місяць Alchemy та QuickNode коштують значно, власна нода — дешевше. Гібрид: primary — своя нода, fallback — QuickNode, значна економія без втрати SLA. Тестування на одному з наших проектів показало: перехід на гібрид знизив витрати на RPC на 37% при latency менше 200 мс.

Клієнти нод Ethereum

Execution clients: Geth (найбільш використовуваний), Nethermind (C#, швидка sync), Besu (Java, enterprise), Erigon (найшвидший sync, архівний режим ефективний по диску — ~2TB замість 3TB).

Consensus clients (post‑Merge): Lighthouse (Rust), Prysm (Go), Teku (Java), Nimbus (Nim). Кожна нода після The Merge потребує пари execution + consensus client.

Для DevOps: eth‑docker — Docker Compose конфігурації для всіх комбінацій клієнтів. Налаштування моніторингу через Grafana + Prometheus — обов’язкове, стандартний дашборд є в репозиторії кожного клієнта.

The Graph: індексація подій

The Graph Protocol — decentralized indexing. Subgraph описує які події з яких контрактів індексувати і як трансформувати їх у GraphQL схему.

Структура subgraph:

  • subgraph.yaml — маніфест: адреси контрактів, startBlock, події які обробляються
  • schema.graphql — GraphQL схема entities
  • src/mapping.ts — AssemblyScript обробники подій
dataSources:
  - kind: ethereum
    name: UniswapV3Pool
    network: mainnet
    source:
      address: "0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640"
      abi: UniswapV3Pool
      startBlock: 12370624
    mapping:
      eventHandlers:
        - event: Swap(indexed address,indexed address,int256,int256,uint160,uint128,int24)
          handler: handleSwap

AssemblyScript handlers — не TypeScript. Немає nullable types, немає closures, немає багатьох стандартних API. Помилка в handler зупиняє індексацію subgraph-а на тій транзакції. Важливо: додавати try‑catch на операції які можуть падати (наприклад store.get() для entity яка може не існувати). Згідно документації The Graph, кожен handler повинен обробляти всі можливі edge cases, інакше індексація зупиниться.

Уникнення зупинки індексації субграфа

Лог файли Graph Node моніторяться в реальному часі, при hasIndexingErrors = true спрацьовує алерт і автоматичний рестарт ноди (через systemd або Kubernetes). Типовий downtime при помилці — 150–300 секунд до відновлення. Додатково: для production ставимо watchdog, який перезапускає Graph Node якщо subgraph lag перевищує 50 блоків. Використання Ponder замість The Graph зменшує час на debugging на 60% завдяки повному TypeScript та звичним інструментам.

Вибір між Hosted Service та Decentralized Network

Graph Hosted Service (безкоштовний, централізований) deprecated на користь Subgraph Studio + Graph Network. Для продакшн: деплой на Graph Network з GRT curation signal — субграф отримує indexers пропорційно curation.

Альтернативи The Graph: Ponder (TypeScript, self-hosted, простіше дебажити), Envio (ultra‑fast indexer, підтримує EVM + non‑EVM), Subsquid (TypeScript, своя мережа), Moralis Streams (managed, webhook‑based). Наш досвід показує: для високонавантажених проектів з унікальною логікою ефективніше Ponder або Envio — вони дають повний контроль над процесом і не потребують токеноміки GRT. Ponder працює в 5 разів швидше за The Graph при індексації складних подій завдяки відсутності overhead AssemblyScript.

Webhooks та real-time нотифікації

Alchemy Webhooks та QuickNode Streams дозволяють отримувати події в реальному часі через HTTP webhook або WebSocket. Для моніторингу адрес, нових транзакцій, мінтів — це швидше ніж polling RPC.

Tenderly — платформа для моніторингу та алертів. Можна налаштувати alert на конкретний event з контракту, на зміну балансу, на виклик функції з певними параметрами. Симуляція транзакцій через Tenderly API — безцінно для debugging.

Моніторинг та observability

Мінімальний стек моніторингу для протоколу:

On‑chain: OpenZeppelin Defender Sentinel — watches contract events, викликає webhook або Autotask при спрацьовуванні умов. Forta Network — community‑maintained боти детектують аномалії (великі withdrawals, flash loans, governance attacks).

Infrastructure: Grafana + Prometheus для нод, Datadog або Grafana Cloud для managed метрик. Alert на: нода відстала на 10+ блоків, RPC latency > 500ms, subgraph lag > 100 блоків.

Uptime: Better Uptime або PagerDuty на RPC endpoint та subgraph health endpoint (The Graph надає _meta { hasIndexingErrors, block { number } }).

Обмеження моніторингу без Tenderly

Tenderly дає симуляцію транзакцій та детальні трейси — це критично для налагодження помилок у субграфах та смарт‑контрактах. Forta ж фокусується на аномаліях у мережі, а не на вашій інфраструктурі. Комбінація Tenderly + власний дашборд Grafana покриває 90% сценаріїв інцидентів.

Мультичейн інфраструктура

Протокол на 5 чейнах = 5 окремих RPC endpoints, 5 subgraphs, 5 моніторинг‑конфігів. Це керовано, але потрібна автоматизація деплою.

Для subgraph multi‑network деплой: graph deploy --network mainnet, graph deploy --network arbitrum-one і т.д. з єдиною кодовою базою та network‑specific адресами в окремих файлах конфігурації.

Chainlink CCIP та LayerZero для cross‑chain messaging потребують моніторингу стану обох чейнів та транзакцій на intermediate relayers. Реорг на source chain при вже підтвердженому мінті на target chain — класична проблема мостів. Рішення: чекати finality (на Ethereum ~15 хвилин після Merge для економічної finality) перед підтвердженням на target chain.

Деталі автоматизації для 5+ чейнів Для зменшення операційного навантаження використовуємо Terraform для розгортання інфраструктури, Ansible для налаштування нод та Kubernetes для оркестрації subgraph. Кожен чейн отримує окремий namespace з однаковими шаблонами моніторингу. Це дозволяє розгорнути новий чейн за 2 дні замість 2 тижнів.

Процес налаштування інфраструктури

  1. Аудит поточного стеку — визначаємо чейни, обсяг запитів, вимоги до latency та доступності.
  2. Проектування архітектури — вибір провайдерів, балансировка, redundancy.
  3. Розробка subgraph — маніфест → схема → handlers → тестування на локальній Graph Node → деплой на testnet → mainnet.
  4. Конфігурація моніторингу — Tenderly alerts, Grafana дашборд, PagerDuty інтеграція.
  5. Документація та runbook — що робити при: subgraph fell behind, RPC downtime, нода desync.
  6. Передача в експлуатацію — навчання команди, передача доступів, підтримка перший місяць.

Що входить у роботу?

  • Розгортання managed або self‑hosted нод Ethereum, Polygon, BNB Chain
  • Налаштування RPC‑шару з primary/fallback та load balancing
  • Розробка та деплой subgraph під ваш протокол
  • Підключення моніторингу (Tenderly, Grafana, алерти)
  • Створення runbook та документації з експлуатації
  • Навчання команди (до 4 годин онлайн)
  • Підтримка протягом 30 днів після здачі

Які терміни виконання?

Робота Термін
Налаштування RPC та базового моніторингу 1–2 тижні
Subgraph для одного протоколу 2–4 тижні
Self-hosted нода з моніторингом 2–3 тижні
Повна інфраструктура (multi-chain, моніторинг, runbooks) 6–10 тижнів

Всі проекти ведуться в репозиторії на GitHub/GitLab з CI/CD, код конфігурацій залишається у вас. Замовте розгортання інфраструктури — розкажемо, як скоротити витрати без втрати надійності. Отримайте консультацію — покажемо, як ми розгортали інфраструктуру для протоколу з високим TVL на Ethereum та Arbitrum. Зв'яжіться з нами.