Ми розробляємо data lake (озеро даних) для блокчейн-даних — шар, який вирішує головну проблему on-chain аналітики: сирі дані блокчейну не пристосовані для складних запитів. JSON-RPC вузли відповідають на питання «що сталося в блоці X», але не на «покажи всі свопи Uniswap V3 за останні 30 днів за адресами з об'ємом вище порогу». Озеро даних перетворює сирі блоки на структуровані, індексовані й швидко запитувані таблиці.
Ethereum mainnet сьогодні — це близько 20 мільйонів блоків, приблизно 2 мільярди транзакцій та терабайти event logs. Повна історія Ethereum у форматі Parquet займає 3–4 TB. На кожен новий блок (кожні 12 секунд) додаються сотні транзакцій і тисячі log-записів. До цього додаються BSC, Polygon, Arbitrum, Base — у кожної мережі своя історія та швидкість зростання. Наше озеро даних об'єднує їх у єдине аналітичне середовище.
Чому data lake необхідний для аналітики on-chain?
Три класи даних з різними характеристиками:
Blocks & transactions — структуровані, передбачувана схема. Головна складність: reorgs — тимчасові форки, після яких ланцюжок переписується. Пайплайн повинен вміти відкочувати вже записані дані.
Event logs — найцінніші для аналітики. Transfer, Swap, Liquidation, Mint — все це EVM events. Проблема: декодування ABI. Без ABI контракту log — це просто байти з topics. Ми створюємо реєстр ABI через Etherscan API і Sourcify, щоб декодувати мільйони подій автоматично.
Traces (internal transactions) — виклики між контрактами, які не створюють прямої транзакції. Без трейсів невидима значна частина DeFi: flash loan всередині однієї tx, recursive liquidations, MEV bundle. Отримання трейсів через debug_traceTransaction — важка операція, доступна тільки на archive-вузлах.
Як обробляти reorgs?
Reorg — головний головний біль будь-якого блокчейн data pipeline. Ethereum з Proof-of-Stake має probabilistic finality через кілька блоків і повний finality через ~12.8 хвилин (2 епохи). L2 мережі мають ще складнішу модель.
Стандартний підхід:
- Записувати блоки з confirmation lag (чекати N підтверджень перед записом у фінальний шар). Для Ethereum: 32–64 блоки.
- Зберігати staging-шар для останніх M блоків — дані туди пишуться негайно, але позначаються як
pending. - Підписка на події
Reorganizationвід вузла (WebSocketnewHeads+ порівняння parentHash). При reorg — видаляємо зачеплені блоки з staging і перезастосовуємо новий ланцюжок.
Для Iceberg це елегантно вирішується через time travel і merge операції. Для ClickHouse — через ReplacingMergeTree з version-стовпцем.
Архітектура data lake
Шар ingestion
Два підходи:
- Node-based ingestion — пряме підключення до вузла через WebSocket. Підписка на нові блоки + backfill через
eth_getLogsbatch calls. Потребує archive node. Для backfill мільйонів блоків використовуємо паралельну обробку з asyncio. - Third-party data providers — Goldsky, Envio, Substreams. Швидший старт, але vendor lock-in і дорожче на масштабі.
Сховище: вибір формату та двигуна
Для сирих даних блокчейну оптимальний columnar storage:
- Apache Parquet на S3/GCS — стандарт. Компресія zstd зменшує об'єм у 8–10 разів порівняно з JSON. Партиціонування за датою та номером блоку.
- Apache Iceberg поверх Parquet — ACID, schema evolution, time travel. Критично для reorgs.
- ClickHouse — OLAP для гарячих запитів. Сотні мільйонів рядків за секунди.
Типова двушарова архітектура:
Raw layer (S3 + Parquet/Iceberg) ↓ ETL (dbt / Spark / Flink) Serving layer (ClickHouse / BigQuery) ↓ Query API Analytics / Trading systems / Dashboards Декодування ABI та enrichment
Сирі event logs містять topics (хеші event signatures) та data (ABI-encoded). Для декодування потрібен ABI реєстр. Як це зробити покроково:
- Отримайте ABI контракту з Etherscan API або Sourcify.
- Складіть маппінг
contract_address → ABI. - Для кожного log-запису знайдіть signature за topics[0] та декодуйте за допомогою
eth_abi.decode. - Збагатіть дані token metadata (decimals, symbol, ціна) через Uniswap V3 TWAP або зовнішні API.
from eth_abi import decode from web3 import Web3 TRANSFER_TOPIC = Web3.keccak(text="Transfer(address,address,uint256)").hex() def decode_transfer(log: dict) -> dict | None: if log["topics"][0] != TRANSFER_TOPIC: return None from_addr = "0x" + log["topics"][1][-40:] to_addr = "0x" + log["topics"][2][-40:] amount = decode(["uint256"], bytes.fromhex(log["data"][2:]))[0] return {"from": from_addr, "to": to_addr, "amount": amount} Для масового декодування створюємо реєстр ABI — таблицю з маппінгом contract_address → ABI. Джерела: Etherscan API, Sourcify, 4byte.directory. Невідомі контракти обробляємо як raw bytes, enrichment — по мірі появи ABI.
Token metadata enrichment: для ERC-20 трансферів потрібні decimals, symbol, ціна. Ціни беремо з Uniswap V3 TWAP записів або зовнішніх API (історичні дані).
Схема даних та ключові таблиці
CREATE TABLE decoded_events ( block_number UInt64, block_timestamp DateTime, tx_hash FixedString(66), log_index UInt32, contract FixedString(42), event_name LowCardinality(String), chain_id UInt32, params String, -- JSON INDEX idx_contract (contract) TYPE bloom_filter GRANULARITY 4, INDEX idx_event (event_name) TYPE set(100) GRANULARITY 4 ) ENGINE = ReplacingMergeTree(block_number) PARTITION BY toYYYYMM(block_timestamp) ORDER BY (chain_id, contract, block_number, log_index); Окремі таблиці для високочастотних event types: erc20_transfers, uniswap_v3_swaps, aave_liquidations. Партиціонування по місяцях забезпечує швидке індексування блокчейн-даних.
Приклад партиціонування та оптимізації
Для мережі Ethereum партиціонуємо таблицю подій по місяцях. Це дозволяє швидко видаляти застарілі дані та ефективно сканувати часові діапазони. Індекси bloom_filter на контракті прискорюють фільтрацію за адресами.Приклад запиту:
SELECT sum(amount) FROM erc20_transfers WHERE contract = '0xdAC17F958D2ee523a2206206994597C13D831ec7' AND block_timestamp >= '2023-01-01' виконується за частки секунди на 50M рядків.
Порівняння способів отримання даних
| Параметр | Node-based | Third-party (Goldsky) |
|---|---|---|
| Швидкість старту | Середня (налаштування вузла) | Висока (API ключ) |
| Контроль даних | Повний | Обмежений вендором |
| Вартість на масштабі | Низька (свої вузли) | Висока (плата за об'єм) |
| Обробка reorgs | Власний механізм | Вбудована (але непрозоро) |
Що входить в результат
На виході ви отримуєте:
- Робочий data lake з вибраними мережами та подіями.
- Документацію схеми даних та ETL-пайплайну.
- Доступ до ClickHouse (або іншого serving layer) з прикладами запитів.
- Моніторинг lag’у та алерти при проблемах.
- Навчання команди та 1 місяць підтримки.
Можливість розширення: додавання нових контрактів або мереж — підключається через конфігурацію без зміни коду.
Етапи розробки
| Фаза | Зміст | Тривалість |
|---|---|---|
| Design | Визначення scope, мереж/подій, схема даних | 1–2 тиж |
| Core ingestion | WebSocket listener, backfill, reorg handler | 3–4 тиж |
| ABI registry | Накопичення ABI, декодування, enrichment | 2–3 тиж |
| Storage layer | Parquet/Iceberg, ClickHouse, ETL | 3–4 тиж |
| Serving API | REST/GraphQL, rate limiting | 2–3 тиж |
| Monitoring & ops | Airflow, алерти, документація | 1–2 тиж |
Чому варто працювати з нами
Наша команда має 5+ років досвіду в блокчейн-інженерії, реалізовано понад 20 успішних data pipeline для DeFi-протоколів та крипто-фондів. Ми розробляємо під ключ — від проектування схеми до деплою та моніторингу. Оцінимо ваш проект за 2 дні — зв'яжіться з нами для консультації. Замовте розробку data lake під ключ, щоб прискорити аналітику on-chain-даних.
Довірчі слова: гарантія якості, сертифіковані спеціалісти, великий досвід роботи з L1/L2. Посилання: Детальніше про структуру блокчейну можна прочитати на Wikipedia: Блокчейн.







