Головна
перший урок
наступний

Як працюють блокчейн-індексери і навіщо вони потрібні

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

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

Просте пояснення роботи індексерів

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

У бібліотеці на полицях зберігаються тисячі книг. Зазвичай вони відсортовані за жанрами та прізвищами авторів. Читач швидко знайде полицю з романами Лавкрафта чи довідник із садівництва.

Але припустимо, читач хоче знайти щось конкретне: вірш про акацію, роман про архітектора заправки, або всі книги, написані в 1962 році. Йому доведеться перевіряти всі книги у бібліотеці, доки не знайде потрібні.

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

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

Детально про базу даних та індекси

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

Розробники також часто називають базами даних СУБД — системи управління базами даних, тобто програми для роботи з базами даних. До них відносяться MySQL, PostgreSQL, Oracle Database, Microsoft Access та інші.

Більшість баз даних — реляційні. Вони не просто сортують і записують дані в таблиці, а й створюють між ними зв'язки. Наприклад, база даних бібліотеки може використовувати три таблиці:

  • Список книг. Назви всіх книг у бібліотеці та інформація про них;
  • Список читачів Ім'я кожного читача та його контактні дані;
  • Книги на руках. Реєстр книг, які хтось узяв почитати. Комірка з назвою книги посилається на запис у Списку книг, а комірка з ім'ям читача — на запис у Списку читачів.

1

Ці таблиці допоможуть організувати зберігання даних. Але вони не надто прискорять пошук книг, тому що для знаходження конкретного значення в цій таблиці доведеться використовувати повільний і неефективний пошук row-by-row.

Щоб прискорити пошук, можна зберігати дані не в таблиці, а в складнішій структурі даних, наприклад в збалансованому бінарному дереві (B-Tree).

Для прикладу розглянемо B+ Tree. Корінь і вузли допомагають маршрутизувати запит, а посилання на комірки в основній таблиці або значення зберігається в листях.

2

Допустимо, нам потрібно знайти запис про книгу Ender's Game. Пошук відбудеться так:

  1. Літера E у назві Ender's Game менше літери N у Netherlan, вибираємо ліву гілку.
  2. Літера E менше літери G у The God Machine, вибираємо ліву гілку.
  3. Літера E більше літери C у The Call of Chtulu, вибираємо праву гілку.
  4. Знайшли комірку з Ender's Game.

B+ Tree та інші деревоподібні структури зберігання даних добре оптимізують пошук. Наприклад, якщо в базі даних є мільйон рядків, то для пошуку одного конкретного знадобиться не більш ніж 20 операцій. Без використання дерева кількість операцій може досягати кількості рядків у таблиці, тобто мільйону.

Дані можна зберігати прямо в дереві, але набагато ефективніше використовувати його як додатковий індекс. У прикладі з книгами бібліотекар міг би зробити індекси B-Tree для кожного типу ключів: назви книг, авторів, імен читачів, їх контактних даних і дат, коли вони взяли та повернули книги.

Чим більше стовпців та потенційних ключів у базі даних, тим більше індексів можна створити для ефективного пошуку, а вони займають місце. У 2019 році Baking Bad розповіли, що індекси бази даних розміром 1 ГБ займають у чотири рази більше місця.

3

Навіщо потрібні індексери у блокчейні

Блокчейн-протоколи працюють завдяки нодам, які обробляють операції, забезпечують безпеку мережі, і найголовніше — зберігають копії блоків у хронологічному порядку. Ноди валідаторів умовно поділяються на два типи: легкі з копією останніх блоків та архівні з повним блокчейном. Користувач може отримати ончейн-дані з власної або публічної ноди за допомогою інтерфейсу Remote Procedure Call API (RPC), щоб запитати дані з блокчейна.

Однак RPC не призначений для роботи зі складними запитами та швидкого пошуку по блокчейну. Наприклад, щоб отримати деталі про операцію, потрібно точно знати, де їх шукати.

Спробуємо отримати дані про транзакцію за допомогою Tezos client та RPC API — opRjkzJxJ1xZaUnBDykGUjrRV8qgHFvchcYnbkkcotS1Y7idCSL.

4

Виділений синім рядок на скріншоті — команда, яку ми використовували для отримання даних:

tezos-client rpc get /chains/main/blocks/2283698/operations/3/2.

Цифри в команді означають таке:

  • 2283698 — рівень блоку, в якому була операція;
  • 3 — індекс типу джерела (ініціатора) операції. 3 означає, що її ініціював користувач;
  • 2 — індекс операції у конкретному блоці.

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

