Разработка системы индексации блокчейн-событий
При типичных запросах — «покажи все транзакции пользователя за 30 дней», «объём торгов DEX» — eth_getLogs медленный. На архивной ноде с блока 0 запрос займёт минуты; на публичном RPC — упадёт с timeout или block range too large. Мы проектируем отказоустойчивый pipeline индексации событий с exactly-once семантикой и мониторингом в реальном времени. Экономия ресурсов: до 80% времени на поисковых запросах, снижение затрат на RPC в 10 раз. Реальный кейс — клиент сэкономил десятки тысяч долларов в год на инфраструктуре. Наша команда имеет 8+ лет опыта в блокчейн-разработке и более 50 реализованных проектов по индексации. Закажите консультацию — оценим ваш проект за 1 день.
Какой подход к получению событий выбрать?
Есть три способа получать события из ноды, каждый со своими компромиссами:
| Подход | Latency | Сложность | Надёжность | Примерная пропускная способность |
|---|---|---|---|---|
Polling (eth_getLogs) |
Средняя (1-5 сек) | Низкая | Высокая (exactly-once) | До 1000 блоков за запрос |
| WebSocket subscriptions | Низкая (< 1 сек) | Средняя | Средняя (зависит от сети) | Мгновенная доставка |
| Firehose / StreamingFast | Низкая | Высокая | Очень высокая | Поток блоков без ограничений |
Polling — самый распространённый выбор: воркер периодически опрашивает ноду за диапазон блоков, сохраняя lastIndexedBlock. При перезапуске продолжает с последнего обработанного блока. WebSocket даёт низкую задержку, но требует автоматического переподключения и синхронизации пропущенных блоков. Firehose — enterprise-решение для high-throughput систем.
Как обрабатывать реорганизации цепочки?
Реорги — главный источник багов. На Ethereum PoS финальность наступает через две эпохи (~12 минут). На BSC или Polygon реорги глубиной 3-5 блоков — обычное дело.
Стратегия: индексируем с задержкой на N подтверждённых блоков (13 для Ethereum), сохраняем хеш каждого проиндексированного блока. При расхождении хеша — откат до последнего совпадающего состояния и переиндексация.
-- Таблица состояния индексера
CREATE TABLE indexer_blocks (
block_number BIGINT PRIMARY KEY,
block_hash VARCHAR(66) NOT NULL,
indexed_at TIMESTAMPTZ DEFAULT NOW()
);
-- Событие с привязкой к блоку для rollback
CREATE TABLE indexed_events (
id BIGSERIAL PRIMARY KEY,
block_number BIGINT NOT NULL REFERENCES indexer_blocks(block_number),
log_index INT NOT NULL,
tx_hash VARCHAR(66) NOT NULL,
contract_addr VARCHAR(42) NOT NULL,
event_name VARCHAR(100) NOT NULL,
decoded_data JSONB NOT NULL,
UNIQUE(tx_hash, log_index)
);
При детекции реорга удаляем записи с block_number >= reorg_depth и переиндексируем с этой точки.
Техническая деталь: глубины подтверждения для разных сетей
Ethereum: 13 блоков (рекомендация). Polygon: 25 блоков. BSC: 15 блоков. Solana: 1 слот (≈400 мс). Значение можно менять через переменную окружения CONFIRMATIONS.
Декодирование событий: нюансы
ABI-декодирование тривиально с viem или ethers.js, но есть подводные камни. Согласно документации Solidity по событиям, сложности возникают с:
- Indexed vs non-indexed: indexed параметры попадают в topics, non-indexed — в data. Событие с 3 indexed параметрами занимает 4 topics. Декодирование topics для structs невозможно — данные хешируются.
- Анонимные события: без темы event — редки, требуют нестандартного подхода.
- Proxy-контракты (EIP-1967): события эмитятся с адреса proxy, но ABI у реализации. Нужно резолвить implementation через storage slot
0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc. Подробнее в EIP-1967.
Пример декодирования на TypeScript:
import { decodeEventLog } from 'viem'
function parseSwapEvent(log: Log, abi: Abi): SwapEvent {
const decoded = decodeEventLog({
abi,
eventName: 'Swap',
data: log.data,
topics: log.topics,
})
return {
blockNumber: log.blockNumber,
txHash: log.transactionHash,
sender: decoded.args.sender,
recipient: decoded.args.recipient,
amount0: decoded.args.amount0,
amount1: decoded.args.amount1,
sqrtPriceX96: decoded.args.sqrtPriceX96,
liquidity: decoded.args.liquidity,
tick: decoded.args.tick,
}
} Какую базу данных выбрать для хранения событий?
| Критерий | PostgreSQL (партиционирование) | TimescaleDB |
|---|---|---|
| Настройка | Ручное создание партиций | Автоматические hypertables |
| Сжатие | Нет встроенного | Да, для старых данных (уменьшение в 10 раз) |
| Агрегации | Материализованные представления | Continuous aggregates (автообновление) |
| Производительность | Отличная при хорошем партиционировании | В 5 раз быстрее для time-series запросов |
Для хранения событий используем PostgreSQL с партиционированием по block_number или TimescaleDB для high-frequency контрактов. Пример партиционирования:
CREATE TABLE swap_events (
block_number BIGINT NOT NULL,
event_timestamp TIMESTAMPTZ NOT NULL,
event_data JSONB
) PARTITION BY RANGE (block_number);
CREATE TABLE swap_events_0_5m PARTITION OF swap_events FOR VALUES FROM (0) TO (5000000);
-- аналогично для следующих диапазоновTimescaleDB даёт continuous aggregates для метрик: объём торгов в час, количество транзакций — без фоновых задач.
Мониторинг и алерты
Включаем метрики: indexer_lag_blocks, events_per_second, reorg_count. Алерт при отставании более 50 блоков. Здоровье проверяется через health endpoint (503 при превышении порога). Стек: Go/Rust для воркера, PostgreSQL/TimescaleDB, Redis для state, Grafana + Prometheus.
Как мы это делаем: процесс работы
- Аналитика: изучаем смарт-контракты, выявляем все события, определяем частоту эмиссии. Среднее время — 1-2 дня.
- Проектирование: выбираем подход (polling для простоты, firehose для high-load), проектируем схему БД, API. Создаём диаграмму потока данных.
- Реализация: пишем воркер на Go/Rust, настраиваем декодирование, обработку реоргов, партиционирование. Типовой срок — от 5 до 15 дней.
- Тестирование: симулируем отставание, реорги, высокую нагрузку. Используем testnet (Sepolia, Holesky).
- Деплой: Docker-контейнеры с оркестрацией (Kubernetes или Docker Compose). Первичная индексация последних 1000 блоков.
- Мониторинг и поддержка: дашборды Grafana, алерты, ежемесячные отчёты. В течение первого месяца — быстрые исправления.
Ориентировочные сроки: базовая индексация одного контракта — от 5 дней; сложный pipeline с партиционированием и мониторингом — от 2 недель. Стоимость рассчитывается индивидуально — свяжитесь для оценки.
Что входит в работу
- Архитектурное проектирование: выбор подхода, схема БД, спецификация API.
- Реализация pipeline: воркер, декодирование, обработка реоргов, партиционирование.
- GraphQL API на основе подписок (Hasura или собственный resolver).
- Мониторинг и алерты: дашборды, метрики lag.
- Документация: диаграмма данных, точки масштабирования, runbook.
- Обучение команды клиента.
- Поддержка 1 месяц после ввода.
Закажите разработку системы индексации под ключ. Получите консультацию — мы оценим проект за 1 день и предложим оптимальное решение. Свяжитесь с нами.







