Учимся доставать данные из блокчейна TON на примере ранжирования Жеттонов

Вступление

Часто в криптомире слова децентрализация, смарт-контракты — это всего лишь оболочка для скама или, мягко говоря, нечестных схем.

Страждущие заработать на волнах хайпа оказываются перед проблемой исследования и поиска проектов, что приводит их к необходимость исследования данных из блокчейна и сбора информации о проекте.

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

В TON последние пару месяцев все внимание приковано к Жетонам — стандарту взаимозаменяемых токенов. Появляется много проектов и нужна какая-то отправная точка в исследованиях. 

В этой статье мы разберемся как находить транзакции включающие в себя передачу жетонов и про ранжируем часть жетонов по количество транзакций. И все это с позиции, как вообще может быть устроен процесс раскопки данных.

Дисклеймер: Данная статье не рекламирует никакие проекты, а только лишь предлагает разобраться в сборе данных через индексатор блокчейна на небольшой прикладной задаче.

Откуда будем брать данные? — dton.io 

dton.io

dton.io

Dton.io индексатор блокчейна, что значит, он собирает информацию из каждого нового блока в свою базу данных. В эту базу данных можно делать GraphQL запросы и таким образом собирать историческую информацию без парсинга всей цепочки блоков.

Две самых важных источника данных dton.io это таблица транзакций и представление последнего состояния кошельков/аккаунтов в сети. Также есть различные вспомогательные представления.

В данном туториале нам пригодятся таблица транзакций и представление с пред рассчитанным количеством тех или иных транзакций.

Как находить нужные транзакции

Индексатор dton.io позволяет забирать информацию GraphQL запросами, и вот перед нами рыба запроса:

```python

query = »«

query MyQuery {

}

»«

```

Что делать дальше? — возможных аргументов больше ста. Алгоритм простой на словах, сложный в деталях:

  • изучаем смарт-контракты, которые нас интересуют

  • фиксирует цепочки сообщений между контрактами, которые нам нужны

  • из двух шагов выше получаем аргументы для нашего запроса

Начнем со смарт-контрактов.

Что за Жеттоны?

в TON у него название Жеттон

в TON у него название Жеттон