Індексери спрощують завдання отримання потрібних даних із блокчейну. Вони запитують у нод повні блоки і записують їх у власні бази даних. Потім індексери створюють власне індекси — додаткові структури даних, оптимізовані під швидкий пошук даних (пам'ятаєте B-Tree?), які зберігають самі дані, або посилання на відповідне місце в основній базі даних. При пошуку будь-яких даних індексер шукає їх у відповідному індексі, а не в основній базі.

5

На скріншоті контракт USDT, проіндексований Que Pasa. Індексер створив таблиці кожної точки входу і структури даних у сховищі, і навіть створив індекс кожної таблиці. З їх допомогою ми можемо знайти баланс випадкового власника USDT на його адресу за 0,064 мілісекунди замість того, щоб годинами перевіряти блоки в пошуках останньої операції та зміни балансу вказаної адреси.

6

Список таблиць, схем індексів та синтаксис запитів залежить від індексера та бази даних, яку він використовує. Наприклад, аналогічний запит балансу USDT від публічного TzKT буде виглядати так:

https://api.tzkt.io/v1/tokens/balances?token.contract=KT1XnTn74bUtxHfDtBmm2bGZAQfhPbvKWR8o&account=tz1a1RTsGUbads3VucUQDxJF4EDXkDWcDHPK
  • жовтий — просто посилання на TzKT API;
  • зелений — шлях до таблиці бази даних TzKT з балансами токенів;
  • синій, починається з ? — Перший пошуковий фільтр, в якому ми вказуємо адресу необхідного договору;
  • червоний, починається з & — другий пошуковий фільтр, у якому ми вказуємо адресу власника.

Крім швидкого пошуку за базою даних, індексування має ще одну перевагу перед пошуком по блокчейну: можливість кастомізувати правила індексування. Наприклад, TzKT надає токенам додатковий індекс, у якому кожному FA1.2 і FA2 токену присвоюється внутрішній id. В результаті замість пошуку за порівняно довгою адресою контракту індексер порівнюватиме короткі числа, що зробить пошук даних швидше.

7

Блокчейн-індексери поділяються на два типи: повні та селективні.

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

Найкращі приклади повних індексерів з публічними API — TzKT і TzStats. Вони дозволяють знайти практично будь-яку інформацію, яка колись потрапила до блокчейну Tezos.

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

З популярних селективних індексерів ми розглянемо Que Pasa та фреймворки для створення індексерів DipDup та Dappetizer. Їх використовують багато проєктів Tezos, наприклад Teia.art та інші NFT-маркетплейси, зробили власні індексери на базі DipDup для роботи з NFT.

Які дані можна отримати через блокчейн-індексер

Точний список запитів та фільтрів залежить від вибраного індексу. Але загалом від повного індексера можна отримати інформацію про:

  • аккаунт — баланс tez, історію операцій, тип адреси, статуси на кшталт «бейкер» та «делегатор» та інше;
  • блок — хедер, зміст блоку, метадані на кшталт адреси та соцмереж бейкера, який його створив;
  • контракт — опис, точки входу, баланс, код Michelson, зміст сховища або конкретної big map;
  • бейкерів і делегаторів — хто скільки заробив, хто ендорсив конкретний блок, скільки делегують користувачі;
  • протокол — який зараз цикл, що на голосуванні, яка емісія tez.

Ми взяли кілька цікавих та простих прикладів для виклику індексерів BetterCallDev та TzKT. Перейдіть за посиланнями та вставляйте в адресний рядок свою адресу замість tz1…9v4, щоб отримати дані про свій гаманець:

Де застосовуються індексери

Багато додатків, які працюють з ончейн-даними, використовують індексери.

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

8

Спробуйте самі: перейдіть за цим посиланням та замініть tz1…9v4 на адресу свого гаманця. TzKT поверне вам баланси всіх токенів, які є на вашій адресі. Це той самий запит до TzKT API, який використовує Temple: '/tokens/balances' у константах getTokenBalances та getNFTBalances.

За таким же принципом, Temple Wallet отримує деталі операцій, відображає NFT, нагороди за делегування, вартість ваших токенів та інші дані. Однак, для різних запитів він використовує різні джерела, наприклад, курс XTZ він запитує у Coingecko.

Інші блокчейн-додатки працюють за схожим принципом:

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

Tezos Ukraine запитали MadFish Solutions, Kukai Wallet, Plenty DeFi, youves та розробників інших популярних проєктів Tezos, якими індексерами вони користуються. Результати цікаві: для роботи одного додатку потрібно від двох до п'яти індексерів: публічні індексери для загальних даних, self-hosted-повні для особливо важливих та селективні індексери для інтерфейсу. Ми докладно розповімо про види індексерів, їх переваги та недоліки у наступному уроці.

Неочевидні завдання, які вирішують розробники індексерів

По-перше, Tezos еволюціонує. Нова версія протоколу може, наприклад, змінити схему відповіді від RPC-ноди, через що індексер буде неправильно індексувати блоки.

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

При реорганізації блокчейн-оглядачі та індексери також повинні видалити з бази даних та індексів відкинуті блоки. У 2015 році у тестовій мережі Bitcoin відбулася реорганізація довжиною у 100 блоків, яка зламала частину блокчейн-оглядачів.

Розробники індексерів враховують можливість реорганізації. Наприклад, TzKT при реорганізації блокчейну Tezos відкочується назад блок за блоком, і починає йти новою гілкою. Якщо для вирішення завдання не потрібні дані в реальному часі, в self-hosted TzKT можна налаштувати затримку індексування. Після впровадження алгоритму консенсусу Tenderbake реорганізація можлива лише для двох блоків, тому затримки у два блоки достатньо.

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

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

Відповіді

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

У TzKT це вже реалізовано в окремому API Endpoint:

https://api.tzkt.io/v1/tokens/balances?account=tz1UEQzJbuaGJgwvkekk6HwGwaKvjZ7rr9v4

Використовувати індексер набагато простіше, ніж отримувати дані безпосередньо від RPC-ноди. Для цього спочатку потрібно отримати хеш адреси користувача за допомогою команди:

tezos-client hash data '"{address}"' of type address

9

Потім знайти id big_map balances потрібного контракту. Наприклад, у контракті стейблкоіна Kolibri USD id потрібної big_map — 380. Тепер можна зробити запит:

tezos-client get element exprvEJ9kYbvt2rmka1jac8voDT4xJSAiy48YJdtrXEVxrdZJRpLYr of big map 380

10

В результаті отримаємо кількість токенів на адресі, але як завжди — без ком.

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