После деплоя смарт-контракта начинается самое интересное: нужно понимать, что с ним происходит в реальном времени. Мы сталкивались с проектами, где мониторинг отсутствовал — и это приводило к потере средств. Без системы on-chain метрик вы узнаете о проблеме только когда пользователи начнут жаловаться, а атакующий уже выведет ликвидность. Мониторинг on-chain метрик — это не роскошь, а необходимость для любого DeFi-проекта с TVL от $1M. В этой статье я поделюсь реальным опытом настройки такой системы и дам готовый код, который вы можете адаптировать под свои контракты.
«Realtime on-chain monitoring is the first line of defense for any DeFi protocol.» — говорят наши инженеры с опытом более 100 проектов.
Мы используем стек: Ethereum (через viem с WebSocket), Prometheus + Alertmanager, Grafana, TimescaleDB. Все компоненты проверены в production на проектах с TVL более $10M. Наша система обрабатывает до 2000 событий в секунду — этого достаточно для любого DeFi-протокола. У нас более 5 лет опыта в блокчейн-разработке, выполнено свыше 50 проектов по мониторингу DeFi.
Какие метрики on-chain мониторинга важны для DeFi?
Основные группы метрик
| Метрика | Тип | Задержка | Важность |
|---|---|---|---|
| TVL | Операционная | Реалтайм | Критическая |
| DAU/MAU | Бизнес- | Реалтайм | Высокая |
| Failed-транзакции (%) | Операционная | Реалтайм | Средняя |
| Крупные выводы > $100K | Безопасность | Реалтайм | Алерт |
Операционные метрики: частота вызовов ключевых функций, gas consumption по методам (аномальный рост может означать дорогие операции или атаку), доля failed-транзакций (рост выше 10% — повод для алерта), TVL.
Бизнес-метрики: DAU/MAU on-chain (уникальные адреса за период), retention — адреса, вернувшиеся через N дней, объём в USD через конкретные функции, топ-N адресов по активности (whale alert detector).
Безопасность: крупные выводы, необычные паттерны вызовов (flash loan + контракт в одном блоке), изменения admin-роли, вызовы с новых адресов с большим балансом.
Почему реалтайм-мониторинг критичен?
Пропущенная аномалия может стоить миллионы. Пример из нашей практики: у клиента внезапно упал TVL на 30% за час. Без мониторинга команда узнала об этом через сутки из твиттера. Оказалось, что атакующий использовал flash loan для манипуляции ценой. Мы настроили алерт на резкое падение TVL — теперь подобные инциденты обнаруживаются за минуты. On-chain метрики — это глаза вашего протокола.
Архитектура системы мониторинга on-chain метрик
Источники данных
| Источник | Задержка | Сложность | Применимость |
|---|---|---|---|
| Event logs | Реалтайм (WebSocket) | Низкая | Основной: любые действия контракта |
| Trace calls | Реалтайм (debug) | Высокая | Движение средств между контрактами |
| Storage slots | Реалтайм (RPC) | Средняя | TVL, балансы, неэмитируемые метрики |
| Dune Analytics | 10–30 мин | Низкая | Ретроспективный анализ, SQL-запросы |
Event logs — самый быстрый и дешёвый способ получения данных (Event logging). Они обеспечивают задержку менее 500 мс, что в 20 раз быстрее Dune Analytics. Если ваш контракт не эмитирует нужные события — добавьте их (при обновляемости) или используйте trace calls.
Схема потоков
┌─────────────────┐
│ Blockchain RPC │
│ (Alchemy/own) │
└────────┬────────┘
│
│ eth_getLogs / WebSocket
┌────────▼──────────────┐
│ Event Collector │
│ (подписка на контракт)│
└────────────┬──────────────┘
│
┌────────────▼──────────────┐
│ Metrics Processor │
│ Декодирование ABI, │
│ агрегация, enrichment │
└──────┬────────────┬────────┘
│ │
┌────────────▼──┐ ┌──────▼──────────────┐
│ TimescaleDB │ │ Prometheus/VictoriaDB│
│ (история) │ │ (реалтайм метрики) │
└───────────────┘ └──────────────────────┘
│
┌─────────▼──────────┐
│ Grafana Dashboard │
│ + Alertmanager │
└────────────────────┘
Техническая реализация
Event collector на viem
import { createPublicClient, webSocket, parseAbiItem, decodeEventLog } from 'viem';
import { mainnet } from 'viem/chains';
const client = createPublicClient({
chain: mainnet,
transport: webSocket('wss://eth-mainnet.g.alchemy.com/v2/YOUR_KEY'),
});
const CONTRACT_ABI = [
parseAbiItem('event Deposit(address indexed user, uint256 amount)'),
parseAbiItem('event Withdraw(address indexed user, uint256 amount)'),
parseAbiItem('event Swap(address indexed user, address tokenIn, address tokenOut, uint256 amountIn, uint256 amountOut)'),
];
const unwatch = client.watchContractEvent({
address: CONTRACT_ADDRESS,
abi: CONTRACT_ABI,
onLogs: async (logs) => {
for (const log of logs) {
await processEvent(log);
}
},
onError: (error) => {
console.error('WS error, reconnecting...', error);
},
});
async function processEvent(log: any) {
const decoded = decodeEventLog({
abi: CONTRACT_ABI,
...log
});
await db.query(`
INSERT INTO contract_events (time, block_number, tx_hash, event_name, user_address, amount_usd)
VALUES (NOW(), $1, $2, $3, $4, $5)
`, [log.blockNumber, log.transactionHash, decoded.eventName, decoded.args.user, await convertToUSD(decoded.args.amount)]);
eventCounter.labels(decoded.eventName).inc();
}Prometheus метрики и алерты
import { Counter, Gauge, Registry } from 'prom-client';
const registry = new Registry();
const eventCounter = new Counter({
name: 'contract_events_total',
help: 'Total contract events by type',
labelNames: ['event_name'],
registers: [registry],
});
const tvlGauge = new Gauge({
name: 'contract_tvl_usd',
help: 'Total Value Locked in USD',
registers: [registry],
});
const largeWithdrawalCounter = new Counter({
name: 'contract_large_withdrawals_total',
help: 'Withdrawals above threshold',
labelNames: ['threshold_category'],
registers: [registry],
});
app.get('/metrics', async (req, res) => {
res.set('Content-Type', registry.contentType);
res.send(await registry.metrics());
}); Alertmanager правила
groups:
- name: contract_security
rules:
- alert: LargeWithdrawal
expr: rate(contract_large_withdrawals_total[5m]) > 0
for: 0m
labels:
severity: critical
annotations:
summary: "Large withdrawal detected"
- alert: HighFailureRate
expr: |
rate(contract_failed_txns_total[10m]) / rate(contract_total_txns_total[10m]) > 0.1
for: 5m
annotations:
summary: "More than 10% of transactions failing"
- alert: TVLDrop
expr: |
(contract_tvl_usd - contract_tvl_usd offset 1h) / contract_tvl_usd offset 1h < -0.2
for: 2m
annotations:
summary: "TVL dropped by more than 20% in 1 hour"Event collector обрабатывает до 2000 событий в секунду без потерь при правильной настройке бэка.
Алерты безопасности
Помимо реалтайм-алертов, полезно отслеживать крупные транзакции и flash loan паттерны. Мы реализуем это через отдельный сервис, который анализирует события по порогу (например, $100 000) и проверяет последовательность вызовов в одном блоке. При обнаружении отправляется алерт с деталями. Всё работает на базе тех же event logs.
Grafana дашборд
Ключевые панели для DeFi протокола:
- Overview: TVL (gauge + time series), 24h Volume, DAU, Total Users (cumulative)
- Activity: Events per minute (разбивка по типу), Gas used per block, Failed tx ratio
- Security: Large transactions (таблица с последними whale-транзакциями), New whale addresses, Flash loan detection events
- Economics: Fee revenue over time, Token price correlation с активностью контракта
Дашборд версионируется в git вместе с кодом контракта.
Исторические данные и ретроспективный анализ
Для ретроспективы используем TimescaleDB и SQL:
-- Ежедневные активные пользователи
SELECT date_trunc('day', time) AS day,
COUNT(DISTINCT user_address) AS dau,
SUM(amount_usd) AS volume_usd
FROM contract_events
WHERE event_name IN ('Deposit', 'Swap')
GROUP BY 1
ORDER BY 1 DESC;
-- Retention: пользователи вернувшиеся через 7 дней
WITH first_use AS (
SELECT user_address,
MIN(time) AS first_time
FROM contract_events
GROUP BY 1
),
return_use AS (
SELECT DISTINCT e.user_address
FROM contract_events e
JOIN first_use f ON e.user_address = f.user_address
WHERE e.time > f.first_time + INTERVAL '7 days'
AND e.time < f.first_time + INTERVAL '14 days'
)
SELECT COUNT(r.user_address)::float / COUNT(f.user_address) AS week1_retention
FROM first_use f
LEFT JOIN return_use r ON f.user_address = r.user_address; Объём работ
- Event collector: настройка подписки на события контракта через WebSocket, запись в TimescaleDB.
- Prometheus метрики: экспорт ключевых метрик (TVL, volume, failure rate) через prom-client.
- Grafana дашборд: визуализация операционных, бизнес- и security-метрик с версионированием в git.
- Алерты в Alertmanager: правила для критических событий (TVL drop, large withdrawal, high failure rate).
- Whale detector: оповещения о крупных транзакциях и flash loan паттернах.
- Документация и runbook: инструкции по реагированию на инциденты.
- Обучение команды: передача знаний по эксплуатации системы.
Процесс развёртывания: пошаговая инструкция
- День 1: Настройка event collector. Подключаемся к RPC, создаём подписку на события контракта через viem WebSocket. Записываем сырые события в TimescaleDB. Тестируем на реальных транзакциях.
- День 2: Prometheus и Grafana. Определяем метрики, экспортируем их через prom-client. Строим первый дашборд с TVL, объёмом, частотой событий. Настраиваем базовые алерты (TVL drop, high failure rate).
- День 3: Безопасность и Whale detector. Добавляем алерты на крупные выводы и flash loan паттерны. Интегрируем уведомления в Telegram/PagerDuty. Тестируем через симуляцию атак. Готовим runbook.
Итого 1–3 дня в зависимости от сложности контракта. Работаем с Ethereum, Polygon, Arbitrum, Solana. Гарантируем SLA на работу системы.
Для заказа системы мониторинга вашего DeFi-проекта свяжитесь с нами.
Выбор стека
Основной выбор — между готовыми платформами (Dune, Flipside) и собственной инфраструктурой. Dune хорош для быстрой аналитики, но имеет задержку 10–30 минут и vendor lock-in. Собственный стек мониторинга (Prometheus + Grafana) даёт реалтайм и полный контроль. Мы рекомендуем комбинировать: собственный стек для реалтайм-реагирования и Dune для ретроспективных отчётов. Для проектов с TVL более $1M собственный стек обязателен.
Убытки от одной атаки могут быть огромными, а затраты на настройку мониторинга составляют малую долю. Получите консультацию по настройке мониторинга — свяжитесь с нами для аудита вашего проекта. Мы оценим ваш проект.







