Головна

Повні та селективні індексери Tezos

Команди екосистеми Tezos розробили близько десятка блокчейн-індексерів. Умовно їх можна розділити на дві категорії:

  • повні індексують весь блокчейн. Їх використовують блокчейн-браузери та програми, яким може знадобитися зберігати всі важливі дані на своїх серверах;
  • селективні — індексують лише вказані адреси та смарт-контракти. Їх використовують блокчейн-додатки.

Ми зв'язалися з MadFish Solutions, Kukai Wallet, Plenty DeFi, youves та розробниками інших проєктів на Tezos, щоб дізнатися, якими індексерами вони користуються. Найчастіше вони використовують TzIndex, TzKT та Que Pasa, а також фреймворк DipDup для створення власних селективних індексерів.

Зараз розповімо про ці індексери, а в наступних уроках розглянемо використання в проєктах публічного TzKT API, а також селективних індексерів: простого Que Pasa, просунутого DipDup та нового цікавого індексера Dappetizer.

Який індексер для чого підходить

За допомогою TzKT та TzStats (TzIndex, якщо говорити про self-hosted варіант) можна отримати будь-які ончейн-дані Tezos: від версії Octez, яку використовує конкретний бейкер, до вмісту смарт-контракту big_map. При цьому вони мають відмінності:

  • TzKT API підтримує різні фільтри та сортування відповідей за значеннями у вибраному стовпці. Наприклад, можна відсортувати баланси власників конкретного токена за їх розміром;
  • TzStats API не підтримує просунуте сортування — його потрібно реалізувати на стороні клієнта. Натомість у нього є своя унікальна фіча: Time Series API дозволяє розробникам отримати історичні дані щодо балансів, статистики мережі Tezos та токену tez з агрегацією за вказаним часовим відрізком. Це корисно для аналітики.

За допомогою Que Pasa та DipDup можна отримати лише дані зі смарт-контрактів, а Dappetizer також підтримує індексацію інших даних з блоків.

1

Термінологія та трохи технічних деталей

У попередньому уроці ми пояснювали бази даних та індекси на прикладі книг та говорили про індексери загалом. Зараз ми будемо використовувати загальноприйняту термінологію для опису баз даних та індексування:

  • поле (field) — комірка у базі даних. Приклад: сума однієї транзакції, адреса одного користувача;
  • рядок (row) — горизонтальна сукупність полів, які пов’язані з одним ключем. Наприклад, у рядку про одну транзакцію будуть поля з хешем, адресами відправника та одержувача, сумою, комісіями та іншими даними про операцію;
  • колонка чи стовпець (column) — вертикальна сукупність полів одного типу. Приклад: стовпець «Сума транзакції» міститиме лише поля із сумами транзакцій;
  • схема бази даних або модель даних — опис структури таблиць та зв'язків між ними.

Завдання блокчейн-індексера — не просто вносити дані з блоків до таблиці та створювати індекси, але створити таку схему, щоб оптимізувати продуктивність бази даних, обсяг індексів та кількість можливих запитів. Наприклад, навряд чи хтось шукатиме операцію за сумою транзакційних комісій, тож публічні індексери не використовують такий індекс.

Публічні та self-hosted індексери

За місцем хостингу індексери бувають публічними та self-hosted. Публічний індексер хостить третя сторона і надає доступ всім бажаючим, а self-hosted розробник запускає на власній машині.

Публічні API можна використовувати для експериментів та тестування, але для запуску додатка в продакшн краще клонувати індексер та запустити його у себе, тобто в режимі self-hosted.

По-перше, при використанні self-hosted індексера розробник зможе швидше отримувати дані та не чекати у черзі, якщо публічний API буде перевантажений. TzStats та TzKT в угоді на використання API попереджають, що можуть обмежувати додатки, які надто часто надсилають запити.

По-друге, self-hosted індексер можна модифікувати під завдання проєкту. Селективні індексери Que Pasa, DipDup та Dappetizer будуть зберігати в базі даних та індексувати лише ті дані, які вкаже розробник, а роботу повних індексерів TzKT та TzIndex можна налаштувати через систему управління базою даних типу PostgreSQL.

По-третє, розробники блокчейн-браузерів з публічним API оновлюють їх і можуть змінити схеми запитів чи відповідей. При використанні публічних індексерів доведеться стежити за оновленнями та підлаштовуватися під них.

Також деякі користувачі можуть не довіряти розробнику програми, тому що є ризик, що dApp відображає неправильну інформацію. У такому випадку користувач може запустити власний індексер і перевірити дані або запросити їх у публічного індексера, якому він довіряє.

