Перейти к основному содержимому

Документация по адресам смарт-контрактов

warning

Эта страница переведена сообществом на русский язык, но нуждается в улучшениях. Если вы хотите принять участие в переводе свяжитесь с @alexgton.

В этом разделе описываются особенности адресов смарт-контрактов в блокчейне TON. Он также объясняет, как акторы являются синонимами смарт-контрактов в TON.

Всё является смарт-контрактом

В TON смарт-контракты создаются с использованием акторной модели. Фактически, акторы в TON технически представлены как смарт-контракты. Это означает, что даже ваш кошелек является простым актором (и смарт-контрактом).

Обычно акторы обрабатывают входящие сообщения, изменяют свои внутренние состояния и в результате генерируют исходящие сообщения. Вот почему каждый субъект (т. е. актор-контракт) в блокчейне TON должен иметь адрес, чтобы он мог получать сообщения от других акторов.

ОПЫТ EVM

В виртуальной машине Ethereum (EVM) адреса полностью отделены от смарт-контрактов. Не стесняйтесь узнать больше о различиях, прочитав нашу статью "Шесть уникальных аспектов блокчейна TON, которые удивят разработчиков Solidity" от Тала Кола.

Адрес смарт-контракта

Адреса смарт-контрактов в TON обычно состоят из двух основных компонентов:

  • (workchain_id): Обозначает идентификатор воркчейна (подписанное 32-битное целое число)

  • (account_id) Обозначает адрес аккаунта (64-512 бит, в зависимости от воркчейна)

В разделе обзора необработанных адресов этой документации мы обсудим, как представлены пары (workchain_id, account_id).

Идентификатор воркчейна и идентификатор аккаунта

Идентификатор воркчейна

Как мы уже видели ранее, можно создать до 2^32 воркчейнов, работающих на блокчейне TON. Мы также отметили, как 32-битные префиксные адреса смарт-контрактов идентифицируют и связываются с адресами смарт-контрактов в разных воркчейнов. Это позволяет смарт-контрактам отправлять и получать сообщения в разные воркчейны на блокчейне TON и из них.

В настоящее время в блокчейне TON работают только Мастерчейн (workchain_id=-1) и иногда базовый воркчейн (workchain_id=0).

Оба имеют 256-битные адреса, поэтому мы предполагаем, что workchain_id равен 0 или -1, а адрес внутри воркчейна равен ровно 256 битам.

Идентификатор аккаунта

Все идентификаторы аккаунтов в TON используют 256-битные адреса в мастерчейне и бейстчейне (также называемым базовым воркчейном).

Фактически, идентификатор учетной записи (account_id) определяется как результат применения хэш-функции (в частности, SHA-256) к объекту смарт-контракта. Каждый смарт-контракт, работающий на блокчейне TON, хранит два основных компонента:

  1. Скомпилированный код. Логика смарт-контракта, скомпилированная в байт-код.
  2. Начальное состояние. Значения контракта на момент его развертывания в цепочке.

Чтобы получить адрес контракта, вы вычисляете хэш пары (Начальный код, Начальное состояние). Мы не будем сейчас изучать, как работает TVM, но важно понимать, что идентификаторы аккаунтов в TON следуют этой формуле:

account_id = хэш(начальный код, начальное состояние)

Далее в этой документации мы более подробно рассмотрим технические характеристики схемы TVM и TL-B. Теперь, когда мы знакомы с тем, как генерируется account_id и как он взаимодействует с адресами смарт-контрактов в TON, давайте обсудим необработанные и удобные для пользователя адреса.

Состояние адресов

Каждый адрес может находиться в одном из возможных состояний:

  • nonexist - по этому адресу не было принятых транзакций, поэтому на нем нет никаких данных (или контракт был удален). Можно сказать, что изначально все 2256 адреса находятся в этом состоянии.
  • uninit - адрес имеет некоторые данные, которые содержат баланс и метаданные. В этом состоянии адрес еще не имеет кода смарт-контракта/постоянных данных. Адрес переходит в это состояние, например, когда он был в несуществующем состоянии, а другой адрес отправлял ему токены.
  • active - адрес имеет код смарт-контракта, постоянные данные и баланс. В этом состоянии он может выполнять некоторую логику во время транзакции и изменять свои постоянные данные. Адрес переходит в это состояние, когда он был uninit и было входящее сообщение с параметром state_init (обратите внимание, что для возможности развертывания этого адреса хэш state_init и code должен быть равен адресу).
  • frozen - адрес не может выполнять никаких операций, это состояние содержит только два хеша предыдущего состояния (ячейки кода и состояния соответственно). Когда стоимость хранения адреса превышает его баланс, он переходит в это состояние. Чтобы разморозить его, вы можете отправить внутреннее сообщение с 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' и т. д.).

Проблемы с необработанными адресами

Использование формы необработанного адреса создает две основные проблемы:

  1. При использовании формата необработанного адреса невозможно проверить адреса для устранения ошибок перед отправкой транзакции. Это означает, что если вы случайно добавите или удалите символы в адресной строке до отправки транзакции, ваша транзакция будет отправлена ​​по неправильному адресу, что приведет к потере средств.
  2. При использовании формата необработанного адреса невозможно добавлять специальные флаги, подобные тем, которые используются при отправке транзакций с использованием удобных для пользователя адресов. Чтобы помочь вам лучше понять эту концепцию, мы объясним ниже, какие флаги можно использовать.

Удобные для пользователя адреса

Удобные для пользователя адреса были разработаны для защиты и упрощения опыта для пользователей TON, которые делятся адресами в Интернете (например, на публичных платформах обмена сообщениями или через своих поставщиков услуг электронной почты), а также в реальном мире.

Удобная для пользователя структура адресов

Удобные для пользователя адреса состоят из 36 байтов в общей сложности и получаются путем генерации следующих компонентов в следующем порядке:

  1. [флаги - 1 байт] — Флаги, закрепленные за адресами, изменяют способ реакции смарт-контрактов на полученное сообщение. Типы флагов, которые используют удобный для пользователя формат адреса, включают:

    • isBounceable. Обозначает тип адреса, допускающий или не допускающий отклонений. (0x11 для "отклоняемого", 0x51 для "не отклоняемого")
    • isTestnetOnly. Обозначает тип адреса, используемый только для целей тестовой сети. Адреса, начинающиеся с 0x80, не должны приниматься программным обеспечением, работающим в рабочей сети
    • isUrlSafe. Обозначает устаревший флаг, который определен как безопасный для URL для адреса. Все адреса затем считаются безопасными для URL.
  2. [workchain_id - 1 байт] — идентификатор воркчейна (workchain_id) определяется 8-битным целым числом со знаком workchain_id. (0x00 для Бейсчейна, 0xff для Мастерчейна)

  3. [account_id - 32 байта] — идентификатор аккаунта состоит (от большего к меньшему) 256-битного адреса в воркчейне.

  4. [проверка адреса - 2 байта] — В удобных для пользователя адресах проверка адреса состоит из подписи CRC16-CCITT из предыдущих 34 байтов. (Пример) Фактически, идея, касающаяся проверки удобных для пользователя адресов, очень похожа на алгоритм Луна, который используется на всех кредитных картах, чтобы пользователи не вводили по ошибке несуществующие номера карт.

Добавление этих 4 основных компонентов означает, что: 1 + 1 + 32 + 2 = 36 байтов в общей сложности (на удобный для пользователя адрес).

Чтобы сгенерировать удобный для пользователя адрес, разработчик должен закодировать все 36 байтов, используя либо:

  • base64 (т. е. с цифрами, заглавными и строчными латинскими буквами, '/' и '+')
  • base64url (с '_' и '-' вместо '/' и '+')

После завершения этого процесса завершается генерация удобного для пользователя адреса длиной 48 неразделенных символов.

ФЛАГИ DNS-АДРЕСОВ

В TON DNS-адреса, такие как mywallet.ton, иногда используются вместо необработанных и удобных для пользователя адресов. DNS-адреса состоят из удобных для пользователя адресов и включают все необходимые флаги, которые позволяют разработчикам получать доступ ко всем флагам из записи DNS в домене TON.

Примеры кодировки адресов, удобных для пользователя

Например, смарт-контракт "test giver" (специальный смарт-контракт, находящийся в тестовой сети мастерчейна, который отправляет 2 тестовых токена всем, кто их запрашивает) использует следующий необработанный адрес:

-1:fcb91a3a3816d0f7b8c2c76108b8a9bc5a6b7a55bd79f8ab101c52db29232260

Вышеуказанный необработанный адрес "test giver" необходимо преобразовать в удобную для пользователя форму адреса. Это достигается с помощью форм base64 или base64url (которые мы представили ранее) следующим образом:

  • kf/8uRo6OBbQ97jCx2EIuKm8Wmt6Vb15+KsQHFLbKSMiYIny (base64)
  • kf_8uRo6OBbQ97jCx2EIuKm8Wmt6Vb15-KsQHFLbKSMiYIny (base64url)
к сведению

Обратите внимание, что обе формы (base64 и base64url) являются допустимыми и должны быть приняты!

Адреса с возможностью отклонения и без него

Основная идея флага адреса с возможностью отклонений — безопасность средств отправителя.

Например, если целевой смарт-контракт не существует или если во время транзакции возникнет проблема, сообщение будет"отклонено" обратно отправителю и составит остаток от исходной стоимости транзакции (за вычетом всех комиссий за перевод и газ). Что касается адресов с возможностью отклонений, в частности:

  1. Флаг bounceable=false обычно означает, что получатель — это кошелек.
  2. Флаг bounceable=true обычно обозначает пользовательский смарт-контракт с собственной логикой приложения (например, DEX). В этом примере невозвратные сообщения не должны отправляться из соображений безопасности.

Не стесняйтесь читать больше по этой теме в нашей документации, чтобы лучше понять невозвратные сообщения.

Представления бронированного base64

Дополнительные двоичные данные, связанные с блокчейном TON, используют похожие "бронированные" удобные для пользователя представления адресов base64. Они отличаются друг от друга в зависимости от первых 4 символов их байтового тега. Например, 256-битные открытые ключи Ed25519 представляются путем создания сначала 36-байтовой последовательности с использованием следующего процесса в следующем порядке:

  • Однобайтовый тег с использованием формата 0x3E обозначает открытый ключ
  • Однобайтовый тег с использованием формата 0xE6 обозначает открытый ключ Ed25519
  • 32 байта, содержащих стандартное двоичное представление открытого ключа Ed25519
  • 2 байта, содержащих от большего к меньшему представление CRC16-CCITT предыдущих 34 байтов

Полученная 36-байтовая последовательность преобразуется в 48-символьную строку base64 или base64url стандартным способом. Например, открытый ключ Ed25519 E39ECDA0A7B0C60A7107EC43967829DBE8BC356A49B9DFC6186B3EAC74B5477D (обычно представленный последовательностью из 32 байтов, например: 0xE3, 0x9E, ..., 0x7D) представляется через "бронированное" представление следующим образом:

Pubjns2gp7DGCnEH7EOWeCnb6Lw1akm538YYaz6sdLVHfRB2

Преобразование удобных для пользователя адресов и необработанных адресов

Самый простой способ преобразования удобных для пользователя и необработанных адресов — это использование одного из нескольких API TON и других инструментов, включая:

Кроме того, существует два способа преобразования удобных для пользователя и необработанных адресов для кошельков с помощью JavaScript:

Также возможно использовать аналогичные механизмы с помощью SDK.

Примеры адресов

Узнайте больше примеров адресов TON в Кулинарной книге TON.

Возможные проблемы

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

Что происходит, когда вы переводите Toncoin на адрес uninit?

Транзакция с включенным state_init

Если вы включаете state_init (состоящий из кода и данных кошелька или смарт-контракта) в свою транзакцию. Смарт-контракт сначала развертывается с использованием предоставленного state_init. После развертывания входящее сообщение обрабатывается аналогично отправке на уже инициализированный аккаунт.

Транзакция без установленных флагов state_init и bounce

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

Транзакция без флагов state_init и bounce

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

Как это сделать правильно

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

Блокчейн TON реализует защиту от ошибочных транзакций

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

Если вам нужно быстро получить адрес в форме с возможностью возврата/без возможности возврата, это можно сделать здесь.

Ответственность за пользовательские продукты

Если вы разрабатываете пользовательский продукт на блокчейне TON, важно реализовать аналогичные проверки и логику:

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