Жеттон это стандарт взаимозаменяемого токена в сети TON. Для того, чтобы токены можно было использовать в других приложениях (от кошельков до децентрализованных бирж) вводятся стандарты интерфейсов смарт-контрактов для токенов. Интерфейс в данном случае это некая сигнатура — (синтаксическая конструкция объявления функции.

Стандарты смарт-контрактов предполагают публичное обсуждение. В TON это происходит здесь — https://github.com/ton-blockchain/TEPs/blob/master/text/0074-jettons-standard.md

Внутри расписана основная логика, а также есть некоторая простая реализация.  

Рассмотрим стандарт Жетон

Подробно разбирать стандарт Жеттон мы не будем, так как у меня есть отдельная статья про это — https://github.com/romanovichim/TonFunClessons_ru/blob/main/lessons/smartcontract/9lesson/ninthlesson.md. Отметим, ключевые на данном этапе идеи:

Токен стандарта Жетон должен состоять из двух видов смарт-контрактов:

Каждый Жетон имеет основной смарт-контракт (будем называть его мастер контракт), который используется для чеканки новых Jetton, учета общего предложения и предоставления общей информации о токене.

Информация о количестве жетонов, принадлежащих каждому пользователю, хранится в смарт-контрактах, называемых Jetton кошельком.

## Вступление

Часто в криптомире слова децентрализация, смарт-контракты — это всего лишь оболочка для скама или, мягко говоря, нечестных схем.

Страждущие заработать на волнах хайпа оказываются перед проблемой исследования и поиска проектов, что приводит их к необходимость исследования данных из блокчейна и сбора информации о проекте.

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

В TON последние пару месяцев все внимание приковано к Жетонам — стандарту взаимозаменяемых токенов. Появляется много проектов и нужна какая-то отправная точка в исследованиях. 

В этой статье мы разберемся как находить транзакции включающие в себя передачу жетонов и проранжируем часть жетонов по количество транзакций. И все это с позиции, как вообще может быть устроен процесс раскопки данных.

Дисклеймер: Данная статье не рекламирует никакие проекты, а только лишь предлагает разобраться в сборе данных через индексатор блокчейна на небольшой прикладной задаче.

### Откуда будем брать данные? — dton.io 

3e0067ef0efde5b4e1f9f65e0ccde8fe.jpeg

Dton.io индексатор блокчейна, что значит, он собирает информацию из каждого нового блока в свою базу данных. В эту базу данных можно делать GraphQL запросы и таким образом собирать историческую информацию без парсинга всей цепочки блоков.

Две самых важных источника данных dton.io это таблица транзакций и представление последнего состояния кошельков/аккаунтов в сети. Также есть различные вспомогательные представления.

В данном туториале нам пригодятся таблица транзакций и представление с пред рассчитанным количеством тех или иных транзакций.

## Как находить нужные транзакции

Индексатор dton.io позволяет забират информацию GraphQL запросами, и вот перед нами рыба запроса:

```python

query = »«

query MyQuery {

}

»«

```

Что делать дальше? — возможных аргументов больше ста. Алгоритм простой на словах, сложный в деталях:

  • изучаем смарт-контракты, которые нас интересуют

  • фиксирует цепочки сообщений между контрактами, которые нам нужны

  • из двух шагов выше получаем аргументы для нашего запроса

Начнем со смарт-контрактов.

### Что за Жеттоны?

0e027f74dc4c44ca535e00da0c6ee93b.jpeg

Жеттон это стандарт взаимозаменяемого токена в сети TON. Для того, чтобы токены можно было использовать в других приложениях (от кошельков до децентрализованных бирж) вводятся стандарты интерфейсов смарт-контрактов для токенов. Интерфейс в данном случае это некая сигнатура — (синтаксическая конструкция объявления функции.

Стандарты смарт-контрактов предполагают публичное обсуждение. В TON это происходит здесь — https://github.com/ton-blockchain/TEPs/blob/master/text/0074-jettons-standard.md

Внутри расписана основная логика, а также есть некоторая простая реализация.  

### Рассмотрим стандарт Жетон

Подробно разбирать стандарт Жеттон мы не будем, так как у меня есть отдельная статья про это — https://github.com/romanovichim/TonFunClessons_ru/blob/main/lessons/smartcontract/9lesson/ninthlesson.md. Отметим, ключевые на данном этапе идеи:

Токен стандарта Жетон должен состоять из двух видов смарт-контрактов:

Каждый Жетон имеет основной смарт-контракт (будем называть его мастер контракт), который используется для чеканки новых Jetton, учета общего предложения и предоставления общей информации о токене.

Информация о количестве жетонов, принадлежащих каждому пользователю, хранится в смарт-контрактах, называемых Jetton кошельком.

Internal transfer

После первичного ознакомления со смарт-контрактами, нужно обратить внимание, на op коды — это код, который отображает, что должен сделать смарт-контракт. 

cba3fc0a5f01eaec34495d5f30b479fe.png

После беглого просмотра op кодов, нужно вычленить подходящие под вашу задачу и отрисовать процесс. Рассмотрим процесс:

1. отправитель отправляет сообщение op: transfer на свой кошелек jetton.

2. sender_jetton_wallet уменьшает баланс токена

3. sender_jetton_wallet отправляет сообщение op: internal_transfer на кошелек получателя.

4. recipient_jetton_wallet увеличивает баланс своих токенов

5. recipient_jetton_wallet отправляет op: transfer_notification своему владельцу (TON кошелек получателя)

*есть еще и излишек, но в статье мы это опустим, предлагаю читателю самому ознакомиться со стандартом

После этого, для удобства отрисуем процесс отправки Жеттонов:

в данном случае выглядит просто, но когда контрактов становиться 5-6 задача сильно усложняется

в данном случае выглядит просто, но когда контрактов становиться 5–6 задача сильно усложняется

Судя по этой схеме, нам нужен internal transfer, именно сообщения с internal transfer позволят нам собрать отправку Жеттонов с кошелька на кошелек.

Для более сложных цепочек контрактов, также важно прописывать какие данные передаются внутри, так как не каждое сообщение несет информацию о некоторой бизнес операции — чаще только необходимый минимум. Особенно это акутально для DEX. Еще раз повторюсь, на данном этапе мы ищем транзакции, который позволяет нам собрать нужную информацию.

Собираем информацию об одном Жеттоне

После того как мы определились нужными транзакциями, сократим задачу, до минимальной — в нашем случае это поиск информации об одном Жеттоне. 

Для ваших исследований, предлагаю следующее эмпирическое правило — сокращает задачу, то того момента, пока его нельзя будет проверить в эксплорере. То есть, чтобы выполнив запрос, вы могли найти транзакцию и понять, нашли ли вы правильную информацию. 

Обозначим эндпойнт dton.io (весь код из данного туториала будет доступен в конце в Google Colab):

```python

endpoint = 'https://dton.io/graphql/'

```

Создадим пустой запрос:

```python

query = »«

query MyQuery {

}

»«

response = requests.post (endpoint, json={'query': query})

if response.status_code == 200:

  data = response.json ()['data']

  print (data)

else:

  print (response.json ())

```

Для нашей цели — подсчета количества транзакций Жеттона, есть удобное представление lastTransactionCountSegments его мы и будем использовать. Внутрь положим нужный op_code — internal transfer и адрес мастер контракта любого жеттона (так как это не рекламная статья, что за жеттон говорить не буду, если вы хотите попробовать какой-то другой жеттон, можете взять его здесь — в ссылках сразу hex формат адреса https://tonlearn.tools/#/jetton-dash).

В данном случаем мы можем взять op_code прямо из стандарта, чтобы перевести его из байтов в 32-integer, воспользуемся вот этим сайтом: https://cryptii.com/pipes/integer-encoder

По итогу получим:

```python

endpoint = 'https://dton.io/graphql/'

query = »«

query MyQuery {

  lastTransactionCountSegments (

    parsed_jetton_wallet_jetton_address_address: «F4BDD480FCD79D47DBAF6E037D1229115FEB2E7AC0F119E160EBD5D031ABDF2E»

    in_msg_op_code: 395134233

      segmentation: «day»

      days: 30) {

    segment

    cnt

  }

}

»«

response = requests.post (endpoint, json={'query': query})

if response.status_code == 200:

  data = response.json ()['data']

  print (data)

else:

  print (response.json ())

```

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

Перейдем к ранжированию

Список Жеттонов

Чтобы было что ранжировать, нужен некоторый список мастер-контрактов Жеттонов, собрать его можно было бы, просто делая запросы в таблицу состояний контрактов в сети —  account_states. Но это имеет мало смысла — мы получим огромный список Жеттонов, по части из которых будет максимум 1 — 2 транзакции. Поэтому предлагаю, простой метод, взять адреса из общедоступного списка Жеттонов, которые отобржает в своем интерфейсе один из популярный кошельков на TON:

```python

url = «https://raw.githubusercontent.com/tonkeeper/ton-assets/main/jettons.json»

resp = requests.get (url=url)

jettons_list = resp.json ()

jettons_list[0]

```

Google Colab с кодом будет в конце туториала

Google Colab с кодом будет в конце туториала

Важно отметить, что это опенсорсный список и в нем бывают ошибки, например, иногда адреса хранятся в разных форматах. Поэтому конструируя следующий запрос, нам надо будет вычистить лишнее. 

Конструируем запрос

Для сбора информации в разрезе Жеттона, нужно просто конкатенировать запросы:

```python

formatted_query_cnt =»

for token in jettons_list:

  # if not hex skip

  if (token['address'].upper ()[0:2]!='0:'):

    #print (token['address'].upper ()[0:2])

    continue

  #cut workchain from address

  temp_addr = token['address'].upper ()[2:]

  template = string.Template (»«

    seq${addr_cut}: lastTransactionCountSegments (

      in_msg_op_code: 395134233

      segmentation: «day»

      days: 30

      parsed_jetton_wallet_jetton_address_address: ${addr_dop}

    ) {

      segment

      cnt

    }

  »«)

  formatted = template.substitute (addr_cut = temp_addr, addr_dop= '»'+temp_addr+'»')

  formatted = formatted +»\n»

  formatted_query_cnt += formatted

formatted_query = »«query {»«+formatted_query_cnt+»«}»«

response_cnt = requests.post (endpoint, json={'query': formatted_query})

response_cnt

```

Лимит конкатенации — 100, но по моему опыту, важно оценивать, насколько сложно вычислимый запрос и отталкиваться от этого.

Сортируем и обсуждаем результат

После, соберем и отсортируем данные, данный код в статью добавлять не буду, все есть в Google Colab:

https://colab.research.google.com/drive/1h6fFy2OaTntlUXNKJLaVztuOGH-A_NIg? usp=sharing

Результат примерно следующий:

500ebe31732f2f79d1d0a342d69ef811.png

Отмечу, что это учебная задача, ранжировать по транзакциям Жеттоны применимо к реальным задачам довольно сложно, так как многие Жеттоны накручиваю объемы сделок на DEX и подобные сделки нужно вычищать. 

Заключение

Мне нравится блокчейн TON своей технической изящностью, как минимум это не очередная копия Ethereum, которую разгоняют с помощью большого капитала без оглядки, а вообще зачем это нужно пользователю. Если вы хотите узнать больше о блокчейне TON, у меня есть опенсорсные уроки, благодаря которым вы научитесь создавать полноценные приложения на TON.

https://github.com/romanovichim/TonFunClessons_ru

Новые туториалы и дата аналитику я кидаю сюда: https://t.me/ton_learn

Код данного туториала:  

https://colab.research.google.com/drive/1h6fFy2OaTntlUXNKJLaVztuOGH-A_NIg? usp=sharing

© Habrahabr.ru