Як працює TzKT

Індексер TzKT розробила команду Baking Bad. Його використовує однойменний оглядач TzKT.io.

Схема роботи TzKT виглядає так:

  1. TzKT перевіряє останній блок у своїй базі даних PostgreSQL та звіряє його з останнім блоком у Tezos.
  2. Якщо останнього блоку Tezos ще немає в базі даних, TzKT перевіряє його валідність.
  3. Якщо блок валідний, індексер розпізнає дані в блоці за попередньо описаними моделями даних, а потім послідовно додає їх в базу даних в окремих операціях. Якщо в блокчейні відбувається реорганізація, індексер автоматично відкочує операції, що не порушує структуру бази даних.
  4. PostgreSQL приймає дані та оновлює індекси загальної бази даних.
  5. Модуль API TzKT виконує запити до бази даних.

Крім звичного індексування всієї інформації з блоку, TzKT має кілька унікальних фіч:

  • привласнення токенам ідентифікаторів, яке спрощує їх пошук;
  • оновлення в реальному часі — TzKT підтримує WebSocket API та може отримувати інформацію про нові транзакції, виклики смарт-контрактів та інші операції в мережі Tezos у реальному часі;
  • автоматична валідація одержаних блоків через порівняння блоку з «еталоном». Так індексер переконується, що обробив дані правильно та не отримав жодних несподіваних даних;
  • можливість звантажити снапшот бази даних та використовувати його для швидкого запуску self-hosted індексера замість того, щоб індексувати блокчейн з нуля;
  • індексування токенів та офчейн-метаданих з IPFS. TzKT розпізнає смарт-контракти токенів big_map зі структурою реєстру (ledger), описаної в TZIP-12.

Ліцензування: Baking Bad дозволяють безкоштовно використовувати TzKT у self-hosted режимі та публічний TzKT API, але з додаванням до проєкту дисклеймера "Powered by TzKT".

Щоб оптимізувати роботу API, розробники використовують горизонтальне масштабування. Вони реплікують базу даних, щоб запити різних джерел отримували дані з різних копій однієї бази.

2

Для запуску індексера потрібна машина із 4 ГБ оперативної пам'яті або більше. Що більше RAM, то більше місця можна виділити під кешування даних прискорення пошуку даних. Як і індекси, кешування можна налаштувати: вимкнути повністю, зменшити або збільшити розмір для конкретного типу даних.

Снапшот бази даних займає 60 ГБ, а разом з усіма індексами TzKT може використовувати 300-400 ГБ. Отже, TzKT краще запускати на машині з жорстким диском об'ємом 500 ГБ або 1 ТБ.

За допомогою TzKT можна отримати такі дані:

  • head — статус індексу: поточна мережа, останній проіндексований блок, останній timestamp;
  • протокол — інформація про всі версії протоколу Tezos: рівні першого та останнього блоків, час створення блоку, ліміт газу, слоти ендорсменту та інше;
  • голосування — пропозиції (proposals), адреси бейкерів, що проголосували, періоди голосувань;
  • цикли Tezos — рівень початку та завершення, загальний стейк, кількість делегаторів;
  • делегати — інформацію про конкретний делегат: баланс, рівень активації, кількість делегаторів;
  • бейкінг — нагороди за бейкінг та делегування, версії ПЗ, на якому працюють ноди;
  • акаунти — баланси та метадані адрес, дата останньої активності, делегування та інша інформація;
  • bigmap — інформація про bigmap, ключі, значення, апдейти ключів та історичні значення;
  • блоки — повний вміст блоків з різними можливостями для сортування, наприклад, за обсягом транзакційних комісій;
  • глобальні константи;
  • смарт-контракти — код, опис, стан та схема сховища, bigmap-и контракту;
  • операції — транзакції, делегування, активації облікових записів, а також операції з роллапами, спроби подвійного бейкінгу, внесення пропозицій та інші;
  • котирування Tezos до фіатних валют та криптовалют;
  • винагороди за бейкінг та делегування за цикл;
  • статистика мережі за вказаний період;

Приклади використання:

Найбільша транзакція kUSD — $1,17 млн!

Запит має такий вигляд:

https://api.tzkt.io/v1/tokens/transfers?token.contract=KT1K9gCRgaLRFKTErYt1wVxA3Frb9FjasjTV&limit=1&sort.desc=amount

Спочатку ми запитаємо таблицю /tokens/transfers/. Потім додаємо фільтри: token.contract з адресою контракту kUSD, limit=1 щоб отримати лише один рядок, і sort.desc=amount, щоб отримати рядок з найбільшим значенням amount.

