Разработка системы отслеживания транзакций
Наивная реализация мониторинга транзакций — это polling JSON-RPC каждые N секунд: eth_getBlockByNumber, перебор транзакций, поиск нужного адреса. При нагрузке в 10+ адресов это быстро превращается в проблему: растущий lag, rate-limit от RPC-провайдера, пропущенные транзакции при кратковременных сбоях. Правильная система строится на другой архитектуре — event-driven, с реорганизацией цепи и гарантированной обработкой.
Архитектура: три основных подхода
1. WebSocket-подписки (подходит для небольших систем)
Ethereum WebSocket API поддерживает eth_subscribe:
-
newHeads— новые блоки -
logs— события смарт-контрактов по фильтру -
newPendingTransactions— mempool (ненадёжно, не использовать для финансов)
const { ethers } = require("ethers");
const provider = new ethers.WebSocketProvider(process.env.WS_RPC_URL);
// Подписка на Transfer события ERC-20
const filter = {
address: USDC_CONTRACT,
topics: [
ethers.id("Transfer(address,address,uint256)"),
null,
ethers.zeroPadValue(WATCHED_ADDRESS, 32), // только входящие
],
};
provider.on(filter, async (log) => {
const parsed = iface.parseLog(log);
await processIncomingTransfer({
txHash: log.transactionHash,
from: parsed.args.from,
amount: parsed.args.value,
blockNumber: log.blockNumber,
});
});
Проблема: WebSocket-соединение падает. Нужен reconnect с восстановлением пропущенных событий — запрос eth_getLogs за пропущенный диапазон блоков при реконнекте.
2. Indexer-сервис (для средних и крупных систем)
The Graph, Ponder, или собственный indexer на базе eth_getLogs с курсором. Схема:
RPC Node → Indexer Worker → PostgreSQL (indexed events) → API → Clients
Indexer хранит last_processed_block, при рестарте продолжает с того же места. Batching запросов: eth_getLogs за диапазон блоков (рекомендуется по 1000–2000 блоков за раз).
3. Webhook-провайдеры (самое быстрое внедрение)
Helius (Solana), Alchemy (EVM), QuickNode Streams берут мониторинг на себя, вызывая ваш endpoint при событиях. Подходит, когда инфраструктурная простота важнее полного контроля.
Реорганизация цепи (chain reorg)
Это самое неочевидное место. Blockchain reorg — это нормальное явление, особенно на малых глубинах. Транзакция с 3 confirmations может исчезнуть. Система, которая не обрабатывает reorg, периодически показывает пользователям "оплаченные" заказы, которые потом откатываются.
Правило: не помечать транзакцию как финальную до достижения безопасной глубины:
| Сеть | Безопасная глубина | Финализация |
|---|---|---|
| Ethereum | 12+ подтверждений (~2.5 мин) | Checkpoint (slots, ~13 мин) |
| Bitcoin | 6 подтверждений (~60 мин) | Probabilistic |
| Polygon PoS | 256 подтверждений (~8 мин) | Checkpoint в Ethereum |
| Solana | finalized (~15 сек) | Однозначная |
Реализация статусной машины для транзакции:
pending → confirming (1+ conf) → confirmed (12+ conf) → finalized
↓
reorged → needs_retry
При обнаружении reorg (блок с нашей транзакцией был заменён): откат статуса, уведомление, повторная проверка.
Хранение и индексирование
Минимальная схема таблицы транзакций:
CREATE TABLE tracked_transactions (
id BIGSERIAL PRIMARY KEY,
tx_hash VARCHAR(66) NOT NULL,
network VARCHAR(20) NOT NULL,
block_number BIGINT,
block_hash VARCHAR(66), -- для детекта reorg
from_address VARCHAR(42),
to_address VARCHAR(42),
value_raw NUMERIC(78, 0), -- wei/lamports, без потери точности
token_contract VARCHAR(42),
status VARCHAR(20) DEFAULT 'pending',
confirmations INT DEFAULT 0,
metadata JSONB,
first_seen_at TIMESTAMPTZ DEFAULT now(),
confirmed_at TIMESTAMPTZ,
UNIQUE(tx_hash, network)
);
CREATE INDEX idx_tracked_tx_address ON tracked_transactions(to_address);
CREATE INDEX idx_tracked_tx_status ON tracked_transactions(status)
WHERE status NOT IN ('finalized', 'failed');
block_hash позволяет обнаружить reorg: если блок с нашим block_number имеет другой hash — произошёл форк.
Мониторинг самого indexer'а
Метрика indexer_lag_blocks — насколько indexer отстаёт от head цепи. Если lag > 50 блоков — алерт: либо RPC упал, либо indexer перегружен. Добавляем в Prometheus/Grafana или хотя бы Uptime Robot с webhook.
Что входит в разработку системы
- Компонент получения событий (WebSocket + fallback polling)
- Обработчик reorg с откатом статусов
- Worker подтверждений (обновляет счётчик confirmations)
- REST/WebSocket API для фронтенда
- Webhook delivery для внешних систем (с retry и dead-letter queue)
- Dashboard текущего состояния indexer'а







