Сбор USDT с депозитных адресов в TRON: активация, энергия и пропускная способность на каждый сбор
Платёжный шлюз или биржа, выдающие каждому клиенту собственный депозитный адрес, должны собрать TRC-20 USDT с этих адресов на один главный кошелёк — горячий, — прежде чем что-либо из этого выплатить. В TRON каждое такое перемещение — обычный перевод USDT, подписанный депозитным адресом. Ему нужны аккаунт в сети, энергия на вызов контракта и пропускная способность на байты, а у депозитного адреса, на который только платили USDT, нет ничего из этого.
Получение USDT аккаунт не создаёт
Баланс USDT — это ячейка в собственном хранилище контракта токена. Входящий перевод пишет в эту ячейку и аккаунт не создаёт, поэтому адрес может держать USDT, когда у сети для него нет аккаунта вовсе. Наш замер 7 сентября 2026 года нашёл в основной сети два таких адреса: на каждом лежал USDT, а нода, с которой мы читали, на запрос аккаунта за ним возвращала пустой объект — и до нашего тестового вызова, и после. 27 октября на обоих лежали ровно те же балансы, что и 7 сентября.
Энергия делегируется аккаунту, и на адрес, у которого его нет, мы её не доставляем: заказ в mode A или mode C, называющий такой адрес в from, возвращается с 422 invalid_address и details.reason, равным inactive_wallet. Принимает ли делегацию на такой адрес сама сеть, мы не проверяли, потому что наш отказ срабатывает раньше. В наших заметках по эксплуатации записан и ответ ноды на отправку с кошелька, который никогда ничего не получал, — no OwnerAccount. Эта заметка о TRX, отправленных с нашего собственного горячего кошелька; перевод USDT с адреса в таком состоянии мы не пробовали. Более общая история этого состояния — в посте о неактивированных аккаунтах.
Активация адреса — один перевод TRX, и платит за него отправитель
Любой входящий перевод TRX создаёт аккаунт, каким бы малым он ни был, и с этого момента адрес — такой же аккаунт, как любой другой. Первая попытка этого замера споткнулась именно об это, и мы её отбросили: адрес прочитался как не имеющий аккаунта, а через 22 секунды кто-то отправил ему один sun, и аккаунт появился. Об этом говорило само время его создания.
Плату за создание берут с того, кто отправляет TRX: в схеме сбора это кошелёк, оплачивающий активации. Её задают два параметра сети. Мы прочитали их 3 сентября 2026 года, а сеть может их менять, поэтому прочитайте их снова, прежде чем закладывать в бюджет.
| Параметр сети | Значение, прочитано 3 сентября 2026 года |
|---|---|
getCreateAccountFee | 0.1 TRX |
getCreateNewAccountFeeInSystemContract | 1 TRX |
Как эти два параметра складываются на обычном переводе TRX, мы собственной отправкой не замеряли: для этого нужен живой перевод на свежий адрес, а мы его не делали. Так или иначе плата берётся один раз на адрес. Служба, активирующая каждый адрес при его создании, платит её и на адресах, которые могут так и не увидеть депозита, а активирующая при первом депозите — только там, где есть что собирать.
Каждый сбор берёт меньшую цифру энергии
Сколько энергии тратит перевод USDT, зависит от получателя. Когда у получателя USDT уже есть, перевод берёт около 65,000 единиц; когда его баланс USDT нулевой — около 131,000. Есть ли у получателя аккаунт, в этом не участвует. Замер, нашедший эти два адреса, поставил рядом все четыре сочетания, и каждый раз решал баланс (почему цифр две).
Сбор всегда платит одному и тому же получателю — горячему кошельку, а на горячем кошельке USDT лежит. Поэтому каждый сбор — более дешёвого вида, single, в каком бы состоянии ни был депозитный адрес. Вызовы 7 сентября переводили одну единицу с кошелька, сохранявшего остальное, а сбор переводит всё и оставляет депозитный адрес на нуле. 27 октября мы попросили ноду смоделировать оба случая на тех же двух адресах, с кошельком, где лежит USDT, в роли получателя.
| Смоделированный перевод на кошелёк с USDT, 27 октября 2026 года | Потрачено энергии |
|---|---|
| Первый адрес, одна единица | 64,285 |
| Первый адрес, весь баланс | 64,285 |
| Второй адрес, одна единица | 64,285 |
| Второй адрес, весь баланс | 64,285 |
Опустошение депозитного адреса ничего не изменило, а цифра — та же, какую тот замер дал для каждого перевода держателю. Это симуляции ноды, и ни одна из них не является квитанцией отправленного сбора; цифры 7 сентября несут ту же оговорку. Есть ли у этих двух адресов аккаунт сегодня, мы заново не читали.
Единственный способ лишиться более дешёвого вида — опустошить горячий кошелёк. Одной единицы USDT у получателя хватает для меньшей цифры, но на нуле следующий сбор на него возьмёт около 131,000 единиц, а это 13.1 TRX, если сжигать. При сжигании обычный сбор стоит 6.5 TRX по протокольной ставке 100 sun за единицу, а стоимость аренды той же энергии движется вместе с рынком.
Бесплатной пропускной способности хватает примерно на один сбор в сутки с адреса
Пропускная способность меряет байты транзакции, тогда как энергия меряет её вычисления (два счётчика рядом). Каждый аккаунт получает бесплатную суточную норму пропускной способности. Перевод USDT, который мы отправили и замерили в основной сети 2 сентября 2026 года, оплатил свою пропускную способность в TRX, и это точно показывает, сколько её ему выставили.
| Пропускная способность одного перевода USDT | Значение | Прочитано |
|---|---|---|
Сожжено за байты (net_fee) | 0.345 TRX | 2 сентября 2026 года |
Цена сжигания одного байта (getTransactionFee) | 1,000 sun | 3 сентября 2026 года |
| Выставлено пропускной способности, делением | 345 байт | вычислено |
Бесплатная норма на аккаунт в сутки (getFreeNetLimit) | 600 | 3 сентября 2026 года |
Против 600 в сутки один сбор, которому выставили столько, укладывается, а два подряд — нет. Сверх нормы сеть сжигает за байты TRX отправителя. Поэтому первый сбор с адреса за сутки ничего не стоит по пропускной способности, а депозитному адресу, который получает ещё и энергию по делегации, для отправки собственные TRX не нужны. Второй сбор вскоре после первого оплачивает свои байты из TRX депозитного адреса. Как быстро норма восстанавливается между ними, мы не измеряли; наш собственный сбор рассчитывает примерно на один перевод в сутки на адрес из бесплатной нормы. Если адрес будут собирать чаще, активирующий перевод может заодно оставить на нём TRX на эти байты.
Как заказывать энергию для прогона сбора
Mode A называет оба конца каждого перевода — депозитный адрес как from и горячий кошелёк как to, — а вид мы определяем по горячему кошельку сами. Mode C называет только кошелёк, который нужно снабдить энергией, и берёт вид у вас; это подходит кастодиальной системе, которая подписывает свои сборы по собственному расписанию и хочет, чтобы энергия уже стояла на месте (mode C подробно). Для сбора этот вид — всегда single, пока на горячем кошельке есть USDT. Любой режим принимает до 500 переводов в одном заказе — тот же потолок, что у прогона выплат. Срок аренды — пять минут или час, а send_before не доходит до его конца на три секунды.
Один депозитный адрес без аккаунта отклоняет весь заказ. 422 называет его в details.index и details.address, и ничего не покупается. Поэтому прогон сначала нужно проверить. POST /v1/estimate принимает те же 500 переводов, ничего не резервирует и предупреждает там, где заказ отказал бы: передайте from в каждой позиции — и каждый депозитный адрес без аккаунта вернётся с пометкой inactive_sender. Активируйте их, дождитесь подтверждения активаций и отправляйте заказ. Отказ не расходует Idempotency-Key, а перед тем как отказать заказу из-за неактивированного адреса, мы перечитываем активацию мимо кэша, так что тот же ключ и то же тело сработают, как только активирующий перевод подтвердится.
Правила, которые стоит взять из нашего собственного сбора
У нас есть собственный сбор. Клиенты платят на депозитные адреса, которые мы держим для них, а фоновый проход переносит эти монеты на единственный горячий кошелёк, который оплачивает закупки. Он перемещает TRX, поэтому тратит пропускную способность и не тратит энергии, и его записи ничего не говорят об энергетической стороне сбора USDT.
Наш сбор читает сумму из сети в тот момент, когда принимает решение. Наши собственные записи не знают ни о сожжённой комиссии, ни о сборе, чья строка в базе не пережила упавший процесс, а сеть знает. То же правило делает безопасным повтор: если монеты уже ушли, отправлять нечего.
Отправленный в сеть сбор мы держим открытым, пока его транзакция не появится в блоке, и списываем как неудавшийся только по истечении окна не короче самого долгого срока действия, который наш подписывающий сервис ставит на транзакцию. Закрой мы его раньше — перевод, который ещё может дойти до блока, считался бы потерянным, и следующий проход мог бы подписать второй перевод того же баланса. Пока сбор не подтверждён, его адрес остаётся вне следующего прохода.
Наш сбор TRX отправляет не больше, чем баланс за вычетом резерва на комиссию, и оставляет этот резерв, только когда бесплатная пропускная способность адреса уже потрачена. Сбор USDT платит комиссию не той монетой, которую переносит, поэтому USDT уходит с баланса весь каждый раз, а резерв превращается в те TRX, которые депозитному адресу нужны на байты второго сбора за сутки.
Найдите все депозитные адреса, которым ещё нужна активация, до того, как оценён сбор, по пятьсот на запрос: POST /v1/estimate с from в каждой позиции →