Розробка блокчейн-інфраструктури
"Інфраструктура" — це всі, що знаходиться між блокчейном та вашим продуктом. Смарт-контракти написані, але без нод, індексерів, event processing pipeline та мониторінгу вони марні в production. Саме інфраструктурні помилки убивають проекти, які вже пройшли аудит смарт-контрактів: втрачені подіїв, downtime RPC провайдера в момент високого навантаження, відсутність replay механізму при падінні сервісу.
Шари блокчейн-інфраструктури
┌─────────────────────────────────────────────────────┐
│ Application Layer │
│ (Frontend, API, Business Logic) │
├─────────────────────────────────────────────────────┤
│ Data Access Layer │
│ (GraphQL API, REST API, WebSocket) │
├─────────────────────────────────────────────────────┤
│ Indexing Layer │
│ (The Graph / custom indexer / event processor) │
├─────────────────────────────────────────────────────┤
│ Node Layer │
│ (Archive node / full node / light client) │
├─────────────────────────────────────────────────────┤
│ Blockchain Layer │
│ (Ethereum / L2 / custom chain) │
└─────────────────────────────────────────────────────┘
Кожний шар має свої вимоги до надійності та масштабування. Розберемо кожний.
Node Layer: своя нода або RPC провайдер
Коли потрібна своя нода
RPC провайдери (Infura, Alchemy, QuickNode) — правильний вибір для 80% проектів. Вони вирішують операційні задачі, дають SLA, масштабуються автоматично.
Своя нода потрібна коли:
-
Потрібна archive node для історичних запитів (
eth_callпо мінулим блокам) — провайдери беруть надбавку - Rate limits критичні — при 100k+ запитах/день провайдер дорогий або обмежує
- Приватність — провайдер бачить всі запити; для протоколів де метадані транзакцій чутливі
- Специфічні методи — деякі debug/trace методи недоступні у провайдерів
Запуск Geth/Reth
# Reth (Rust Ethereum) — синхронізується швидше ніж Geth
reth node \
--chain mainnet \
--http \
--http.addr 0.0.0.0 \
--http.port 8545 \
--http.api eth,net,web3,debug,trace \
--ws \
--ws.addr 0.0.0.0 \
--ws.port 8546 \
--datadir /data/reth
Вимоги до залізо (Ethereum full node):
- CPU: 4+ ядра
- RAM: 16+ GB (32 GB рекомендується)
- SSD: 2+ TB NVMe (не HDD, не SATA SSD)
- Bandwidth: 25+ Mbps стабільно
Час синхронізації Reth: ~24–48 годин для full node, ~2–4 дні для archive.
Мультиплексування RPC
Навіть з одним провайдером потрібен failover. Паттерн — load balancer з health checks:
class RpcMultiplexer {
private providers: JsonRpcProvider[];
private healthStatus: Map<string, boolean> = new Map();
constructor(endpoints: string[]) {
this.providers = endpoints.map(url => new JsonRpcProvider(url));
this.startHealthChecks();
}
async getHealthyProvider(): Promise<JsonRpcProvider> {
const healthy = this.providers.filter(
(p, i) => this.healthStatus.get(String(i)) !== false
);
if (healthy.length === 0) throw new Error('No healthy RPC providers');
return healthy[Math.floor(Math.random() * healthy.length)];
}
private startHealthChecks(): void {
setInterval(async () => {
for (let i = 0; i < this.providers.length; i++) {
try {
await this.providers[i].getBlockNumber();
this.healthStatus.set(String(i), true);
} catch {
this.healthStatus.set(String(i), false);
}
}
}, 15_000);
}
}
Indexing Layer: The Graph vs кастомний індексер
The Graph
Для більшості EVM проектів The Graph — правильний вибір. Пишете subgraph (AssemblyScript + GraphQL schema), деплоїте в Subgraph Studio, отримуєте GraphQL API.
Плюси: decentralized, швидкий старт, GraphQL з коробки.
Мінуси: обмежені можливості в обработчиках, AssemblyScript замість TypeScript, debugging незручний.
Кастомний індексер
Потрібен коли: складна обробка подій, кілька контрактів з залежностями, cross-chain дані, інтеграція off-chain джерел.
class EventIndexer {
private db: Pool;
private provider: JsonRpcProvider;
async indexFromBlock(startBlock: number): Promise<void> {
let currentBlock = startBlock;
const headBlock = await this.provider.getBlockNumber();
while (currentBlock <= headBlock) {
const batch = Math.min(currentBlock + 999, headBlock);
const logs = await this.provider.getLogs({
fromBlock: currentBlock,
toBlock: batch,
address: CONTRACT_ADDRESSES,
});
await this.db.query('BEGIN');
try {
for (const log of logs) {
await this.processLog(log);
}
await this.updateCursor(batch);
await this.db.query('COMMIT');
} catch (e) {
await this.db.query('ROLLBACK');
throw e;
}
currentBlock = batch + 1;
}
await this.startRealtimeIndexing(headBlock);
}
}
Ключові принципи: cursor-based resumption, транзакційність, ідемпотентність, reorg handling.
Event Processing Pipeline
Для високонагруженных систем — Kafka як шина подій. Розділення listener та processor дає горизонтальне масштабування та стійкість до збоїв.
Моніторинг
Prometheus + Grafana. Ключові метрики: indexer lag vs head block, швидкість обробки транзакцій, RPC помилки, час обробки блока.
Алерти:
-
indexer_lag_blocks > 100→ critical -
rpc_errors_total rate > 10/min→ warning -
block_processing_seconds > 30→ warning
Управління ключами та секретами
Розділення полномочій:
- Read-only ключи (індексери, API): тільки читання on-chain
- Transaction signing keys (боти, автоматизація): мінімальні права, AWS KMS або HSM
- Admin keys (Gnosis Safe multisig): тільки управління контрактами, ніколи в автоматизації
- Ротація — ротація API ключів кожні 90 днів
Типові етапи проекту
| Етап | Зміст | Час |
|---|---|---|
| Assessment | Аналіз вимог, архітектура, вибір паттерна | 1–3 дні |
| Node setup | Нода/RPC конфігурація, мультиплексирование | 3–5 днів |
| Indexer | Subgraph або кастомний індексер | 1–2 тижні |
| Event pipeline | Kafka/Redis, processors, webhooks | 3–5 днів |
| Monitoring | Prometheus + Grafana + алерти | 2–3 дні |
| Load testing | Нагрузочне тестування, оптимізація | 2–3 дні |
| Documentation | Runbook, incident response | 1–2 дні |
Суммарно для типовго DeFi протоколу: 3–6 тижнів production-ready інфраструктури з мониторінгом та документацією.







