Неудачная транзакция TRON: REVERT, сгоревшие TRX и что вернётся

Статус REVERT значит, что контракт сам отклонил вызов: USDT остались у вас, а списана только энергия до точки отката и bandwidth. Разбираем причины, Tronscan и что делать.

Overtron Editorial
revert tronrevert opcode executedнеудачная транзакция tronсгорел trx при ошибкетранзакция trc20 failedошибка перевода usdt

Коротко: статус REVERT означает, что смарт-контракт сам отклонил ваш вызов — проверка внутри кода не прошла, и сеть откатила все изменения. Сумма перевода или свопа осталась на вашем адресе. Потеряно только то, что сеть успела израсходовать до точки отката: энергия (или TRX, сожжённые вместо неё) и bandwidth за саму транзакцию. Повторять отправку бессмысленно, пока не устранена причина отказа, — второй REVERT спишет ресурсы ещё раз.

Что такое REVERT в TRON

REVERT — один из стандартных кодов результата исполнения контракта в протоколе TRON. Он перечислен в Tron.proto репозитория java-tron (перечисление contractResult) рядом с SUCCESS, OUT_OF_ENERGY и другими исходами. Появляется, когда код контракта дошёл до инструкции отката: условие вида «баланса хватает», «адрес не заблокирован», «цена в пределах допуска» оказалось ложным, и контракт намеренно прервал исполнение.

Транзакция в TRON атомарна: она либо выполняется целиком, либо все её изменения отменяются. Поэтому REVERT не бывает «частичным» — получатель ничего не получил, а ваш баланс токена не изменился. При этом транзакция всё равно попала в блок: её видно в обозревателе, у неё есть TXID и статус FAILED.

REVERT и OUT_OF_ENERGY: в чём разница

Обе ошибки дают статус FAILED, но причины и цена разные. OUT_OF_ENERGY — контракту не хватило ресурса, чтобы доработать до конца; это разобрано в статье «Ошибка FAILED — OUT_OF_ENERGY». REVERT — ресурса хватало, но контракт сам сказал «нет». Разница важна для кошелька: по документации TRON о fee_limit, нормальное исполнение и REVERT оплачиваются по фактически израсходованной энергии, а исключительные сбои вроде OUT_OF_TIME или недопустимой инструкции могут списать максимум энергии, разрешённый транзакции.

  • REVERT: контракт отклонил вызов по своей проверке. Списывается энергия, израсходованная до точки отката.
  • OUT_OF_ENERGY: энергии и TRX в пределах fee_limit не хватило до конца исполнения. Лечится ресурсом, а не исправлением параметров.
  • Прочие исключения (тайм-аут, недопустимая инструкция): могут списать весь лимит энергии транзакции.
  • SUCCESS: перевод выполнен. Если деньги «не пришли», проблема не в сети, а на стороне получателя или биржи.

Что сгорает, а что остаётся

  • Сумма перевода или свопа — остаётся на вашем адресе. Изменения балансов откатываются целиком.
  • Энергия, израсходованная до точки отката, — не возвращается. Документация прямо говорит, что израсходованная энергия не возмещается, даже если транзакция затем откатилась.
  • TRX, сожжённые вместо энергии, — тоже не возвращаются. Если энергии на адресе не было, сеть покрыла расход сжиганием TRX в пределах fee_limit.
  • Bandwidth — списан. Транзакция попала в блок, а её байты оплачиваются всегда: из 600 бесплатных единиц в сутки или сжиганием TRX, если они закончились.
  • Арендованная энергия — израсходованная часть потеряна, остаток доступен до конца срока аренды.

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

Частые причины REVERT для пользователей USDT

1. Сумма больше баланса токена

Кошельки обычно не дают отправить больше, чем есть. Но при отправке через API, скрипт или сторонний интерфейс можно запросить перевод сверх баланса — контракт проверит остаток и откажет. Учитывайте, что у USDT TRC-20 шесть знаков после запятой: сумма 1 USDT в вызове контракта записывается как 1 000 000 минимальных единиц. Ошибка в множителе — классическая причина отказа в самописных интеграциях. Параметры токена, включая число знаков, видны на странице контракта USDT в Tronscan.

2. Адрес отправителя заморожен эмитентом

Контракт USDT позволяет эмитенту блокировать адреса. С заблокированного адреса перевод не пройдёт, сколько бы энергии на нём ни было. Как проверить адрес до операции и что делать с рискованными входящими — в статье о проверке USDT на чистоту и риск заморозки.

3. Нет разрешения (approve) на списание

Сервисы, боты и платёжные шлюзы часто списывают токены через transferFrom — это требует, чтобы владелец заранее выдал разрешение на нужную сумму. Если разрешение меньше суммы операции или не выдано вовсе, контракт отклонит вызов.

4. Свопы на DEX: проскальзывание и истёкший срок

