Адреса смарт-контрактов
В этом разделе будут описаны особенности адресации смарт-контрактов в блокчейне TON. Также будет объяснено, как акторы являются синонимами смарт-контрактов на TON.
Все является умным контрактом
В TON смарт-контракты строятся с использованием модели [Actor model] (/learn/overviews/ton-blockchain#single-actor). Фактически, акторы в TON технически представлены в виде смарт-контрактов. Это означает, что даже Ваш кошелек является простым актором (и смарт-контрактом).
Как правило, акторы обрабатывают входящие сообщения, изменяют свое внутреннее состояние и в результате генерируют исходящие сообщения. Именно поэтому каждый актор (т.е. смарт-контракт) в блокчейне TON должен иметь адрес, чтобы иметь возможность получать сообщения от других акторов.
В виртуальной машине Ethereum (EVM) адреса полностью отделены от смарт-контрактов. Не стесняйтесь узнать б ольше о различиях, прочитав нашу статью "Шесть уникальных аспектов блокчейна TON, которые удивят разработчиков Solidity", написанную Талом Колом.
Адрес смарт-контракта
Адреса смарт-контрактов, работающих на TON, обычно состоят из двух основных компонентов:
-
(workchain_id): обозначает ID рабочей цепи (знаковое 32-битное целое число)
-
(account_id) обозначает адрес аккаунта (64-512 бит, в зависимости от рабочего цепочки)
В разделе этой документации, посвященном обзору сырых адресов, мы обсудим, как выглядят пары (workchain_id, account_id).
Идентификатор рабочей цепи и идентификатор учетной записи
Идентификатор рабочей цепи
Как мы уже видели ранее, на блокчейне TON можно создать до 2^32
рабочих цепей. Мы также отметили, что адреса смарт-контрактов с 32-битным префиксом идентифицируют и связываются с адресами смарт-контрактов в разных рабочих цепях. Это позволяет смарт-контрактам отправлять и получать сообщения в разные рабочие цепочки TON Blockchain и из них.
В настоящее время в блокчейне TON работает только мастерчейн (workchain_id=-1) и время от времени основной workchain (workchain_id=0).
Оба они имеют 256-битные адреса, поэтому мы предполагаем, что workchain_id равен либо 0, либо -1, а адрес внутри рабочей цепочки точно равен 256 битам.
Идентификатор счета
Все идентификаторы учетных записей на TON используют 256-битные адреса на Мастерчейне и Бейсчейне (или базовом рабочем цепочке).
Фактически, идентификаторы аккаунта (account_id) определяются как хэш-функции для объектов смарт-контракта (в частности, SHA-256). Каждый смарт-контракт, работающий на блокчейне TON, хранит два основных компонента. К ним относятся:
- Скомпилированный код. Логика смарт-контракта, скомпилированная в виде байткода.
- Инициальное состояние. Значения контракта в момент его развертывания на цепи.
Наконец, чтобы точно определить адрес контракта, необходимо вычислить хэш, соответствующий паре (Начальный код, Начальное состояние) объектов. Сейчас мы не будем глубоко вникать в то, как работает TVM, но важно понимать, что идентификаторы счетов на TON определяются по такой формуле: : account_id = hash(начальный код, начальное состояние).
Со временем, на протяжении всей этой документации, мы будем углубляться в технические характеристики и обзор схемы TVM и TL-B. Теперь, когда мы знакомы с генерацией account_id и их взаимодействием с адресами смарт-контрактов на TON, давайте объясним, что такое Raw и User-Friendly адреса.
Обращается к государству
Каждый адрес может находиться в одном из возможных состояний:
nonexist
- по этому адресу не было принято ни одной транзакции, поэтому он не содержит никаких данных (или контракт был удален). Можно сказать, что изначально все2256 адресов находятся в таком состоянии.uninit
- адрес имеет некоторые данные, которые содержат баланс и мета-информацию. В этом состоянии у адреса еще нет кода смарт-контракта/постоянных данных. Адрес переходит в это состояние, например, когда он не существовал, и какой-то другой адрес отправил ему токены.Активный
- адрес имеет код смарт-контракта, постоянные данные и баланс. В этом состоянии он может выполнять некоторую логику во время транзакции и изменять свои постоянные данные. Адрес переходит в это состояние, когда он былuninit
и поступило сообщение с параметром state_init (обратите внимание, что для развертывания этого адреса хэш изstate_init
иcode
должен быть равен адресу).заморозка
- адрес не может выполнять никаких операций, это состояние содержит только два хэша предыдущего состояния (ячейки кода и состояния соответственно). Когда заряд памяти адреса превышает его баланс, он переходит в это состояние. Чтобы разморозить его, Вы можете послать внутреннее сообщение сstate_init
иcode
, которые хранят описанные ранее хэши и некоторое количество Toncoin. Восстановить его может быть сложно, поэтому не стоит допускать такой ситуации. Существует проект по размораживанию адреса, который Вы можете найти здесь.
Сырые и удобные адреса
После краткого обзора того, как адреса смарт-контракто в на TON используют рабочие цепи и идентификаторы учетных записей (для Мастерчейна и Бейсчейна в частности), важно понять, что эти адреса выражаются в двух основных форматах:
- Сырые адреса: Оригинальное полное представление адресов смарт-контрактов.
- Удобные для пользователя адреса: Удобные для пользователя адреса - это улучшенный формат сырого адреса, который обеспечивает лучшую безопасность и простоту использования.
Ниже мы расскажем о различиях между этими двумя типами адресов и более подробно рассмотрим, почему на TON используются удобные для пользователя адреса.
Сырой адрес
Необработанные адреса смарт-контрактов состоят из идентификатора рабочей цепи и идентификатора учетной записи (workchain_id, account_id) и отображаются в следующем формате:
- [десятичный workchain_id]:[64 шестнадцатеричных цифр с account_id].
Ниже приведен пример необработанного адреса смарт-контракта, в котором используются идентификатор рабочей цепи и идентификатор учетной записи вместе (выраженные как workchain_id и account_id):
-1:fcb91a3a3816d0f7b8c2c76108b8a9bc5a6b7a55bd79f8ab101c52db29232260
Обратите внимание на -1
в начале строки адресов, которая обозначает workchain_id, принадлежащий Мастерчейну.
Прописные буквы (такие как 'A', 'B', 'C', 'D' и т.д.) могут использоваться в адресных строках вместо их строчных аналогов (таких как 'a', 'b', 'c' 'd' и т.д.).
Проблемы с сырыми адресами
При использовании формы "Сырой адрес" возникают две основные проблемы:
- При использовании необработанного формата адресов невозможно проверить адреса, чтобы исключить ошибки перед отправкой транзакции. Это означает, что если Вы случайно добавите или удалите символы в адресной строке перед отправкой транзакции, Ваша транзакция будет отправлена не по назначению, что приведет к потере средств.
- При использовании необработанного формата адреса невозможно добавить специальные флаги, подобные тем, что используются при отправке транзакций, в которых используются удобные для пользователя адреса. Чтобы помочь Вам лучше понять эту концепцию, ниже мы объясним, какие флаги можно использовать.
Удобный для пользователя адрес
Удобные адреса были разработаны для обеспечения безопасности и упрощения работы пользователей TON, которые обмениваются адресами в Интернете (например, на публичных платформах обмена сообщениями или через своих поставщиков услуг электронной почты), а также в реальном мире.
Удобная структура адресов
Удобные для пользователя адреса состоят всего из 36 байт и получаются путем генерации следующих компонентов по порядку:
-
[флаги - 1 байт] - Флаги, которые прикрепляются к адресам, изменяют способ реакции смарт-контрактов на полученное сообщение. Типы флагов, использующие удобный формат адреса, включают:
- isBounceable. Обозначает отскакивающий или неотскакивающий тип адреса. (0x11 для "bounceable", 0x51 для "non-bounceable")
- isTestnetOnly. Обозначает тип адреса, используемый только для целей тестовой сети. Адреса, начинающиеся с 0x80, не должны приниматься программным обеспечением, работающим в рабочей сети
- isUrlSafe. Обозначает устаревший флаг, который определен как URL-safe для адреса. После этого все адреса считаются безопасными для URL.
-
[workchain_id - 1 байт] - Идентификатор рабочей цепи (workchain_id) определяется подписанным 8-битным целым числом workchain_id.
(0x00 для BaseChain, 0xff для MasterChain) -
[account_id - 32 байта] - ID счета состоит из (big-endian) 256-битного адреса в рабочей цепочке.
-
[Проверка адреса - 2 байта] - В дружественных адресах проверка адреса состоит из CRC16-CCITT-подписи из предыдущих 34 байт. (Пример) На самом деле, идея, относящаяся к проверке для дружественных адресов, очень похожа на алгоритм Luhn, который используется на всех кредитных картах, чтобы предотвратить ввод пользователями несуществующих номеров карт по ошибке.
Сложение этих 4 основных компонентов означает, что: 1 + 1 + 32 + 2 = 36
байт в сумме (на один удобный для пользователя адрес).
Чтобы сгенерировать удобный для пользователя адрес, разработчик должен закодировать все 36 байт, используя либо:
- base64 (т.е. с цифрами, латинскими буквами верхнего и нижнего регистра, '/' и '+')
- base64url (с '_' и '-' вместо '/' и '+')
После этого процесса создание удобного для пользователя адреса длиной 48 символов без пробелов завершается.
На TON вместо необработанных и удобных для пользователя адресов иногда используются DNS-адреса, такие как mywallet.ton. На самом деле, DNS-адреса состоят из удобных для пользователя адресов и включают в себя все необходимые флаги, которые позволяют разработчикам получить доступ ко всем флагам из DNS-записи в домене TON.