У стандартного кошелька Kaspa нет задержки и страховочной сети. Если кто-то получит ваш приватный ключ — через фишинг, скомпрометированное устройство или физическое принуждение — он транслирует транзакцию, и KAS исчезнет в течение одного блока. В блокчейне нет кнопки «отменить».
Kaspa Safe решает это с помощью хранилища на основе ковенантов, которое обеспечивает задержку вывода, выбранную владельцем. Каждый исходящий вывод помещается в очередь на фиксированный период (от одного часа до девяноста дней). В течение этого окна второй, отдельно хранимый тревожный ключ может отменить вывод и вернуть все средства в хранилище. Вор, получивший только горячий ключ, не получит ничего — монеты остаются в контракте, пока владелец не заметит оповещение и не нажмёт «Отменить».
В этой статье объясняется, как эти два механизма работают на уровне сценария-ковенанта, как они взаимодействуют и где у модели безопасности есть реальные границы.
Контракт on-chain: состояния и пути расходования
Kaspa Safe построен на ковенанте Toccata — Silverscript-сценарии (vault.sil, текущая версия v3), скомпилированном в Kaspa P2SH-адрес. Контракт хранит два состояния:
mode:0= VAULT (нормальное),1= UNVAULTING (вывод в процессе)dest: 36-байтовый скрипт-публичный ключ с версионным префиксом — адрес назначения, зафиксированный в момент начала вывода
Из контракта существует семь путей расходования, каждый с разными требованиями к подписям и переходами состояний. Три из них важны для защиты от кражи:
| Путь | Подпись | Переход состояния | Назначение |
|---|---|---|---|
initiate(hotSig, destPk) | Горячий ключ | VAULT → UNVAULTING | Начать вывод; назначение фиксируется в dest |
cancel(alarmSig) | Тревожный ключ | UNVAULTING → VAULT | Отмена в течение окна задержки |
complete() | Нет | UNVAULTING → dest | Только после age >= delay; платит строго на зафиксированный dest |
Остальные пути обрабатывают проверки (check-in), наследование (inheritAuto / inheritSigned) и миграцию с полным контролем (migrate, требует оба ключа). Все семь начинаются с проверки require(tx.inputs.length == 1) — это предотвращает атаку «обескровливания» нескольких UTXO, когда два UTXO-ковенанта разделяют один выход транзакции, «утекая» значение меньшего UTXO в комиссии.
Как работает задержка вывода, пошагово
DAA score — метка времени алгоритма регулировки сложности Kaspa. Сеть нацелена примерно на 10 блоков в секунду, поэтому 36 000 DAA ≈ 1 час. Хранилище измеряет время в DAA, а не в секундах реального времени.
1. Владелец инициирует вывод.
С помощью горячего ключа владелец (или атакующий, его укравший) вызывает initiate. Транзакция включает два элемента: подпись горячего ключа и публичный ключ назначения. Ковенант проверяет подпись, затем переключает mode с 0 на 1 и записывает назначение в dest. С этого момента dest неизменяем — он является частью состояния UTXO в блокчейне, и никто не может его изменить.
2. Начинается окно задержки.
«Возраст» UTXO (время с момента последнего изменения состояния, измеряемое в DAA) сбрасывается на ноль. Контракт не позволит выполнить complete, пока age < delay, где delay — значение, выбранное владельцем при создании хранилища. Предустановки варьируются от 6 часов (216 000 DAA) до 14 дней; полный диапазон — от 1 часа до 90 дней.
В течение этого окна средства заморожены. Ни владелец, ни атакующий, ни серверы Kaspa Forge — никто не может их переместить. Путь complete явно проверяет возраст и отвергает преждевременные вызовы.
3. Владелец (или кто угодно) может транслировать cancel.
Если вывод был несанкционированным, владелец использует тревожный ключ для подписи транзакции cancel. Ковенант проверяет подпись тревожного ключа, переключает mode обратно в 0 и обнуляет dest. Средства возвращаются в хранилище, полностью защищённые.
Важно, что для cancel не требуется горячий ключ, исходное устройство или даже сайт Kaspa Forge. Требуется только тревожный ключ и доступ к любому узлу Kaspa. Открытый инструмент CLI vaultctl может сделать это из терминала к любому узлу Kaspa v2+ с utxoindex.
4. Если отмены не поступает, средства освобождаются на зафиксированный адрес.
После того как age >= delay, становится доступен путь complete. Он не требует никакой подписи — контракт обеспечивает, что средства могут идти только на dest, который был зафиксирован на шаге 1. Это сделано намеренно: кто угодно (включая сервис-наблюдатель Kaspa Forge) может транслировать транзакцию завершения, но деньги всегда идут на указанный инициатором адрес. Перенаправить их невозможно.
Auto-complete — необязательный флаг (рекомендуется), при котором сервис-наблюдатель Kaspa Forge автоматически транслирует транзакцию complete по истечении задержки. Это означает, что владельцу не нужно возвращаться на сайт для получения средств. Контракт гарантирует назначение независимо от того, кто его инициирует.
Почему два ключа вместо одного
Модель безопасности основана на разделении ключей. Вот матрица:
| Атакующий имеет… | Может ли он украсть средства? |
|---|---|
| Только горячий ключ | Он может начать вывод, но у владельца есть полное окно задержки для отмены с помощью тревожного ключа |
| Только тревожный ключ | Он может отменять выводы, но не может начать их или переместить средства куда-либо |
| Оба ключа | Мгновенная потеря. Путь migrate позволяет перебросить все средства на любой адрес без задержки |
Это честный компромисс: два ключа дают вам окно для реакции, но оба ключа вместе дают полный контроль. Вся модель зависит от хранения горячего и тревожного ключей в разных местах — горячий ключ на устройстве или в менеджере паролей (удобно для регулярного использования), тревожный ключ на бумаге в отдельном физическом месте (используется только в чрезвычайных ситуациях).
Если атакующий получит оба ключа, механизм задержки не обеспечит защиты. Путь migrate существует для легитимных целей — смены скомпрометированного ключа, перехода на новую версию хранилища — но он также является путём мгновенной потери. Это осознанное дизайн-решение: две подписи равны полным правам владельца, при этом ни сервер, ни третья сторона не могут вмешаться.
Что тревожный ключ может и чего не может делать
Тревожный ключ имеет ровно одну возможность on-chain: он может подписать путь cancel. Вот что это значит на практике:
- Cancel возвращает средства обратно в хранилище, но никогда не выводит их. Путь
cancelпереводит из состояния UNVAULTING обратно в VAULT. Он не задаёт назначение и не освобождает средства. Вор, каким-то образом получивший только тревожный ключ, не сможет ничего украсть — он может только срывать выводы. - Cancel работает в любой момент в течение окна задержки. Нет минимального ожидания. Как только транзакция
initiateподтверждена, тревожный ключ может немедленно её отменить. - Cancel обнуляет
dest. Адрес назначения стирается из состояния контракта. Даже если тот же атакующий повторно инициирует вывод, ему придётся снова выбирать назначение, и полная задержка начнётся заново. - Cancel не требует веб-сайта Kaspa Forge. Достаточно тревожного ключа и CLI
vaultctlили любого совместимого инструмента. Это важно, если сайт недоступен или атакующий блокирует к нему доступ.
Тревожный ключ намеренно исключён из пути initiate. Только горячий ключ может начинать выводы. Это означает, что скомпрометированный тревожный ключ сам по себе не даёт атакующию возможности перемещать средства — только отменять, что возвращает деньги в хранилище владельца.
Бюджет комиссии и граница грифинга
Каждый путь (кроме migrate) проверяет параметр feeBudget, ограниченный 0,1 KAS. Это предотвращает атаку типа «грифинг», когда наблюдатель или третья сторона транслирует бесключевой путь (как complete или inheritAuto) с завышенной комиссией, сжигая стоимость хранилища в доход майнерам. Путь migrate намеренно не имеет такого ограничения — он требует обе подписи владельца, поэтому владелец напрямую контролирует комиссию.
Текущая реализация v3 имеет известное ограничение: проверенные пути требуют значение outputs[0], но не обеспечивают tx.outputs.length == 1. Это означает, что автор транзакции может добавить второй выход в пределах бюджета комиссии (0,01–0,1 KAS) вместо уплаты его в качестве сетевой комиссии. Сборщики Kaspa Forge всегда формируют канонические транзакции с одним выходом, а основная стоимость хранилища защищена инвариантом стоимости. Более строгая проверка количества выходов запланирована для v4.
Как вписываются наблюдатель и оповещения
Логика хранилища on-chain самодостаточна — ей не нужен сервер для обеспечения задержки или соблюдения тревожного ключа. Но на практике вам нужно знать, что был инициирован вывод. Здесь на помощь приходит сервис-наблюдатель Kaspa Forge:
Фоновый сервис опрашивает каждое зарегистрированное хранилище каждые 10 секунд, сравнивая снимки UTXO. Когда он обнаруживает переход из VAULT в UNVAULTING, он отправляет оповещение через все подключённые каналы: Telegram, электронную почту и push-уведомления в браузере. Оповещение содержит тип события (вывод инициирован, отменён, завершён), но никогда не включает адреса, суммы или метки — они собираются на стороне клиента для обеспечения приватности.
Подписка на оповещения необязательна и платная (100 KAS/год, 30-дневная бесплатная пробная версия). Защита хранилища on-chain работает независимо от того, активны ли оповещения. Но без оповещений вы можете узнать о выводе, инициированном вором, только когда случайно проверите панель хранилища — а к тому времени окно задержки может уже истечь.
Kaspa Safe работает в основной сети. Контракт хранилища, механизм отмены тревожным ключом и оповещения наблюдателя — это производственная инфраструктура, а не прототип. Ключи генерируются в вашем браузере и никогда не покидают ваше устройство; код контракта открыт и имеет набор из 25 самопроверок. Если вы хотите увидеть задержку и тревожный ключ в действии, мастер создания хранилища подробно объясняет каждый параметр, а страница восстановления точно описывает, что делать во время кражи. Для работы офлайн, без веб-сайта, CLI-инструмент vaultctl делает всё из терминала к любому узлу Kaspa v2+.
Компромиссы и честные ограничения
Ни один механизм безопасности не бесплатен. Вот реальные затраты:
- Ваши собственные выводы задерживаются. Если вам нужно быстро переместить KAS — скажем, на биржу во время чувствительного ко времени предложения — вы ждёте полный срок задержки. Путь
migrate(оба ключа) — единственный мгновенный выход, что означает: держать оба ключа доступными для экстренных случаев подрывает модель разделения. Большинство пользователей принимают 24-часовую задержку как разумное значение по умолчанию.
- Потерянный тревожный ключ означает потерю защиты от кражи. Вы всё ещё можете выводить обычным способом (дождавшись истечения задержки), но не можете отменить вывод атакующего. Рекомендуемый ответ: немедленно выполнить обычный вывод в новое хранилище с новым тревожным ключом.
- Потерянный горячий ключ означает невозможность обычных выводов. Если наследование включено, прекратите проверки и ждите, пока наследник заявит свои права. Без наследования средства фактически сожжены — никто, включая Kaspa Forge, не может их восстановить. Поэтому FAQ рекомендует всегда включать наследование, даже на ваш собственный второй адрес.
- Оба ключа скомпрометированы = мгновенная потеря. Пути восстановления нет. Разделение ключей — это граница модели безопасности, а не рекомендация.
- Контракт не прошёл аудит. Он прошёл внутреннее стресс-тестирование и набор из 25 самопроверок, и код открыт для изучения, но стороннего аудита безопасности не проводилось. Хранилище хранит реальные KAS в основной сети — пользователи должны всё проверить, прежде чем хранить значительные суммы.
- Время измеряется в DAA, а не в секундах реального времени. Целевая скорость блоков Kaspa — 10 BPS, но фактическое продвижение DAA может варьироваться. Интерфейс конвертирует в понятное человеку время, но принудительное исполнение on-chain использует DAA score. Это факт на уровне протокола, а не специфическая проблема Safe — подробности о DAA и синхронизации блоков смотрите на вики Kaspa.
Собираем всё воедино
Модель защиты от кражи в Kaspa Safe нарочито проста на уровне контракта: один ключ начинает вывод, второй ключ может его отменить, а время делает остальное. Нет оракула, нет комитета мультиподписи, нет шага одобрения off-chain. Сценарий-ковенант в блокчейне Kaspa обеспечивает задержку и назначение — и он будет делать это, существует ли Kaspa Forge или нет.
Тревожный ключ — не сложный механизм. Это одна подпись на одном пути, которая переключает один бит состояния с 1 обратно на 0. Эта простота — суть: нечему ломаться, нечего настраивать неправильно, и ничто не требует доверия к третьей стороне. Если вы храните тревожный ключ отдельно от горячего, вор с одним ключом получает таймер обратного отсчёта вместо ваших KAS — а вы получаете шанс действовать.
FAQ
Что произойдёт, если кто-то украдёт мой горячий ключ?
Он сможет инициировать вывод, но средства останутся заблокированными в хранилище на весь срок задержки (выбранный вами период). Вы используете отдельно хранимый тревожный ключ для отмены вывода, и монеты возвращаются в хранилище.
Может ли тревожный ключ быть использован для кражи моих средств?
Нет. Тревожный ключ может только отменить выполняющийся вывод — он возвращает средства обратно в хранилище, но никогда не выводит их. Только горячий ключ может начать вывод. Единственный путь, который использует оба ключа вместе — это миграция, и для неё требуются обе подписи.
Что делать, если я потеряю тревожный ключ?
Вы потеряете возможность отменять выводы, инициированные вором. Вам следует немедленно выполнить обычный вывод (дождавшись истечения задержки), а затем перевести KAS в новое хранилище с новым тревожным ключом.
Что делать, если я потеряю горячий ключ?
Вы не сможете начать обычные выводы. Если наследование включено, прекратите проверки (check-in) — по истечении периода наследования средства перейдут вашему наследнику (которым может быть ваш собственный второй адрес). Без наследования средства заморожены навсегда.
Может ли команда Kaspa Forge отменить или получить доступ к моему хранилищу?
Нет. Ключи генерируются и существуют только в вашем браузере. Хранилище — это сценарий-ковенант в блокчейне Kaspa. У OfficeForge нет доступа к вашим ключам или средствам, и они не могут отменять транзакции.
Проводился ли аудит контракта хранилища?
Контракт v3 работает в основной сети и прошёл внутреннее стресс-тестирование, но внешнего аудита пока не было. Код контракта и инструмент CLI (vaultctl) открыты для независимой проверки.
Держите KAS там, где кражу можно отменить
Ковенант-сейф в мейннете Kaspa: ваши ключи, ваши правила, наш инструмент. Ончейн — бесплатно, навсегда.
Создать сейф
