EQ, UQ и raw: форматы адресов TON и почему депозит «отскакивает»
EQ, UQ и raw: форматы адресов TON, bounceable против non-bounceable и почему первый депозит на новый кошелёк отскакивает отправителю.
Разработчик генерирует свежий кошелёк, копирует адрес, кидает туда первые 5 GRAM на газ — и через минуту монеты возвращаются на отправляющий кошелёк. Баланс нового адреса: ноль. Никакой ошибки, никакого «reverted», транзакция прошла успешно. Просто деньги… отскочили. В чатах TON это классика: «отправил на свой же адрес — не дошло». И почти всегда причина одна — перепутанные форматы адреса и флаг bounceable.
Разберём по фактам, что такое форматы адресов TON — EQ, UQ и raw, чем отличается bounceable от non-bounceable, и почему первый депозит на новый кошелёк уходит обратно отправителю. А заодно покажу, как проверить всё это одним вызовом инструмента из ИИ-агента, не поднимая ни SDK, ни ноду.
Три формата адреса TON: raw, EQ и UQ — в чём разница
У любого адреса в TON под капотом лежит одно и то же: номер воркчейна плюс 256-битный хэш стейт-инита контракта. Это и есть raw-формат:
0:83dfd552e63729b472fcbcc8c45ebcc6691702558b68ec7527e1ba403a0f31a8
Слева от двоеточия — воркчейн (обычно 0 — базовый, -1 — мастерчейн), справа — 256-битный хэш в hex. Формат честный и однозначный, но у него нет контрольной суммы: опечатался в одном символе — получил другой валидный на вид адрес. Именно raw обычно ждут get-методы контрактов и низкоуровневые инструменты, а людям его почти не показывают.
Второе представление — user-friendly: те самые 48 символов base64url, которые вы видите в кошельках и эксплорерах:
EQCD39VS5jcptHL8vMjEXrzGaRcCVYto7HUn4bpAOg8xqB2N (bounceable)
UQCD39VS5jcptHL8vMjEXrzGaRcCVYto7HUn4bpAOg8xqEBI (non-bounceable)
В нём зашита та же пара «воркчейн + хэш», плюс байт флагов и CRC16-контрольная сумма на конце. CRC ловит опечатки: битый адрес просто не пройдёт валидацию ещё до отправки. И именно из этого байта флагов рождаются префиксы EQ и UQ.
Ключевое, что стоит усвоить сразу:
- raw и user-friendly — это два способа записать один и тот же адрес.
- EQ и UQ — это два варианта одного user-friendly адреса, различающиеся ровно одним флагом.
То есть EQ… и UQ… для одного кошелька указывают на один и тот же raw-хэш, один и тот же контракт, один и тот же баланс. Это не два разных кошелька и не два разных счёта. Разница — только в одном бите намерения отправителя.
Bounceable (EQ) против non-bounceable (UQ): что значит флаг
Тот самый байт флагов внутри user-friendly адреса и определяет префикс:
| Флаг | Тег | Префикс (mainnet) | Префикс (testnet) |
|---|---|---|---|
| bounceable | 0x11 |
EQ |
kQ |
| non-bounceable | 0x51 |
UQ |
0Q |
Для тестнета к тегу добавляется 0x80 — отсюда экзотические kQ и 0Q. Но нас интересует смысл флага, а не арифметика тегов.
Bounceable (EQ) означает буквально: «если на принимающей стороне что-то пойдёт не так — верни монеты мне обратно». Это защита для смарт-контрактов. Если вы шлёте деньги контракту, который должен их обработать, а он падает с ошибкой, ещё не задеплоен или газа не хватило, — вы не хотите, чтобы монеты просто зависли в пустоте. Bounce-механизм вернёт их отправителю за вычетом комиссии.
Non-bounceable (UQ) означает противоположное: «доставь и оставь, что бы там ни было». Никакого возврата — монеты просто ложатся на адрес.
Для повседневных переводов между людьми разница незаметна — до одного конкретного случая.
Почему первый депозит на неразвёрнутый кошелёк «отскакивает»
Вот та самая ловушка. В TON адрес кошелька существует до того, как контракт кошелька реально задеплоен в блокчейн. Адрес — это детерминированный хэш от кода контракта и начальных данных (публичного ключа), поэтому вы знаете его сразу после генерации мнемоники, полностью офлайн. Но пока по адресу не прошла первая транзакция, аккаунт находится в состоянии uninit (неинициализированный): адрес есть, кода контракта на нём — нет.
Теперь смотрите, что происходит с bounceable-переводом:
- Вы шлёте на этот uninit-адрес перевод в формате EQ (bounceable).
- Сеть пытается доставить монеты и «вызвать» принимающий контракт. Принимать их некому — контракта на адресе нет.
- Срабатывает bounce: раз доставить не удалось, монеты возвращаются отправителю за вычетом комиссии.
Итог — тот самый «отскок». Транзакция прошла успешно, но баланс нового кошелька остался нулевым, а деньги вернулись туда, откуда пришли. Никто ничего не украл, сеть отработала ровно как задумано — просто вы использовали bounceable-формат там, где не должны были.
А если тот же перевод отправить в формате UQ (non-bounceable)?
- Сеть пытается доставить монеты на uninit-адрес.
- Bounce отключён флагом — возвращать не нужно.
- Монеты остаются на адресе, даже несмотря на то что контракт ещё не развёрнут.
Кошелёк пополнен. Позже, когда вы отправите с него первую исходящую транзакцию, вместе с ней задеплоится код контракта — и аккаунт станет active. С этого момента он спокойно принимает любые переводы, включая bounceable. Правило UQ критично только для самого первого пополнения ещё не развёрнутого кошелька.
Хорошая новость: экосистема постепенно закрывает эту дыру за пользователя. Кошельки v5r1 и ряд клиентов по умолчанию показывают адрес именно в non-bounceable (UQ) виде — как раз чтобы новичок не потерял первый депозит. Но как только вы работаете с адресами программно — из бэкенда, из скрипта, из ИИ-агента — ответственность за флаг снова на вас.
Как правильно слать первый перевод: UQ вместо EQ
Практическое правило умещается в одну строчку:
Первый депозит на новый (uninit) кошелёк — всегда на UQ. Дальше можно как угодно.
Развёрнутая логика для любого сервиса, который отправляет пользователю средства:
- Адрес получателя в состоянии uninit → шлите на UQ (non-bounceable).
- Адрес active → можно на EQ (bounceable).
- Отправляете на смарт-контракт (DEX, джеттон-минтер, эскроу) → EQ, чтобы при ошибке деньги вернулись.
Проблема в том, что «на глаз» EQ от UQ отличается одним символом префикса, а состояние uninit/active по адресу вообще не видно. Обе проверки нужно делать программно. И вот тут не обязательно тащить в проект @ton/ton, поднимать провайдера и парсить ячейки — оба вопроса закрываются двумя инструментами MCP-сервера, которые ИИ-агент дёргает сам.
Если тема генерации и первого пополнения кошелька для вас свежая — есть отдельный разбор в гайде про создание TON-кошелька.
parse_address: конвертация и проверка адресов офлайн одним вызовом
parse_address — это офлайн-инструмент из TONNode, hosted MCP-сервера для TON. Он раскодирует адрес, пересчитывает форматы и проверяет CRC16, не обращаясь к сети: ему не нужны ни нода, ни ключ — это чистая математика над строкой, поэтому мгновенно и без расхода лимитов.
Что он умеет:
- сконвертировать
EQ ⇄ UQ ⇄ rawв любую сторону; - проверить валидность адреса (сойдётся ли контрольная сумма);
- показать флаг bounceable и номер воркчейна.
MCP (Model Context Protocol) — стандарт, по которому ИИ-агенты (Claude, Cursor, ChatGPT/Codex и любой MCP-клиент) вызывают инструменты. Подключается MCP-сервер одной записью в конфиг клиента. Локальный бесплатный вариант с полным набором инструментов чтения:
{
"mcpServers": {
"ton": {
"command": "npx",
"args": ["-y", "@tonnode/mcp"]
}
}
}
Дальше агенту достаточно обычного промпта:
Возьми адрес
EQCD39VS5jcptHL8vMjEXrzGaRcCVYto7HUn4bpAOg8xqB2Nи покажи его в non-bounceable (UQ) и raw форматах. Проверь, что контрольная сумма валидна.
Агент вызовет parse_address и вернёт UQ-версию того же кошелька, raw-хэш и статус валидности. Никакого ручного base64url-жонглирования и риска опечататься в 48 символах.
get_account_state: как понять, развёрнут ли кошелёк, до отправки
Форматом дело не заканчивается — надо ещё узнать, в каком состоянии адрес: active или uninit. Это уже он-чейн вопрос, и на него отвечает get_account_state. Инструмент возвращает статус аккаунта, флаги и данные о последней транзакции.
Логика перед отправкой первого перевода:
get_account_stateвернул uninit → адрес ещё не задеплоен → шлём на UQ.- вернул active → кошелёк развёрнут → можно спокойно слать на EQ.
Промпт агенту:
Проверь через get_account_state, развёрнут ли адрес
UQCD39VS5jcptHL8vMjEXrzGaRcCVYto7HUn4bpAOg8xqEBI. Если состояние uninit — напомни, что первый депозит нужно слать в UQ-формате.
Связка получается такая: generate_wallet создаёт кошелёк (версии v3r2/v4/v5r1/highload_v3) и отдаёт адрес, который на момент создания гарантированно uninit — сеть про него ещё не знает. Значит, первый депозит на него идёт строго на UQ. Перед отправкой get_account_state подтверждает, что адрес и правда uninit, а parse_address гарантирует, что вы взяли именно non-bounceable представление. После пополнения удобно дёрнуть get_balance и убедиться, что монеты легли на адрес, а не отскочили.
Важный момент про генерацию: generate_wallet возвращает мнемонику, ключи и адрес пользователю — сервер их не хранит и не подписывает ничего за вас. Это некастодиальная механика, и она распространяется на все инструменты свапа, кроссчейна и кошелька.
Небольшое терминологическое уточнение: GRAM — это переименованный Toncoin (переименован в июне 2026), сама сеть по-прежнему называется TON.
Чек-лист: как не потерять первый депозит на TON
Короткий алгоритм на каждый первый перевод новому кошельку:
- Сгенерировали адрес (
generate_walletили свой SDK) — считайте его uninit по умолчанию. - Проверьте состояние через
get_account_state:uninitилиactive. - Если uninit — приведите адрес получателя к UQ через
parse_addressи шлите первый депозит только на него. - Если active — можно
EQ, для контрактов это даже предпочтительнее. - На смарт-контракты всегда шлите bounceable (
EQ), чтобы при сбое деньги вернулись. - После пополнения проверьте
get_balance— монеты должны лечь на адрес, а не отскочить. - Помните:
EQиUQ— один и тот же кошелёк (один raw-хэш); вы выбираете не адрес, а поведение при неудачной доставке.
Обе ключевые проверки — parse_address (офлайн) и get_account_state (он-чейн) — доступны сразу, без своей инфраструктуры. Возьмите бесплатный ключ Hobby (60 запросов/мин, без карты) и дёргайте оба инструмента прямо из ИИ-агента: https://tonnode.io/dashboard?plan=hobby.
А дальше по той же схеме удобно решать смежные задачи: ловить входящие USDT-платежи на TON, читать баланс USDT одним вызовом или вызывать get-метод контракта без SDK. Форматы адресов — это фундамент, на котором стоит всё остальное: разберётесь с EQ/UQ один раз — и «отскочивший» депозит больше не застанет вас врасплох.
Дайте вашему агенту доступ к TON
16 MCP-инструментов: чтение, некастодиальные свапы, кроссчейн и кошельки. Бесплатный тариф — 60 запр/мин, карта не нужна.