Парсинг данных NFT-коллекций: floor price, volume, holders и аналитика

Парсинг данных NFT-коллекций (floor price, volume, holders) OpenSea API возвращает floor price с задержкой 5-15 минут и агрегирует данные по своей методологии. Для торговых ботов, аналитических платформ и minting dApps, которым нужен реальный floor — это неприемлемо. **Мы разрабатываем парсеры, к

Направления блокчейн-разработки

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1451
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1309
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1005
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1270
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    719
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    1011

Парсинг данных NFT-коллекций (floor price, volume, holders)

OpenSea API возвращает floor price с задержкой 5-15 минут и агрегирует данные по своей методологии. Для торговых ботов, аналитических платформ и minting dApps, которым нужен реальный floor — это неприемлемо. Мы разрабатываем парсеры, которые читают события прямо из блокчейна, обеспечивая точность до секунды. Это единственный способ получить актуальный floor без задержек.

Наш опыт — 5+ лет в блокчейн-разработке и десятки проектов по парсингу NFT-данных. Мы знаем все тонкости: реорганизации цепочек, rate limits валидаторов, wash trading и как их обрабатывать. Гарантируем стабильную работу парсера даже на высоконагруженных коллекциях.

В этой статье разберём полную архитектуру парсера NFT-данных: выбор стека, индексирование событий, вычисление floor price, хранение в ClickHouse и типовые проблемы. Также покажем, что входит в наше решение под ключ.

Источники данных: что откуда брать

On-chain события

Для ERC-721/ERC-1155 коллекций все продажи видны через события маркетплейсов. Каждый маркетплейс эмитирует собственное событие:

  • OpenSea Seaport: OrderFulfilled(...) — контракт 0x00000000000000ADc04C56Bf30aC9d3c0aAF14dC
  • Blur: TakerAsk / TakerBid на 0x000000000000Ad05Ccc4F10045630fb830B95127
  • LooksRare v2: TakerAsk / TakerBid
  • X2Y2: EvInventory

Floor price нельзя получить из событий напрямую — события показывают исполненные ордера, а не активные листинги. Для актуального floor нужно либо индексировать active listings через маркетплейс API, либо использовать агрегаторы.

Holders и transfers

Transfer(address indexed from, address indexed to, uint256 indexed tokenId) — стандарт ERC-721. Полный граф владения строится через replay всех Transfer событий от блока деплоя. Unique holders = уникальные адреса to за вычетом адресов, которые затем перевели токены на другой адрес.

Для ERC-1155: TransferSingle и TransferBatch. Здесь владение — это баланс, не бинарное состояние: balanceOf(address, tokenId).

Как мы вычисляем floor price?

Два подхода:

1. Маркетплейс API агрегация — запрашиваем floor у OpenSea, Blur, LooksRare, берём минимум. Проблема: rate limits и кэширование на стороне API. Мы используем кэш на 60 секунд и fallback при превышении лимитов.

2. Orderbook индексирование — подписываемся на события создания/отмены ордеров. Seaport: OrderValidated (создание), OrderCancelled, OrderFulfilled (исполнение). Строим локальный orderbook, вычисляем floor самостоятельно. Точнее, но сложнее в поддержке при обновлениях контрактов маркетплейса. Мы рекомендуем первый подход для большинства проектов, второй — для торговых ботов с субсекундным откликом.

Метод Точность Сложность Задержка
API агрегация Средняя Низкая ~60 сек
Orderbook Высокая Средняя <5 сек

Архитектура парсера

Стек

ethereum-node (Alchemy/Infura/Quicknode) → ethers.js / viem (event filtering) → message queue (Redis Streams / BullMQ) → PostgreSQL / ClickHouse (storage) → REST/WebSocket API (выдача данных) 

Для исторических данных — getLogs с фильтром по address и topics[0]. Блоки батчим по 2000 (ограничение большинства RPC провайдеров на eth_getLogs):

async function fetchTransferEvents( contract: string, fromBlock: number, toBlock: number, provider: JsonRpcProvider ) { const iface = new Interface(['event Transfer(address indexed from, address indexed to, uint256 indexed tokenId)']); const filter = { address: contract, topics: [iface.getEventTopic('Transfer')], fromBlock, toBlock, }; const logs = await provider.getLogs(filter); return logs.map(log => iface.parseLog(log)); } 

Для real-time: WebSocket подписка через provider.on(filter, callback) или Alchemy eth_subscribe newLogs.

Хранение и запросы

ClickHouse эффективнее PostgreSQL для time-series NFT данных — аналитические запросы на миллионах строк в 10-50x быстрее. Схема:

Колонка Тип Описание
block_number UInt64 Блок события
tx_hash FixedString(66) Хэш транзакции
contract FixedString(42) Адрес коллекции
token_id UInt256 ID токена
from FixedString(42) Продавец/отправитель
to FixedString(42) Покупатель/получатель
price_wei UInt256 Цена в wei
marketplace LowCardinality(String) Маркетплейс
timestamp DateTime Время блока

Партиционирование по месяцам (toYYYYMM(timestamp)), сортировочный ключ (contract, timestamp).

Почему on-chain данные точнее OpenSea API?

OpenSea API использует собственный пул ордеров и кэширует floor price с задержкой до 15 минут. Это критично для арбитражных ботов и аналитики в реальном времени. On-chain данные — единственный источник истины. Мы гарантируем точность до последнего подтверждённого блока (финализация за 2 эпохи — 64 блока на Ethereum PoS).

Решение типовых проблем

Rate limits

Alchemy Free — 330 CUPS, Growth — 660 CUPS. При историческом парсинге крупной коллекции (BAYC: 500k+ Transfer событий) без throttling получим 429. Реализуем exponential backoff + queue с concurrency control.

Как избежать rate limits при историческом парсинге? Используйте exponential backoff и несколько RPC эндпоинтов. Мы настраиваем очередь с максимум 5 параллельных запросов и таймаутом 30 секунд.

Реорганизации блокчейна

События из последних 12 блоков нужно помечать как «pending» и подтверждать только после finality. Для Ethereum PoS — 2 эпохи (64 блока) для экономического finality.

Wash trading

Объём по адресам с циклическими переводами искажает статистику. Базовая эвристика: сделки где from и to — связанные адреса (получали ETH из одного источника) помечаются флагом.

Что входит в работу

  • Архитектура парсера под вашу задачу
  • Код на TypeScript с использованием ethers.js/viem
  • Настройка ClickHouse для хранения и аналитики
  • Дашборд в Grafana с ключевыми метриками (floor price, volume, holders)
  • REST/WebSocket API для интеграции с вашим приложением
  • Полная документация и обучение команды
  • Поддержка после запуска

Мы предоставляем решение под ключ. Оценим ваш проект за 1 день.

Ориентиры по срокам

Парсер Transfer событий + holders tracker — 1 день. Добавление floor price через маркетплейс API + кэш — ещё полдня. Исторический бэкфилл для крупной коллекции + дашборд — 2-3 дня суммарно.

Свяжитесь с нами, чтобы получить консультацию и точную оценку для вашего проекта.