Replay-атаки и защита через seqno/nonce
Защитишь контракт от повторного принятия того же подписанного payload через seqno или собственный nonce.
Replay и seqno
Replay — повторная подача уже валидного сообщения (или его копии), чтобы эффект сработал снова. У стандартных кошельков TON защита — поле seqno: контракт принимает только текущий номер и увеличивает его после успеха. Свой контракт с external без аналога nonce принимает один и тот же body многократно.
Уязвимый external без nonce
Исправленный контракт с seqno
Как это работает
- Клиент читает
currentSeqno(), подписывает payload с этим номером, шлётexternal. - Контракт сверяет
msg.seqno == self.seqno, проверяет подпись по тому же хешу полей, затемacceptMessage()и инкремент. - Инкремент до
sendобязателен: иначе при частичном успехе возможен повтор. - Wallet V4/V5 уже несут свой seqno; это не заменяет nonce твоего контракта, если он сам принимает signed external.
Частые ошибки
Проверяешь подпись, но не seqno → валидная подпись ≠ одноразовость.
Инкрементируешь seqno после send → при ошибке после accept возможен повторный приём того же номера.
Кладешь в подпись не все поля → атакующий меняет dest/amount при той же подписи.
Что дальше
- Типичные уязвимости контрактов — где replay стоит в общей карте
- Access control: только владелец — кто имеет право слать команды
- Аудит-чеклист перед mainnet — пункт про replay в чеклисте
Материалы gramdocs.tech носят образовательный характер и не являются финансовой, юридической или инвестиционной рекомендацией. Работа с блокчейном TON и токеном Gram связана с рисками потери средств. Правовая информация