Мы часто сталкиваемся с проблемой: смарт-контракты не хранят историю состояния в удобном для запросов виде. eth_getLogs с фильтром по событиям — это грубый инструмент: нет сортировки, нет агрегации, нет связей между событиями разных контрактов. В итоге фронтенд либо тащит тонны данных и обрабатывает их на клиенте, либо команда поднимает собственный индексирующий бэкенд. The Graph решает эту задачу стандартным способом — вы описываете, что индексировать, а сеть делает это за вас. Наша команда разработала более 20 subgraph для DeFi-протоколов и NFT-маркетплейсов, накопив опыт в оптимизации и отладке. Получите консультацию по вашему проекту — поможем спроектировать схему и выбрать стек.
Subgraph — это по сути декларация: какие контракты слушать, какие события обрабатывать, как трансформировать данные в entities. Написать его правильно с первого раза сложнее, чем кажется.
Как оптимизировать schema для GraphQL-запросов?
Схема должна проектироваться исходя из того, какие запросы нужны фронтенду — не из структуры событий контракта. Типичная ошибка: делать entities один-к-одному с событиями. Это ведёт к тому, что фронтенд делает N+1 запросов. Денормализованные entities с предагрегированными данными сокращают количество запросов в 3–5 раз.
Правильный подход — денормализованные entities с предагрегированными данными:
type Pool @entity { id: ID! # address пула token0: Token! token1: Token! feeTier: BigInt! totalVolumeUSD: BigDecimal! # накопительный объём — обновляем в каждом Swap totalValueLockedUSD: BigDecimal! txCount: BigInt! swaps: [Swap!]! @derivedFrom(field: "pool") } type Swap @entity { id: ID! # txHash + logIndex pool: Pool! sender: Bytes! recipient: Bytes! amount0: BigDecimal! amount1: BigDecimal! amountUSD: BigDecimal! timestamp: BigInt! blockNumber: BigInt! } @derivedFrom — виртуальная связь, не хранит массив ID в записи Pool. Это важно для производительности: пул с тысячами свапов не будет расти в размере записи. Пример запроса, который фронтенд может выполнять:
{ pools(first: 10) { id totalVolumeUSD swaps(first: 5) { amountUSD timestamp } } } Почему AssemblyScript опасен для разработчиков TypeScript?
AssemblyScript — строго типизированный язык, компилируется в WebAssembly. Привычки из TypeScript здесь опасны:
// НЕПРАВИЛЬНО — null reference в AS вызывает панику let pool = Pool.load(event.address.toHexString()) pool.txCount = pool.txCount.plus(BigInt.fromI32(1)) // pool может быть null // ПРАВИЛЬНО let poolId = event.address.toHexString() let pool = Pool.load(poolId) if (pool === null) { pool = new Pool(poolId) pool.txCount = BigInt.fromI32(0) pool.totalVolumeUSD = BigDecimal.fromString("0") } pool.txCount = pool.txCount.plus(BigInt.fromI32(1)) pool.save() BigDecimal для финансовых значений — обязательно. BigInt из контракта нужно конвертировать с учётом decimals токена:
function convertTokenToDecimal(tokenAmount: BigInt, exchangeDecimals: BigInt): BigDecimal { if (exchangeDecimals == BigInt.fromI32(0)) { return tokenAmount.toBigDecimal() } return tokenAmount.toBigDecimal().div( BigInt.fromI32(10).pow(exchangeDecimals.toI32() as u8).toBigDecimal() ) } Как отладить медленную синхронизацию?
Если subgraph синхронизируется медленнее ожидаемого, выполните проверку:
- Посчитайте количество callHandlers — замените на eventHandlers где возможно. eventHandlers в 5–10 раз быстрее.
- Убедитесь, что startBlock не слишком ранний. Идеально — блок деплоя контракта.
- Проверьте количество eth_call в handlers — каждый вызов контракта из mapping добавляет RPC-запрос.
- Используйте ipfs.cat минимально — это медленная операция.
| Тип обработчика | Скорость | Применение |
|---|---|---|
| eventHandlers | Быстро (2000–5000 блоков/мин) | Любые события, эмитированные контрактом |
| callHandlers | Медленно (в 5–10 раз медленнее) | Если контракт не эмитит событий |
| blockHandlers | Очень медленно | Только когда нет альтернативы, с filter: { kind: once } |
Типичные ошибки в обработчиках:
- Забывают проверить null перед Pool.load
- Указывают startBlock = 0
- Используют callHandlers вместо eventHandlers там, где можно наоборот
- Не конвертируют BigInt в BigDecimal с учётом decimals
Как выбрать между Hosted Service и Decentralized Network?
Для production протоколов рекомендуется децентрализованная сеть: она обеспечивает censorship resistance и устойчивость к отключению. Hosted Service бесплатен, но подходит только для разработки и тестирования. Сравнение:
| Hosted Service | Decentralized Network | |
|---|---|---|
| Стоимость | Бесплатно (сервис закрывается) | GRT токены (Indexer fees) |
| Latency | Низкая | Выше (~100–500ms) |
| Censorship resistance | Нет (centralized) | Да |
| SLA | Без гарантий | Зависит от Indexers |
| Подходит для | Разработка, тестирование | Production с требованием decentralization |
Для деплоя в децентрализованную сеть используйте Graph Studio:
graph auth --studio <deploy-key> graph codegen && graph build graph deploy --studio <subgraph-name> Подробнее об архитектуре можно прочитать в документации The Graph. Свяжитесь с нами для консультации по выбору сети и оптимизации схемы.
Процесс разработки subgraph: этапы и сроки
Мы работаем по следующей схеме:
- Анализ ABI контрактов и определение списка событий и вызовов для индексации.
- Проектирование GraphQL-схемы под конкретные запросы фронтенда (с упором на денормализацию).
- Написание AssemblyScript-обработчиков с учётом обработки null, конвертации BigInt и оптимизации производительности.
- Локальное тестирование с помощью graph-cli и дебаггинг медленных мест.
- Деплой в выбранную сеть и настройка мониторинга синхронизации.
Сроки зависят от сложности контрактов и количества сущностей: от 3 до 10 рабочих дней. Стоимость рассчитывается индивидуально после анализа вашего проекта.
Что входит в нашу работу по разработке subgraph
- Анализ ABI контрактов и определение нужных events/calls
- Проектирование schema под конкретные запросы фронтенда
- Написание и тестирование AssemblyScript handlers
- Оптимизация производительности (экономия до 40% на RPC-запросах за счёт денормализации)
- Деплой и мониторинг синхронизации
- Документация GraphQL endpoints и примеры запросов
Наша команда имеет многолетний опыт в разработке блокчейн-решений, более 30 успешных проектов на Ethereum, Polygon, BNB Chain, Solana. Закажите разработку subgraph у профессионалов и получите быструю индексацию без компромиссов.







