К основному содержанию
T TON Adoption
← Словарь
NODE/03 · Term

seqno

Sequence number в TON-кошельке: 32-битный счётчик-nonce, который смарт-контракт инкрементирует при каждой исходящей транзакции для защиты от replay-атак.

Синонимы: sequence number, секно

seqno (sequence number) — 32-битный счётчик в data-cell каждого TON-кошелька, увеличивающийся на 1 после каждой исходящей транзакции. Подписанные сообщения включают seqno в тело; если seqno в подписанном сообщении не равен текущему в data — контракт отклоняет транзакцию через THROWIFNOT 33.

Зачем нужен

  • Защита от replay: атакующий не может «переотправить» вашу старую транзакцию — её seqno уже инкрементирован.
  • Гарантия порядка: транзакции выполняются строго по возрастанию seqno.

Как использовать в SDK

@ton/ton SDK сам читает seqno у контракта перед отправкой:

const seqno = await walletContract.getSeqno();
await walletContract.sendTransfer({ seqno, secretKey, messages: [...] });

В Wallet V5 появилась расширенная семантика: extensions могут иметь собственный seqno-namespace и подписывать независимо от основного владельца.

Что делать, если транзакция «застряла»

Если sendTransfer прошёл, но в эксплорере транзакции нет 30+ секунд — возможные сценарии:

  1. Внешнее сообщение отклонено валидатором (низкая комиссия, неверная подпись). seqno в data не инкрементировался — можно повторять с тем же seqno.
  2. Сеть перегружена — сообщение в очереди, ждите ещё 15-30 секунд.
  3. Race condition с другой подписью — если кто-то параллельно отправил транзакцию (например, открытое второе окно кошелька) с тем же seqno, ваше отклонит throw 33.

Проверка через API:

const stored = await walletContract.getSeqno();
if (stored === seqno) {
  // транзакция не прошла — можно retry
} else if (stored > seqno) {
  // транзакция включена в блок (или была другая параллельная отправка)
}

Никогда не «угадывайте» seqno вручную — всегда читайте свежее значение перед каждой подписью.

Batch-отправка

Один seqno покрывает один внешний message, но внутри него можно отправить до 4 outgoing-сообщений (Wallet V4) или до 255 (Wallet V5 batch mode). Все они выполнятся атомарно в рамках одной транзакции; если хоть один fail’нет на стадии compute — откатывается весь batch.

Wallet V5 namespaces — подробнее

В Wallet V5 структура data усложнилась: помимо основного signature_auth_seqno есть отдельные счётчики для каждого подписанного extension. Это позволяет:

  • Использовать multi-sig с несколькими ключами без race-конфликтов.
  • Делегировать sign-полномочия dApp’у (через TON Connect 2) с ограниченным namespace.
  • Запускать gasless flows: relayer оплачивает gas, юзер подписывает только тело operation.

При работе с V5 кошельком всегда используйте getSeqno({ extensionId }) если вы — extension, иначе будет 33-throw от чужого namespace’а.

См. также