3

Дані про всі протоколи Tezos: перший блок протоколу, слоти ендорсмента блоку, вартість байта та інші параметри.

Це простий запит до таблиці /protocols/ — https://api.tzkt.io/v1/protocols/

4

Останні спроби подвійного бейкінгу.

Трішки складніший запит — https://api.tzkt.io/v1/operations/double_baking?limit=5&sort.desc=level

Запитуємо таблицю /operations/double_baking/ і застосовуємо два фільтри: limit для отримання 5 рядків та sort.desc=levels , щоб отримати останні операції.

5

Як працює TzIndex

TzIndex (також відомий як Blockwatch) Tezos Indexer розробила аналітична компанія Blockwatch Data та використовує його в браузері TzStats.

Головна фіча TzIndex — кастомна стовпчикова база даних, яка зберігає інформацію в стовпцях замість рядків. За словами розробників, таке рішення краще справляється зі складними аналітичними запитами та отриманням даних.

У першому уроці ми згадували, що продуктивність сучасних баз даних упирається не в обчислювальні потужності машини, а швидкість читання з диска. Тепер пояснимо це докладніше.

Звичайні бази даних типу PostgreSQL зберігають назви полів у стовпцях, а записи — у рядках.

6

На жорсткому диску ця таблиця буде виглядати так:

[Book1, The Call of Cthulhu, Lovecraft, 1928], [Book3, The Lord of the Rings, Tolkien, 1954], [The Adventures of Tom Sawyer, Mark Twain, 1876]

Бази даних змушені повністю зчитувати рядок, навіть якщо потрібно отримати лише одне поле зі всього рядка. Так відбувається через те, що дані на диску зберігаються в кластерах — у квадратних дужках у нашому прикладі. Щоб прочитати потрібний запис, комп'ютер повинен завантажити цілий кластер. Якщо потрібні поля зберігаються у різних кластерах, доведеться повністю завантажувати ці кластери.

Допустимо, ми хочемо отримати з бази даних дати публікації всіх книг, щоб визначити найпродуктивніший рік. Пошук виглядатиме так: СУБД візьме перший рядок, послідовно прочитає записи у рядку, запише дату, потім перейде на другий рядок, послідовно прочитає записи, і так далі.

7

Стовпчикові бази враховують особливості фізичного зберігання даних і розв’язують проблему за допомогою повороту таблиць на 90°: зберігають назви полів у рядках, а дані — у стовпцях.

8

На жорсткому диску ця таблиця виглядає так:

[Book Name, The Call of Cthulhu, The Lord of the Rings, The Adventures of Tom Sawyer], [Book Author, Lovecraft, Tolkien, Mark Twain], [Publication Year, 1928, 1954, 1876].

Якщо ми запитаємо дати публікації книг, то колонкова база даних прочитає лише один рядок і поверне потрібні дати.

9

В результаті стовпчикова база даних виконуватиме комплексні запити у 2-10 разів швидше, ніж звичайна рядкова база. Розробники TzIndex у блозі наводять точну швидкість виконання запитів у своїй кастомній стовпчиковій базі даних.

10

Розробники можуть запустити TzIndex на своїй машині або скористатися індексами через TzStats API. Для роботи TzIndex, окрім швидкого жорсткого диска, потрібно щонайменше 8 ГБ оперативної пам'яті та двоядерний процесор. Проте, що більше пам'яті і ядер, то швидше працюватиме індексер.

TzIndex може працювати в трьох режимах:

  • Light — індексує всі ончейн-операції, окрім тих, що пов'язані з бейкінгом: ендорсментами, розкриттям nonce, пропозиціями, голосуваннями та іншими. Підходить для бекенду більшості децентралізованих додатків. На момент написання база даних займає 32 ГБ;
  • Full — індексує всі операції включно з бейкінгом. Підходить для всіх блокчейн-додатків, особливо тих, які працюють з даними про бейкінгу. База даних займає 38-40 ГБ;
  • Validate — при індексації кожного блоку він звіряє оновлені баланси користувачів та стану смарт-контрактів з даними archive-ноди перед тим, як додати їх до бази даних. Також наприкінці циклу Tezos індексер звіряє всі баланси у базі даних. Режим потрібен, щоб упевнитися в безпомилковості даних.

Ліцензування: Light-режим та TzStats API — безкоштовні для некомерційних проєктів. Щоб використовувати їх для заробітку або запустити self-hosted TzIndex у Full- та Validate-режимі потрібно купити передплату.

