Индексация данных: The Graph и subgraph
Нода плохо отвечает на вопросы «покажи историю и агрегаты». The Graph индексирует данные контракта и отдаёт их через GraphQL.
The Graph — протокол индексации блокчейн-данных. Subgraph — описание, какие события контракта собирать и в какие сущности складывать; фронт запрашивает их обычным GraphQL.
Мы уже видели: прочитать «все переводы за всё время» напрямую с ноды нельзя — eth_getLogs ограничен диапазоном, а агрегаций («топ-10», «сумма за неделю») у ноды нет вовсе. Для дашбордов, лент и поиска это тупик. The Graph решает его, превращая разрозненные события в нормальную базу с GraphQL-запросами.
Почему нельзя «просто читать с ноды»
- Нода хранит текущее состояние, а не удобную историю запросов.
eth_getLogsпо большому диапазону — медленно и ограничено провайдером.- Нет JOIN, GROUP BY, сортировки, пагинации — всё это пришлось бы делать на клиенте поверх тысяч логов.
Как устроен subgraph
Subgraph — это три части: схема сущностей (что хранить), манифест (какой контракт и события слушать) и маппинги (код, превращающий событие в запись). Индексатор проходит по всем блокам, ловит события и наполняет базу. Результат фронт запрашивает GraphQL'ом:
query {
transfers(first: 10, orderBy: value, orderDirection: desc) {
from
to
value
blockNumber
}
}Это уже привычная фронтендеру работа: GraphQL-запрос, как к любому API. Никаких eth_getLogs и ручной агрегации.
Что остаётся на ноде, а что уходит в The Graph
| Через ноду (ethers/wagmi) | Через The Graph |
| Текущий баланс, текущее состояние | История переводов |
| Отправка транзакции | Лента активности, агрегаты |
| Чтение одного значения | Поиск, сортировка, пагинация |
Правило: «сейчас и записать» — нода; «история и аналитика» — индексатор.
Как работает под капотом
Индексатор The Graph синхронизируется с сетью блок за блоком. На каждом блоке он смотрит, не сработали ли отслеживаемые события; если да — вызывает ваш маппинг, который создаёт/обновляет сущности в базе (обычно Postgres). Поверх базы поднят GraphQL-сервер. Фронт шлёт ему запрос и получает уже готовые, отсортированные, агрегированные данные. Важно: данные в subgraph чуть «отстают» от головы сети (индексация занимает время), поэтому для свежайшего состояния всё равно нужна нода.
Частые ошибки
- Тянуть историю с ноды на клиенте. Не масштабируется; используйте индексатор.
- Брать критичный текущий баланс из subgraph. Он может отставать; для «прямо сейчас» читайте ноду.
- Считать The Graph обязательным для любого dApp. Для простого приложения без истории он избыточен.
Итоги
- Нода не умеет историю и агрегаты — для них есть индексаторы.
- The Graph через subgraph превращает события в GraphQL-API.
- «Сейчас/записать» — нода; «история/аналитика» — The Graph.