В традиционном онлайн-блэкджеке казино хранит ваши деньги в строке базы данных и контролирует тасовку через TLS-соединение. Вы доверяете серверу оператора — или не играете. UTXO-игра Kaspa переворачивает эту модель: каждый раунд — это цепочка ковенантных состояний on-chain, и каждое из них представляет собой UTXO, скрипт погашения которого определяет единственно допустимый следующий ход. Ни один сервер не хранит средства. Ни один участник не может переписать историю. Контракт *и есть* правила.
В этой статье подробно разбирается, как именно работает эта ковенантная машина состояний для Arena Blackjack — от создания Room через JOIN, раздачу, игру и терминальный расчёт — на реальной архитектуре, которую Kaspa Forge запускает на мейннете.
Конечный автомат, в котором каждое состояние — это непотраченный выход транзакции (UTO). Переходы — это транзакции, которые потребляют текущий UTXO и порождают следующий, ковенантный скрипт которого кодирует следующее допустимое состояние. В Kaspa это основано на опкодах ковенантов Toccata, активированных в основной сети.
Проблема: азартная игра без хранителя
Доказуемо честная карточная игра on-chain должна одновременно решать три задачи:
1. Средства должны быть заблокированы, а не переданы на хранение. Ни игрок, ни дилер не должны иметь возможность забрать банк в середине раздачи. 2. Тасовка должна быть проверяемой. Ни одна из сторон не должна знать порядок карт до раздачи, но обе должны иметь возможность убедиться в честности после. 3. Каждый результат должен быть самоисполняемым. Выплата победителю не может зависеть от готовности проигравшего платить.
Модель UTXO в Kaspa необычайно хорошо подходит для этого. Каждый UTXO — это дискретная, независимо проверяемая единица состояния. Ковенантные скрипты — включённые обновлением Toccata в Kaspa — позволяют писать условия погашения, которые анализируют транзакцию, расходующую выход: какие выходы создаются, какие скрипты они несут, какую стоимость хранят. Kaspa Arena Room Game становится цепочкой UTXO, каждый из которых — состояние в конечном автомате, где ковенант *выступает* арбитром.
Анатомия Room-UTXO
Прежде чем карты будут розданы, игра начинается как Room — UTXO, созданный дилером, который блокирует средства и объявляет правила.
Room-UTXO содержит:
- Уровень ставки: один из
5 / 10 / 25 / 50 / 75 / 100 KAS, одинаковый для обеих сторон - Залог дилера:
2или5 KAS— гарантия активности дилера - Резерв комиссий: рассчитанный по худшему сценарию сетевых комиссий при текущем пороге включения, удвоенный для надёжности
- Политика входа:
OPEN(любой, кто совпадает по ставке, может присоединиться) илиINVITE(только конкретный публичный ключ игрока) - Режим комнаты:
LOCALилиHOSTED— определяет, применяется ли комиссия за ZK-доказательство - Тайм-ауты: тайм-аут комнаты (~24 часа при 10 BPS, закодировано как
864 000 DAA), плюс все дедлайны игровых фаз, зафиксированные вtimeout_policy_hash
Общая стоимость, заблокированная в Room до присоединения кого-либо, составляет 1,5 × ставка + залог_дилера + резерв. Дополнительная половина ставки — предоплата дилера на случай выплаты за натуральный блэкджек по коэффициенту 3:2.
Room-ковенант имеет ровно две ветки:
WAITING_ROOM
├── JOIN → подпись игрока + совпадающая ставка/залог → DECK_PROOF_PENDING (Game UTXO)
└── ROOM_TIMEOUT → любой после дедлайна DAA → возврат дилеру (с ограничением комиссии)
Третьего пути нет. Дилер не может вернуть средства, пока возможен корректный JOIN, а игрок не может извлечь средства, не предоставив корректную подпись с правильной ставкой.
Шаг 1: JOIN — от Room к игре
Когда игрок отправляет транзакцию JOIN, ковенант проверяет:
- Подпись игрока совпадает с заявленным публичным ключом (или, для комнат
INVITE, с зафиксированным ключом) - Игрок вносит ровно
ставка + залог_игрокав совпадающих входах - Выход-преемник несёт корректный
covenant_id— привязывая его к шаблону Game
Единственная транзакция потребляет Room-UTXO и порождает Game-UTXO в состоянии DECK_PROOF_PENDING. На этом этапе весь банк заблокирован: 2,5 × ставка + оба залога + резерв. Game-UTXO наследует все фиксации из Room — ставку, комиссии, тайм-ауты, режим — и записывает ключ, адрес и обязательство игрока в свою область состояния. Эти поля доступны для однократной записи: ни один последующий переход не может их изменить.
DECK_PROOF_PENDING
├── PROVE_AND_DEAL → подпись дилера + ZK-доказательство → PLAYER_TURN
├── DEALER_DECK_PROOF_TIMEOUT → любой после дедлайна → игрок получает все основные средства + залоги
Шаг 2: PROVE_AND_DEAL — тасовка и начальная раздача
Здесь в игру вступает проверяемость. Дилер должен доказать с помощью доказательства с нулевым разглашением, что колода была честно перетасована — что ни одна из сторон не знала порядок карт до фиксации обязательства.
Транзакция PROVE_AND_DEAL содержит:
- Журнал ZK-доказательства, привязанный к
game_id, обоим обязательствам, раскрытому сиду игрока и схеме правил deck_root— корень Меркла, фиксирующий все 52 карты в перетасованном порядке- Пути Меркла, раскрывающие карты с индексами 0, 1 и 2 (две карты игрока и открытая карта дилера)
hole_card_commit— blake3-обязательство на скрытую карту дилера (индекс 3)
Game-UTXO-преемник переходит в состояние PLAYER_TURN с next_card_index = 4, что означает: следующий HIT извлечёт карту с индексом 4 из зафиксированной колоды.
Индексы карт в протоколе V1:
0 карта игрока 1
1 открытая карта дилера
2 карта игрока 2
3 закрытая карта дилера (зафиксирована, не раскрыта)
4 первая карта при HIT
Вариант доказательства Groth16, используемый на мейннете, создаёт транзакцию объёмом ~3,2 КБ стоимостью примерно 0,16 KAS в части комиссий за доказательство — оплачивается казино согласно текущей политике комиссий V3, не вычитается из ставки игрока.
Шаг 3: Действия игрока — HIT, STAND и отсчёт времени
Попав в PLAYER_TURN, протокол блэкджека on-chain разветвляется на интерактивные состояния игры:
PLAYER_TURN
├── PLAYER_HIT_CONTINUE → корректное доказательство Меркла для следующей карты, нет перебора → PLAYER_TURN
├── PLAYER_HIT_BUST → корректное доказательство, сумма > 21 → терминал (дилер выигрывает)
├── PLAYER_STAND → подпись игрока → DEALER_TURN
├── PLAYER_ACTION_TIMEOUT → любой после дедлайна → auto-stand (без ограничений по доступу)
Каждый HIT — это ковенантный переход, который:
1. Принимает доказательство Меркла, подтверждающее, что следующая карта (с индексом next_card_index) принадлежит deck_root 2. Добавляет карту в player_hand[] 3. Вычисляет сумму руки непосредственно в скрипте из сырых байтов карты — а не из числа, предоставленного свидетелем. Скрипт пересчитывает сумму, включая логику повышения туза, напрямую из карт, которые сам выход-преемник записывает. Игрок не может указать ложную сумму — подсчёт ведёт скрипт, и его результат неоспорим.
Ветка PLAYER_ACTION_TIMEOUT заслуживает внимания: она открыта для всех (любой может отправить транзакцию) и использует последовательную блокировку для обеспечения дедлайна DAA. Она не выплачивает ставку игрока — лишь автоматически фиксирует руку, переводя раздачу к ходу дилера. Цель auto-stand — константа, встроенная в ветку, а не выбранная отправителем.
Шаг 4: Ход дилера и раскрытие закрытой карты
Когда игрок фиксирует руку, ковенант переходит в DEALER_TURN. Теперь дилер должен:
1. Раскрыть закрытую карту — транзакция должна открыть blake3-обязательство *и* одновременно проверить карту по deck_root, считывая из того же физического байта в области состояния 2. Тянуть до 17 или получить перебор — каждый HIT дилера следует той же дисциплине доказательств Меркла, что и у игрока 3. Зафиксировать руку — как только сумма дилера ≥ 17
На дилера распространяется та же дисциплина тайм-аутов. DEALER_ACTION_TIMEOUT присуждает весь банк игроку — без вычета комиссий, поскольку услуга не была оказана.
Шаг 5: Терминальный расчёт — ковенант решает
Терминальные ветки — это место, где ковенант оправдывает своё название. Результат вычисляется из обеих рук — player_hand[] и dealer_open_hand[] — непосредственно в скрипте. Ветка, формирующая расчётную транзакцию, должна доказать:
- Корректный результат (выигрыш, проигрыш, ничья или натуральный блэкджек)
- Точные суммы выходов для каждого участника
- Точные выходы комиссий (сервисная комиссия и комиссия провайдера доказательства в режиме HOSTED)
- Отсутствие посторонних выходов — ковенант фиксирует количество выходов и отклоняет любые добавления
- Резерв комиссий ограничен сверху — трата даже одного сомпи сверх лимита влечёт отклонение на уровне консенсуса
Таблица выплат:
| Результат | Получает игрок | Получает дилер | Комиссии |
|---|---|---|---|
PLAYER_WIN | нетто + залог_игрока | залог_дилера | точные выходы |
DEALER_WIN | залог_игрока | нетто + залог_дилера | точные выходы |
PUSH | ставка − комиссии_игрока + залог_игрока | ставка − комиссии_дилера + залог_дилера | точные выходы |
| Тайм-аут дилера | весь банк + оба залога | ничего | ноль |
Где нетто = 2 × ставка − комиссии. Натуральный блэкджек (ровно две карты с суммой 21) выплачивается по коэффициенту 3:2 — дополнительная половина ставки поступает из начального финансирования Room дилером. Ветка натурального выигрыша и ветка обычного выигрыша взаимоисключающие: скрипт проверяет player_natural && !dealer_natural как производный факт из байтов карт, а не как утверждение свидетеля. Сумма 21 из трёх карт — это *не* натуральный блэкджек и не запускает выплату 3:2.
Залоги всегда возвращаются полностью вне зависимости от результата. Они существуют для наказания за неявку, а не для финансирования банка. Ковенант обеспечивает это: любая терминальная ветка, которая снижает залог ниже объявленной суммы, отклоняется.
Как Kaspa Forge использует эту машину состояний
Arena Blackjack запускает именно этот конечный автомат на мейннете Kaspa как публичную бета-версию. Вкладка Arena внутри Desk позволяет игрокам просматривать открытые Room, проверять ковенантную программу и присоединяться с помощью локально подписанных транзакций. Ключи никогда не покидают устройство игрока.
В режиме HOSTED Kaspa Forge создаёт ZK-доказательство тасовки от имени игрока; комиссия за доказательство в настоящее время составляет ноль согласно политике комиссий V3 — казино покрывает её. В режиме LOCAL дилер создаёт доказательство самостоятельно. Сервисная комиссия (0,9% от банка в две ставки) появляется отдельным точным выходом только после определённого результата; тайм-ауты не создают комиссионных выходов, поскольку услуга не была оказана.
Система обеспечивает жёсткие экономические границы: не более 6 активных комнат, лимит совокупной заблокированной экспозиции в 1 300 KAS на контроллере Blackjack и резервы комиссий для каждой комнаты, рассчитанные по текущим сетевым условиям. Каждая транзакция Room, Game и терминального расчёта независимо проверяема on-chain — ковенантная программа имеет открытый исходный код, а конечный автомат протестирован через негативную матрицу из 696 случаев состояний рук и 110 случаев тайм-аутов с нулём ложных допусков.
Arena Blackjack запущен на мейннете Kaspa как публичная бета-версия. Вы можете просматривать открытые Room, проверять ковенантный код и присоединиться к игре на вкладке Arena в Desk. Вся игровая логика работает on-chain; ваши ключи остаются на вашем устройстве.
Компромиссы и честные границы
У этой архитектуры есть реальные ограничения, которые стоит понимать.
Сессионные секреты хранятся локально. Сиды дилера зашифрованы ключом устройства и никогда не покидают машину игрока. Если устройство утеряно без зашифрованного экспорта, сид невозможно восстановить. Залог дилера существует именно для отражения этого операционного риска — он компенсирует игроку исчезновение дилера.
Реорганизации требуют отката проекции. Протокол GHOSTDAG в Kaspa допускает небольшие, частые реорганизации в широком DAG. Игровая проекция откатывается до последнего канонического Game-UTXO при реорганизации; конфликтующие транзакции сохраняются локально для повторной отправки, но никогда не переписывают состояние on-chain. Интерфейс считает переход окончательным только после настроенной глубины подтверждения.
Тайм-ауты — это страховочная сеть, а не штатный путь. Каждый тупик в конечном автомате — исчезнувший игрок, удерживающий доказательство дилер, неудачное доказательство — имеет ветку тайм-аута, которая разрешает банк. Но тайм-ауты занимают время (тайм-аут действия игрока — ~2 минуты, тайм-аут комнаты — ~24 часа), и в течение этого окна средства заблокированы.
Ёмкость намеренно ограничена. Шесть активных комнат и лимит экспозиции в 1 300 KAS — это не инженерные ограничения, а меры контроля рисков для бета-системы. Капитальная политика отслеживает подтверждённые обычные UTXO, сверенный залог и ожидающие резервации, чтобы предотвратить двойной учёт средств между играми.
Чем этот продукт не является. Dice прошёл значительную инженерную подготовку, но его постоянная продакшн-ветка отключена до завершения независимой проверки. Duel и баккара — идеи из дорожной карты, а не продукты. Permissionless Tokens запланирован, но не запущен. Ни одно из этого не следует путать с конечным автоматом блэкджека, описанным выше, который работает на мейннете сегодня.
Ключевая идея проста: в Kaspa UTXO *и есть* состояние, транзакция *и есть* переход, а ковенантный скрипт *и есть* арбитр. Блэкджек — первая игра, построенная на этом фундаменте. Машина состояний не доверяет ни одной стороне — она доверяет математике.
FAQ
Что такое UTXO-игра Kaspa?
UTXO-игра Kaspa кодирует каждый раунд как серию переходов состояний UTXO, обеспечиваемых ковенантными скриптами. Каждое состояние игры — это расходуемый выход, правила погашения которого определяют единственно допустимый следующий ход — без сервера, без хранителя, без доверия.
Как Room-UTXO защищает обоих игроков?
Room блокирует ставку дилера, залог и резерв комиссий в ковенанте с ровно двумя ветками: корректный JOIN от подходящего игрока или ROOM_TIMEOUT, возвращающий средства дилеру. Ни одна из сторон не может в одностороннем порядке забрать банк.
Что произойдёт, если игрок исчезнет в середине игры?
Ковенант включает ветку PLAYER_ACTION_TIMEOUT. После истечения дедлайна DAA любой может отправить транзакцию, которая автоматически фиксирует руку игрока (auto-stand), переводя игру к ходу дилера без подписи отсутствующего игрока.
Как обеспечиваются выплаты в блэкджеке on-chain?
Терминальные ветки вычисляют результат из обеих рук непосредственно в скрипте, а затем фиксируют точные суммы выходов и адреса. Ковенант отклоняет любую транзакцию, которая недоплачивает победителю, переплачивает комиссии или добавляет посторонние выходы — математика и есть контракт.
Запущен ли Arena Blackjack?
Arena Blackjack находится в публичной бета-версии на основной сети. Dice прошёл значительную инженерную подготовку, но его постоянная продакшн-ветка отключена до завершения независимой проверки. Duel и баккара — идеи из дорожной карты, а не продукты.
Где хранятся мои ключи во время игры?
Ключи всегда остаются на устройстве игрока. Игровые транзакции подписываются локально; Kaspa Forge никогда не хранит приватные ключи и не выступает кастодианом средств.
Держите KAS там, где кражу можно отменить
Ковенант-сейф в мейннете Kaspa: ваши ключи, ваши правила, наш инструмент. Ончейн — бесплатно, навсегда.
Создать сейф