При обмене на децентрализованной бирже вы задаёте минимальную сумму к получению и срок действия заявки. Если пока транзакция ждала включения в блок, курс в пуле сдвинулся сильнее допуска или срок истёк, контракт пула откатит обмен. Для свопов это самая частая причина REVERT.

5. Неверные параметры вызова

Не тот адрес контракта, перепутанные аргументы, вызов функции, которую контракт не поддерживает, — всё это может закончиться откатом. Типичная ситуация для тех, кто только начинает работать с TRC-20 через код.

Как прочитать причину в Tronscan

Откройте Tronscan и вставьте TXID в поиск. Подробный разбор интерфейса — в гиде по Tronscan; для этой ошибки достаточно четырёх полей:

  • Статус и результат: FAILED и REVERT. Если результат другой — читайте соответствующий раздел выше.
  • Сообщение об отказе: если контракт вернул текст причины, обозреватель может показать его рядом с результатом. Это самая полезная подсказка.
  • Ресурсы: сколько энергии и bandwidth списано и сколько TRX сожжено — ваша фактическая потеря.
  • Вызванный метод и параметры: transfer, transferFrom или функция свопа, адрес получателя и сумма. Здесь видны ошибки в сумме и адресе.

Что делать после REVERT

  • Не нажимайте «отправить» повторно сразу. Без исправления причины повтор даст тот же отказ и спишет ресурсы ещё раз.
  • Сверьте баланс токена с суммой операции, включая шесть знаков после запятой у USDT.
  • Для операций через сервис проверьте выданное разрешение (approve) и при необходимости выдайте его на нужную сумму.
  • Для свопа обновите котировку, при необходимости аккуратно увеличьте допуск проскальзывания и отправьте заново.
  • Если подозреваете блокировку адреса — проверьте его до любых новых попыток: энергия здесь не поможет.
  • Перед повтором убедитесь, что на адресе есть энергия под операцию, чтобы не жечь TRX.

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

Как не терять TRX на неудачных транзакциях

Полностью исключить отказы нельзя: курс в пуле или статус адреса может измениться за те секунды, пока транзакция ждёт блока (блок в TRON — 3 секунды). Но цену отказа можно сделать минимальной.

  • Проверяйте баланс, разрешения и адрес до отправки, а не после.
  • В интеграциях симулируйте вызов перед публикацией и выставляйте fee_limit с запасом относительно оценки, но без многократного завышения.
  • Держите на адресе энергию под планируемые операции: тогда и успешный перевод, и отказ оплачиваются ресурсом, а не сожжёнными TRX. Без энергии обычный перевод USDT сжигает около 6,5 TRX, на пустой адрес — около 13.
  • Для серии переводов арендуйте объём сразу на всю серию: обычный перевод USDT на адрес с USDT расходует около 64 500–65 000 энергии, на пустой адрес — примерно вдвое больше (~131 000).

Если повторная попытка упирается не в контракт, а в ресурс, вам нужна другая статья — про OUT_OF_ENERGY. Если же статус SUCCESS, а средства не видны у получателя, пройдите чек-лист «USDT отправлен, но не пришёл».

Транзакция TRON со статусом REVERT: контракт отклонил вызов, средства остались у отправителя
REVERT — контракт сам отклоняет вызов: изменения откатываются, списываются только израсходованные ресурсы.

Когда причина устранена, закройте вопрос ресурса заранее: энергию под перевод можно арендовать в боте @overtronbot или на сайте — энергия делегируется на ваш адрес on-chain, приватные ключи не нужны. Состояние сервиса видно на странице статуса.

Читайте также

FAQ

Пропали ли мои USDT после REVERT?

Нет. REVERT откатывает все изменения балансов, сумма перевода осталась на вашем адресе. Теряются только ресурсы, израсходованные до отката.

Вернут ли сожжённые TRX за неудачную транзакцию?

Нет. Энергия и TRX, израсходованные на исполнение, не возмещаются — даже если транзакция затем откатилась. Это правило протокола, а не конкретного кошелька.

Почему REVERT обычно дешевле, чем OUT_OF_ENERGY?

При REVERT списывается фактически израсходованная энергия до точки отказа. Исключительные сбои вроде тайм-аута могут списать весь лимит энергии транзакции.

Можно ли просто отправить перевод ещё раз?

Только после устранения причины. Повтор с теми же параметрами снова упрётся в ту же проверку контракта и спишет ресурсы повторно.

Поможет ли аренда энергии избежать REVERT?

Нет, REVERT — это отказ контракта, а не нехватка ресурса. Но с арендованной энергией неудачная попытка оплачивается ресурсом, а не сожжёнными TRX.

Где посмотреть причину отказа?

В Tronscan по TXID: статус FAILED, результат REVERT и, если контракт вернул текст причины, сообщение об отказе. Там же видны вызванный метод и параметры.

Почему своп на DEX завершился REVERT?

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

Как разработчику ловить REVERT до отправки?

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