Live edition loading…

PXke Algorand

Independent daily coverage of the Algorand ecosystem — verified reporting on wallets, DeFi, NFTs and infrastructure, fact-checked on-chain before it publishes.

← Latest stories

ZK Color Sort проверяет ежедневные результаты головоломки в блокчейне с помощью доказательств с нулевым разглашением

· · · · · · ·

ZK Color Sort проверяет ежедневные результаты головоломки в блокчейне с помощью доказательств с нулевым разглашением

Ежедневная головоломка с криптографической таблицей результатов

ZK Color Sort выглядит как головоломка с переливанием цветов, в которую играют на телефоне в ожидании кофе: двенадцать пробирок, десять цветов, переливай, пока в каждой пробирке не останется один цвет. Фишка в том, что страница просит вас сделать после того, как вы закончили. «Подключите кошелёк Algorand, чтобы разблокировать эту функцию», — гласит надпись рядом с кнопкой «Результаты» и счётчиком ходов. Это не платный доступ. Подключение поддерживаемого кошелька — сейчас это Lute или Pera — открывает доступ к настоящей сути игры: отправке вашего результата в смарт-контракт Algorand mainnet вместе с доказательством с нулевым разглашением — криптографическим сертификатом, подтверждающим истинность утверждения без раскрытия данных, стоящих за ним. Здесь утверждение звучит так: «Я решил эту конкретную головоломку за N ходов», а данные, которые остаются приватными, — сама последовательность ходов. Для игры в головоломку кошелёк вообще не нужен; таблица результатов, доступ к которой открывается только при наличии доказательства, — это ончейн-слой.

Ежедневная головоломка берётся из блокчейна. Фронтенд запрашивает у индексатора Algorand первый заголовок блока после полуночи по UTC и детерминированно выводит поле из сида этого заголовка, так что задача публична и воспроизводима из истории блокчейна, а не выбирается разработчиком. Правила следуют стандартному формату Color Sort, точно описанному в README проекта: двенадцать пробирок ёмкостью четыре; десять цветов, каждый из которых встречается ровно четыре раза; две пустые пробирки для переливания; допустимый ход перемещает максимальную непрерывную серию одного цвета в пустую пробирку или в пробирку, верхний цвет которой совпадает; головоломка решена, когда каждая непустая пробирка полностью одноцветна. Результат — это количество ходов, чем меньше, тем лучше; лучшие локальные результаты с полной историей ходов хранятся в localStorage браузера. Ончейн-реестр никогда не примет результат, который не превосходит лучший записанный результат игрока.

Что именно подтверждает доказательство с нулевым разглашением

Любая ончейн-таблица лидеров для игры, требующей мастерства, сталкивается с проблемой доверия: контракт, принимающий число, примет любое число. Доверенный сервер, проверяющий игру, возвращает централизацию, а публикация выигрышного решения раскрывает стратегию, которая к нему привела. ZK Color Sort выбирает третий путь — докажи, но не показывай.

Когда игрок отправляет результат, браузер прогоняет схему Circom через snarkjs — библиотеку доказательств на JavaScript с открытым исходным кодом — и создаёт Groth16-доказательство, одну из самых распространённых схем с нулевым разглашением. При первой отправке загружается примерно 55-мегабайтный ключ доказательства, который игра поставляет как статический ресурс; после этого весь конвейер работает на стороне клиента, без сервера доказательств. Выбор стека не случаен: в README библиотеки snarkjs-algorand отмечается, что gnark — компилятор, лежащий в основе альтернативного верификатора AlgoPlonk, — не поддерживает WebAssembly, что исключило бы генерацию доказательств прямо в браузере; snarkjs написан на TypeScript и работает там, где находится игрок.

Схема подогнана под точный профиль этой игры — двенадцать пробирок, вместимость четыре, до 120 ходов, десять цветов, две пустые пробирки — и обеспечивает полную семантику игры: валидное стартовое поле, легальные ходы по правилам переливания, корректные переходы состояния после каждого хода, полностью решённое финальное поле и количество ходов, равное числу активных ходов. Что является публичным, а что остаётся приватным, — и есть весь дизайн:

ПонятиеПрактическое значение
Публичное: стартовое полеЛюбой может подтвердить, к какой головоломке относится результат
Публичное: количество ходовЧисло, которое хранит реестр и по которому сортируется таблица лидеров
Публичное: идентификатор головоломки и адрес кошелькаПривязаны к доказательству, поэтому доказательство, созданное для одной головоломки или одного аккаунта, нельзя воспроизвести для другой
Приватное: полная последовательность ходовНаблюдатели могут проверить утверждение, не копируя выигрышную стратегию, — обычная причина гибели ончейн-таблиц лидеров для головоломок

Ончейн-реестр результатов

Принимающая сторона — смарт-контракт PuzzleScores, написанный на Algorand TypeScript — современном языке контрактов, компилируемом Puya, который пришёл на смену более старому PyTeal. Он хранит по одному результату для каждой пары (головоломка, кошелёк) в box-хранилище — состоянии, привязанном к самому контракту. Ключ представляет собой 20-байтовый код головоломки, объединённый с 32-байтовым адресом кошелька (всего 52 байта); значение — один байт, что ограничивает хранимые результаты 255 ходами, с большим запасом покрывая любые решения этой головоломки. Создание записи стоит ровно минимальный баланс для box, который контракт вычисляет в рантайме (базовые 2,500 микроALGO плюс 400 за байт) и возвращает, если игрок удаляет запись через removeScore. Методы чтения позволяют игроку получить свой собственный результат или результат любого другого игрока.

Есть два пути записи: addScore для первой записи и updateScore, который контракт принимает только если новый результат строго меньше сохранённого. Оба требуют сопутствующей транзакции «верификатора» в той же атомарной группе, и именно здесь проверяется доказательство. Фронтенд составляет группу из трёх транзакций — платёж на ноль, подписанный логической подписью (счёт, чьи полномочия определяются программой, а не приватным ключом, производной от ключа проверки игры), платёж минимального баланса и вызов приложения. Контракт проверяет, что аттестационный платёж приходит с настроенного адреса верификатора и что публичные сигналы доказательства совпадают с заявленным результатом, кодом головоломки и отправителем; математика проверки Groth16 выполняется внутри программы логической подписи, которая генерирует аттестационный платёж только при принятии свидетеля. Поскольку результат, головоломка и кошелёк игрока привязаны к одному доказательству, отправку, созданную для одной головоломки или одного аккаунта, нельзя использовать повторно для другой. На фронтенде то же box-хранилище обеспечивает просмотр процентиля: после подключения игра сканирует ончейн-записи для головоломки дня и показывает игроку, сколько других он обошёл.

Запущен в mainnet — но кто играет?

Контракт реальный, развёрнутый и актуальный: приложение 3603459425 было создано в раунде 62,209,315 16 июня 2026 года аккаунтом, стоящим за проектом (владеющим .algo-именем tools.orange.algo), а его верификатор был настроен несколькими минутами позже. Сейчас в нём 94 box-записи с результатами, а в реестре видны вызовы приложения вплоть до раунда 64,130,520 — 16 августа 2026 года, за два дня до написания этой статьи. Веб-сборка подтверждает, что сеть фронтенда по умолчанию — mainnet, что соответствует идентификатору приложения в сетевой конфигурации репозитория.

Однако реестр отправителей рассказывает более скромную историю внедрения. Собственный кошелёк разработчика доминирует и в журнале транзакций, и в ключах box; второй кошелёк для отправки был создан в день запуска и пополнен разработчиком на 1 ALGO — это тестовый аккаунт. Ещё два кошелька получили первое финансирование от несвязанных аккаунтов, созданных в 2022 и 2024 годах, что согласуется с внешними игроками, хотя ни один из них не имеет .algo-имени. Честный вывод: реестр жив, но мал, большинство записей можно отнести на счёт собственного тестирования разработчика, и пока нет свидетельств значительной базы игроков.

Сам проект — работа одного разработчика — GitHub-аккаунт funk-af, в профиле которого владельца зовут Эндрю, — и тот же аккаунт публикует другие работы по смарт-контрактам Algorand, включая репозитории, описанные как смарт-контракты для Baanx и для протокола пополнения карт Immersve flexi-card. В репозитории игры 18 коммитов от июня 2026 года и никакой активности с 18 июня, при этом развёрнутый фронтенд и ончейн-контракт продолжают работать.

Где доверительная модель упирается в ограничения

Три оговорки важны для тех, кто читает этот реестр как нечто большее, чем игру. Во-первых, вывод ежедневной головоломки — это соглашение на стороне фронтенда, а не правило контракта: контракт никогда не проверяет, соответствует ли представленный код головоломки сегодняшней, полученной из блока; схема проверяет только корректность и решаемость головоломки. Доказательство для любой корректной головоломки из того же профиля схемы будет принято; ничто в ончейне не привязывает отправку к текущей дате. Во-вторых, и адрес верификатора, и сам контракт контролируются создателем — setVerifier и updateApplication доступны только кошельку создателя, — поэтому целостность реестра в конечном счёте зависит от того, что один разработчик не подменит верификатор и не перепишет контракт. В-третьих, стек доказательств не аудирован: в README snarkjs-algorand предупреждается, что SDK «находится в стадии разработки и пока не стабилен» и что «код в этом репозитории не аудирован. Используйте на свой страх и риск!»

Ни одно из этих замечаний не умаляет того, что здесь действительно примечательно: рабочая сквозная демонстрация генерации Groth16-доказательств на стороне браузера, питающая ончейн-верификатор в Algorand mainnet, с ежедневной головоломкой, источником которой служат заголовки блоков самой сети. Если эта схема разовьётся — аудированный верификатор, закрепление головоломки на уровне контракта и настоящие игроки — ниша игр на мастерство с проверкой на основе доказательств с нулевым разглашением получит надёжную основу. Пока же это честный маленький эксперимент, и он работает.

Источники

Source: https://zk-colorsort.netlify.app/