TzIndex підтримує кілька кінцевих точок API-запитів:

Explorer — детальна інформація про об'єкт з описом. Наприклад, при запиті значень конкретної big_map TzIndex поверне інформацію в звичайному JSON. Підходить для отримання конкретних значень, наприклад, для відображення балансів користувача в програмі.

Наприклад, запитаємо баланси кількох власників токена hDAO, але безпосередньо з big_map "Ledger" з id "515". Фільтри limit=1 і sort=desc означають, що ми отримаємо лише один рядок із найбільшим значенням row_id (пам'ятаєте про сортування лише за row_id?)

https://api.tzstats.com/explorer/bigmap/515/values?limit=1&sort =desc

11

Table — інформація з таблиці індексера. Відповідь важко прочитати, тому що вона не включає назви полів, але краще підходить для запиту великої кількості однотипних даних, оскільки обсяг відповіді буде меншим.

Запитаємо ту ж big_map "Ledger" смарт-контракту hDAO з тими самими параметрами: limit = 1, order = asc.

https://api.tzstats.com/tables/bigmap_values?bigmap_id=515&limit=1&order=asc

12

Time-series — історичні дані балансів, операцій, емісії tez та інших значень. Підходить для складання графіків та аналітики. Наприклад запитаємо time-series балансу випадкової адреси.

Нам потрібно вказати стартову дату, потім часовий інтервал агрегації в аргументі collapse, і нарешті адресу. Запит прикладу наступний:

  • start_date — 2021, по суті 1 січня 00:01;
  • collapse — 1d, тобто кожен рядок буде показувати баланс за один день;
  • address — просто адреса.

https://api.tzstats.com/series/balance?start_date=2021&collapse=1d&address=tz2TSvNTh2epDMhZHrw73nV9piBX7kLZ9K9m

У відповіді отримаємо набір чисел. Перше число в рядку — це timestamp в мілісекундах, друге, з точкою — баланс в tez.

13

За допомогою TzIndex можна отримати такі дані:

  • head — статус індексу: поточна мережа, останній проіндексований блок, останній timestamp;
  • протокол — інформація про всі версії протоколу Tezos: рівні першого та останнього блоків, час створення блоку, ліміт газу, слоти ендорсменту та інше;
  • голосування — пропозиції (proposals), адреси бейкерів, що проголосували, періоди голосувань;
  • цикли Tezos — рівень початку та завершення, загальний стейк, кількість делегаторів;
  • делегати — інформацію про конкретний делегат: баланс, рівень активації, кількість делегаторів;
  • бейкінг — нагороди за бейкінг та делегування, версії ПЗ, на якому працюють ноди;
  • акаунти — баланси та метадані адрес, дата останньої активності, делегування та інша інформація;
  • bigmap — інформація про bigmap, ключі, значення, апдейти ключів та історичні значення;
  • блоки — повний вміст блоків з різними можливостями для сортування, наприклад, за обсягом транзакційних комісій;
  • глобальні константи;
  • смарт-контракти — код, опис, стан та схема сховища, bigmap-и контракту;
  • операції — транзакції, делегування, активації облікових записів, а також операції з роллапами, спроби подвійного бейкінгу, внесення пропозицій та інші;
  • винагороди за бейкінг та делегування за цикл;
  • статистика мережі за вказаний період;
  • котирування Tezos до фіатних валют та криптовалют від бірж Binance, Kraken, HitBTC та інших.

Приклади використання:

  1. Отримуємо баланс USDT конкретної адреси, для цього запитуємо значення big_map Ledger контракту USDT (id 198031) за ключем адреси та id 0.

14

  1. Отримуємо інформацію про котирування tez до BTC на Binance.

15

  1. Отримуємо дані про поточну емісію tez за вказаний період: кількість токенів в обігу, створені tez для винагороди бейкерів, спалювання для оплати сховища та інші цифри.

16

Que Pasa

Que Pasa — селективний індексер смарт-контрактів на Rust. Його розробили Рік Кломп та Джон Ньюбай з TzConnect.

На відміну від TzIndex та TzKT Que Pasa працює тільки в self-hosted режимі. Головна фіча — низькі вимоги до процесора та оперативної пам'яті, можна використовувати старий ноутбук або Raspberry Pi.

Que Pasa записує всі стани зазначеного смарт-контракту в базу даних PostgreSQL: список і деталі операцій з кожною точкою входу, всі записи в сховищі, вміст big_map та інше. Користувачеві не потрібно писати код для обробки блокчейн-даних — Que Pasa робить це автоматично.

Для економії часу при першому індексуванні контракту розробники додали опцію з використанням Better Call Dev, спеціального блокчейна-браузера для отримання детальної інформації про смарт-контракти та операції з ними. Якщо вона включена, Que Pasa буде отримувати у Better Call Dev рівні блоків, у яких змінювався стан зазначеного контракту, та індексувати лише їх.

За допомогою Que Pasa можна отримати лише виклики та стан сховища контракту. Не можна отримати дані про блоки, бейкінг, баланси в tez і все, що не пов'язано з контрактами.

Ліцензування: код Que Pasa опубліковано під ліцензією MIT, і його можна безкоштовно використовувати у комерційних проєктах.

Індексер DipDup

DipDup — фреймворк для створення селективних індексерів з використанням Python, які отримуватимуть дані про виклики смарт-контрактів та їх параметри, а також стан контрактів. Його розробила команда Baking Bad.

17

DipDup працює тільки в режимі self-hosted на локальній машині або Docker. Стандартно він отримує дані від TzKT, але користувач може під'єднати інші джерела: сторонні API, RPC-ноди, ресурси на IPFS та інші.

На відміну від Que Pasa, в якому потрібно лише вказати адресу RPC-ноди та контракту для індексування, у DipDup потрібно самостійно написати логіку індексування, обробки та запису отриманих даних до бази даних. DipDup підтримує Hasura GraphQL для створення API ендпоінтів.

Ліцензування: Baking Bad опублікувала DipDup під ліцензією MIT. Його можна використовувати безкоштовно у комерційних проєктах.

Індексер Dappetizer

Dappetizer — фреймворк для створення селективних індексерів за допомогою JavaScript або TypeScript. Як і в DipDup, користувач повинен сам написати логіку індексування даних та запису до бази даних. Але на відміну від DipDup Dappetizer може індексувати не лише смарт-контракти, а й операції в блоках на кшталт поновлення балансів tez.

Dappetizer потрібно запускати в self-hosted режимі на локальній машині або Docker. Індексер отримує дані тільки від RPC-нод, тому індексування популярного контракту може зайняти кілька годин.

Dappetizer підтримує Hasura GraphQL передачі даних API.

Ліцензування: Dappetizer опубліковано під ліцензією MIT, і його можна безкоштовно використовувати у будь-яких проеєктах.

Домашнє завдання

Перегляньте документацію індексерів:

Подумайте, яким децентралізованим програмам може вистачити публічних API, і для яких завдань варто запустити індекс на своїй машині.

Публічні API можна використовувати для простого відображення ончейн-даних на зразок балансів користувача, або для простої аналітики на кшталт розрахунку прибутковість провайдерів ліквідності.

Для складної аналітики на кшталт зображання графіків з історичними цінами токенів за усередненими даними з кількох пулів ліквідності краще хостити свій індексер і оптимізувати базу даних під свої завдання.

Тепер, коли ви знаєте різницю між публічними, self-hosted повними та селективними індексерами, подумайте, який тип краще підійде для кожного з цих dApps:

  • простий блокчейн-експлорер для відображення балансів tez та токенів користувача;
  • складний блокчейн-експлорер із вбудованою аналітикою бейкінгу та смарт-контрактів;
  • гаманець Tezos з відображенням токенів, NFT та історії операцій користувача;
  • роутер ліквідності, який обирає найкращі маршрути обміну токенів у пулах ліквідності;
  • NFT-вітрина, яка показує останні змінчені NFT на вибраному NFT-маркетплейсі.

Рішення

Щоб зробити простий браузер з балансами, можна використовувати будь-який індексер Tezos крім Que Pasa — він працює зі смарт-контрактами, але не з tez. При невеликій передбачуваній кількості користувачів можна використовувати публічний індексер, оскільки потрібно робити мало запитів.

Для створення складного блокчейн-експлорера знадобиться хостити повний індексер, тому що потрібно зберігати та обробляти величезну кількість даних. Публічних API може не вистачити.

Для простого гаманця можна використовувати публічні API, щоб вимагати баланс tez, токенів і NFT та операції за адресою. Але щоб зробити гаманець безпечнішим, краще захостити власний повний індексер.

Для роутера ліквідності підійде селективний індексер, який індексуватиме контракти пулів ліквідності. З цих даних додаток буде розраховувати обмінний курс та прослизання.

Для NFT-вітрини можна використовувати селективний індексер, щоб отримувати лише релевантні про нові токени зі сховища контракту.

Поділитися в соцмережах: