Как STONfi обрабатывает адреса с поддержкой отскока и без поддержки отскока в TON

Адреса TON могут выглядеть по-разному, при этом указывать на точно тот же самый on-chain аккаунт.

Один из распространённых примеров — различие между адресом, начинающимся с EQ..., и адресом, начинающимся с UQ.... Первый — привычное удобочитаемое представление с возможностью отскока, а второй — представление без отскока. Несмотря на разные префиксы, оба варианта могут идентифицировать один и тот же базовый аккаунт TON, потому что сам аккаунт определяется его workchain и 256-битным идентификатором аккаунта. Отличие между отскок-совместимым и неотскок-совместимым представлено как метаданные в удобочитаемом формате, а не как создание другого аккаунта.

Это различие становится особенно важным при взаимодействии с DeFi-протоколами, такими как STONfi, где один своп может включать несколько TON-адресов и несколько уровней контрактных сообщений.

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

Первое важное различие: идентичность адреса vs поведение сообщения

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

Удобный для пользователей адрес TON содержит несколько элементов информации. Среди них — идентификатор workchain, идентификатор аккаунта и флаги, описывающие, как адрес предназначен для обработки. В частности, флаги кодируют, должно ли сообщение отправляться как bounceable или non-bounceable.

Это значит, что видимый префикс — это не просто альтернативный идентификатор аккаунта.

Например:

EQ... → удобное представление bounceable
UQ... → удобное представление non-bounceable

Когда базовый workchain и идентификатор аккаунта совпадают, это два представления одного и того же аккаунта.

Собственные утилиты TON для адресов могут конвертировать адрес в его «сырой», bounceable и non-bounceable формы — это ещё один способ показать, что это разные представления одного и того же базового назначения, а не отдельные кошельки.

Это один из самых важных концептов для разработчиков, создающих на TON:

Не сравнивайте визуальный префикс, когда пытаетесь определить, указывают ли два адреса на один и тот же аккаунт. Распарсите адрес и сравните базовые компоненты адреса.

Что на самом деле означает «отскакиваемый» (Bounceable)?

Bounceability — по сути про обработку сообщений.

Внутренние сообщения TON содержат флаг bounce. Когда bounceable-сообщение доставляется на назначение и обработка не удаётся при условиях, где bouncing поддерживается, оставшаяся стоимость может быть возвращена отправителю. Рекомендации TON для смарт-контрактов рекомендуют bounceable-сообщения для большинства взаимодействий, потому что они защищают от некоторых сбоев назначения или выполнения.

Важно то, что аккаунт не становится навсегда «bounceable-аккаунтом» или «non-bounceable-аккаунтом».

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

Документация TON описывает форматы для mainnet как:

  • E... для bounceable-адресов

  • U... для non-bounceable-адресов

Тот же аккаунт поэтому может быть представлен в любом из форматов.

Поэтому, когда кто-то меняет адрес с EQ... на UQ..., он не переводит средства, не создаёт второй кошелёк и не меняет сам аккаунт.

Они изменили удобное представление и связанное предпочтение bounce.

Зачем TON нужны non-bounceable-адреса?

Ответ становится яснее, когда мы учитываем инициализацию аккаунта.

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

Это создаёт важную проблему с финансированием.

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

Вот почему non-bounceable-представления особенно связаны с финансированием или инициализацией кошельков.

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

Кошельки в TON — это смарт-контракты

Ещё один концепт, который иногда вызывает путаницу, — слово «кошелёк».

В TON кошелёк — это не просто метка аккаунта в том же смысле, что и аккаунт на традиционной централизованной бирже. Реализации кошельков — это смарт-контракты, и их адрес можно вывести ещё до развертывания.

Вот почему можно знать, где будет существовать кошелёк, ещё до того, как контракт кошелька будет фактически инициализирован в сети.

Адресный процесс TON отражает это различие. Когда приложение кошелька готовит перевод, оно может проверить состояние аккаунта назначения. Документация TON отмечает, что когда назначение ещё не инициализировано, ПО кошелька может принудительно установить bounce-поле исходящего сообщения в false, фактически предпочитая non-bounceable-доставку для сценариев инициализации. Для уже инициализированных назначений кошелёк может использовать предпочтение bounce, представленное адресом.

Поэтому практическое поведение сложнее, чем просто говорить:

«EQ всегда отскакивает».

или

«UQ никогда не отскакивает».

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

Где STONfi вписывается в эту модель

Своп STONfi — это не просто один перевод с одного кошелька на другой.

Типичный своп может включать несколько адресов и несколько сообщений:

Ваш кошелёк → контракт/роутер STONfi → контракт(ы) токена или пулы → адреса получателя/возврата/излишка

В зависимости от операции транзакция может включать адреса для:

  • Ваш подключенный кошелёк

  • Мастер-контракты Jetton

  • Контракты кошельков Jetton

  • Роутеры STONfi

  • Контракты пулов

  • Адреса получателей

  • Адреса возврата средств

  • Назначения для избыточных средств

Каждый адрес может появляться на разных уровнях транзакции.

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

Например, когда кошелёк отправляет транзакцию TON Connect, само сообщение имеет адрес назначения и может содержать произвольную полезную нагрузку. Тогда взаимодействие с контрактом может кодировать дополнительные значения MsgAddress внутри этой полезной нагрузки. Собственные примеры TON показывают этот шаблон для взаимодействий с токенами и NFT, где контрактное сообщение может содержать адреса вроде нового владельца или адреса для избыточных средств.

Именно такая архитектура делает обработку адресов внутри свопа STONfi более интересной, чем простой «отправь с A на B».

Начальная цель — лишь часть транзакции

Рассмотрим начало свопа.

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

Тогда кошельку нужен корректный адрес назначения для этого контракта.

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

Эти адреса представлены как обычные значения TON-адреса в данных контракта.

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

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

Почему STONfi может относиться к EQ... и UQ... как к одному и тому же назначению

Представьте следующее упрощённое сценарное описание:

EQxxxxxxxx... и UQxxxxxxxx...

могут выглядеть как две разные строки.

Наивное приложение может сравнить их как «сырой» текст и решить, что это разные кошельки.

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

После распарсивания приложение может определить общий workchain и идентификатор аккаунта.

Поэтому правильная ментальная модель такова:

Разное удобное представление ≠ разный аккаунт.

Этот принцип особенно важен для STONfi, потому что DeFi-приложение может получать адреса из разных кошельков, SDK, бирж, обозревателей или от разработчиков. Разные инструменты могут отображать один и тот же аккаунт, используя разные удобные представления.

TON даже предоставляет официальные утилиты для определения и «распаковки» этих форм в их базовые компоненты.

Что происходит с to-параметрами в STONfi?

Согласно описанному для SDK STONfi поведению, начиная с v0.5.0, сгенерированные параметры to используют bounceable-представления, потому что эти протокольные назначения ожидаются как инициализированные контракты, которые должны получать и выполнять логику.

Такое проектное решение согласовано с более широкой рекомендацией TON по смарт-контрактам.

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

Это не значит, что каждый адрес в транзакции STONfi должен визуально начинаться с EQ.

Это означает, что сообщение и взаимодействие с контрактом должны использовать соответствующее bounce-поведение для роли, которую адрес играет.

Это различие критически важно.

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

Адреса получателя, возврата и излишка

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

Это не так.

Своп может включать разные роли адресов с разными целями.

Получатель

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

Возврат

Адрес возврата можно использовать, когда операция должна вернуть значение исходному пользователю или другому назначенному месту.

Излишек

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

Эти адреса могут проходить через протокол как значения TON MsgAddress, встроенные в полезные нагрузки.

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

Почему сборщикам нужно распарсивать адреса, а не сравнивать строки

Для разработчиков это может быть самым практичным уроком из всех.

Не строите логику вроде:

если (addressA === addressB)

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

Вместо этого распарсите оба значения в правильные объекты TON Address и сравните их базовую идентичность.

Библиотеки в экосистеме TON предназначены для преобразования между «сырой» и удобной формой. Документация TON явно описывает преобразование между сырой, bounceable и non-bounceable формами, а рекомендации по безопасности предупреждают разработчиков правильно обрабатывать несколько представлений адресов в TON.

Приложение должно заботиться о:

workchain + идентификатор аккаунта

вместо этого:

EQ против UQ

как текстовый префикс.

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

Полезная ментальная модель

Самый простой способ запомнить всю систему — думать о TON-адресе как о имеющем два уровня.

Уровень 1: аккаунт

Это базовая идентичность:

Workchain + 256-битный идентификатор аккаунта

Это и идентифицирует аккаунт назначения.

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

Так этот аккаунт кодируется для людей и ПО:

Варианты Raw / Bounceable / Non-bounceable / Testnet

Удобное представление добавляет метаданные, включая bounceability и информацию о testnet, а также контрольную сумму.

Поэтому две «дружественные» строки могут описывать один и тот же базовый аккаунт.

Вот почему точнее не относиться автоматически к представлению EQ... и представлению UQ... как к двум разным кошелькам.

Что пользователи должны сделать перед свопом STONfi

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

Используйте адрес, предоставленный вашим кошельком или доверенными TON-инструментами, вместо ручного изменения префиксов.

Не меняйте EQ на UQ или UQ на EQ только потому, что другое приложение отображает адрес иначе.

И самое главное: всегда проверяйте реальное назначение, сеть, сумму и детали транзакции перед подписанием.

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

Иными словами, пользователям обычно не нужно вручную управлять флагами bounce при использовании корректно интегрированного кошелька и интерфейса протокола.

Что должны вынести сборщики

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

Надёжная реализация должна:

Сначала распарсите адреса, прежде чем сравнивать их.

Никогда не предполагайте, что две разные строки означают два разных аккаунта.

Сохраняйте информацию о workchain.

Идентификатор аккаунта нужно интерпретировать вместе с правильным workchain. Рекомендации TON по безопасности прямо советуют валидировать цепочку адресов при обработке адресов.

Понимайте разницу между аккаунтом и сообщением.

Bounceability описывает поведение сообщения; это не постоянное свойство, которое создаёт второй аккаунт.

Используйте bounceable-сообщения для соответствующих взаимодействий с контрактами.

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

Используйте non-bounceable-доставку там, где инициализация или финансирование требует этого.

Новый или неинициализированный контракт кошелька — классический случай.

Поручите доверенным SDK детали представления.

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

Общая картина для STONfi

По мере того как TON DeFi становится более продвинутым, транзакции всё чаще включают несколько контрактов, а не простую пересылку кошелёк-к-кошельку.

Свопы STONfi — хороший пример.

Пользователь может видеть только:

«Поменяй токен A на токен B».

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

Следовательно, корректная обработка адресов становится частью надёжности протокола.

Различие между EQ... и UQ... может выглядеть косметическим для пользователя, но на уровне протокола это отражает значимое различие в построении сообщений.

При этом это различие никогда не должно затмевать базовую истину:

Префикс не означает автоматически, что есть два разных аккаунта.

Тот же TON-аккаунт может иметь разные пользовательские представления, при этом сообщение, отправленное в этот аккаунт, может нести разное поведение bounce в зависимости от того, как адрес закодирован, и как построена транзакция.

Итоговое замечание

Система адресов TON мощна именно потому, что отделяет идентичность аккаунта от пользовательского представления.

Адрес EQ... и адрес UQ... могут указывать на один и тот же базовый аккаунт. Важная идентичность — это workchain плюс идентификатор аккаунта; дружелюбный префикс добавляет информацию о обработке, например bounceability.

Для пользователей STONfi это означает: вам не стоит переживать, если доверенный кошелёк или приложение показывает ваш адрес в другой допустимой форме.

Для разработчиков урок ещё важнее:

Распарсите TON-адреса. Нормализуйте их. Сравните их базовую идентичность. И выберите поведение bounce в зависимости от роли назначения и цели сообщения.

Как только эта модель становится понятной, адресная обработка в STONfi становится намного проще для понимания.

В следующий раз, когда вы увидите адрес EQ... и UQ..., не думайте сразу «это два кошелька».

Думайте так:

одно и то же возможное назначение, разное представление, разные предпочтения обработки сообщений.

На уровне интерфейса это различие небольшое, но фундаментальное при построении надёжных приложений на TON.

Узнайте больше в приложении STON.FI app.ston.fi

Подробнее о STONfi — здесь BLOG.STON.FI

#Wallet #TON #swap_crypto