Русский
English
RU
Сетка BlockFirst
Картинка BlockFirst
Ссылка
Иконка копировать
Иконка скопированно

Dark Forest — игра с использованием zk-SNARK

Dark Forest — это MMO (массовая многопользовательская онлайн-игра). Меня особенно заинтересовало, что эта игра использует технологию доказательств с нулевым разглашением (zero-knowledge proof). Сегодня появляется всё больше приложений, основанных на этой технологиию.

20.07.2025
Перевод
Начинающий уровень
Автор BlockFirst
Поделиться
Иконка поделиться
Ссылка
Иконка копировать
Иконка скопировано
ARTICLE BELOW
Картинка
Превью BlockFirst
Картинка
Картинка

pub <== mimc.outs[0];

mimc.ins[0] <== x;
mimc.ins[1] <== y;
mimc.k <== 0;

*/
component mimc = MiMCSponge(2, 220, 1)

21888242871839275222246405745257275088548364400416034343698204186575808495617

220 = 2 * ceil(log_5 p), as specified by mimc paper, where
p =

/*

/* check MiMCSponge(x,y) = pub */

pub1 <== mimc1.outs[0];
pub2 <== mimc2.outs[0];

mimc1.ins[0] <== x1;
mimc1.ins[1] <== y1;
mimc1.k <== 0;
mimc2.ins[0] <== x2;
mimc2.ins[1] <== y2;
mimc2.k <== 0;

component mimc2 = MiMCSponge(2, 220, 1);

component mimc1 = MiMCSponge(2, 220, 1);

component ltDist = LessThan(32);
signal firstDistSquare;
signal secondDistSquare
firstDistSquare <== diffX * diffX;
secondDistSquare <== diffY * diffY;
ltDist.in[0] <== firstDistSquare + secondDistSquare;
ltDist.in[1] <== distMax * distMax + 1;
ltDist.out === 1;

signal diffX;
diffX <== x1 - x2;
signal diffY;
diffY <== y1 - y2;

/* check (x1-x2)^2 + (y1-y2)^2 <= distMax^2 */

component comp = LessThan(32);
signal xSq;
signal ySq;
signal rSq;
xSq <== x * x;
ySq <== y * y;
rSq <== r * r;
comp.in[0] <== xSq + ySq
comp.in[1] <== rSq
comp.out === 1;

/* check x^2 + y^2 < r^2 */

Превью BlockFirst

Одна планета может перемещать ресурсы на другую, и для такого перемещения задана скорость. При отправке можно указать, какие ресурсы следует перевезти. По прибытии, если высаженное население превышает текущее население планеты, игрок может захватить эту планету.
Подробную логику можно посмотреть в функции applyArrival (вызывается по завершении перемещения) в файле:
darkforest-v0.3/eth/contracts/DarkForestLazyUpdate.sol.

С каждым новым обновлением Dark Forest добавляются новые функции. Хотя появляется всё больше схем доказательств, связанных с расположением, основные логики остаются похожими. Если вам интересно, можете свободно ознакомиться с ними.

Объединяет хеш-значения как исходных координат, так и координат после перемещения. Очевидно, что точные координаты являются приватными входными данными, тогда как хеш — публичным входом.

Каждая планета начинается с уровня 1. Цель третьего раунда — атаковать и захватить планеты уровней 3 и выше. Чем ближе планета к началу координат, тем больше очков и выше ранг получит игрок. В центре координат расположена планета уровня 9. Игрок, захвативший эту планету, станет лидером игры.

Разные планеты имеют разные свойства. Некоторые производят ресурсы шахты, некоторые — оборудование, некоторые поддерживают улучшения, а некоторые — нет и так далее.

Красный: текущее население / максимальный лимит населения. Синий: текущее количество ресурсов шахты / максимальный лимит ресурсов шахты.Розовый: уровень защиты (в процентах) / скорость перемещения / радиус атаки. Коричневый: оборудование.

Нажмите на определённую планету, чтобы ознакомиться с её характеристиками. Ниже показаны конкретные параметры планеты, которая была захвачена:

После входа в игру основной интерфейс выглядит так, как показано выше. Он состоит из 4 частей:

  1. Панель инструментов слева. Игрок может просматривать Планеты и Артефакты. Игра поддерживает различные плагины.
  2. История транзакций справа.
  3. Карта распределения космических планет в центре. С точки зрения игрока, вся вселенная состоит из тёмного фона и тумана. Тёмный фон означает, что эта часть мира исследована и развита. Туманная область — неразвитая. В развитом космическом мире существуют планеты разных уровней.
  4. Панель управления сканированием расположена внизу, она управляет процессом сканирования и начальными координатами.

Dark Forest — это MMO (массовая многопользовательская онлайн) игра. Перемещение и атаки планет являются ключевыми стратегическими элементами всей игры. Технология доказательств с нулевым разглашением используется для подтверждения корректности перемещения планет без раскрытия их координат.

Заключение

Было приятно опробовать последнюю версию Dark Forest — v0.6 Round 3. На данный момент для участия в игре требуется приглашение (invitation code).

Игровой опыт в версии v0.6 Round 3

Во время перемещения планеты схема move проверяет, что расстояние перемещения не превышает круговую область радиусом distMax:

Схема перемещения

Схема инициализации (init Circuit) гарантирует, что координата планеты при её создании попадает в допустимый диапазон. И координаты x, и y не должны превышать 2³².

Хеш-функция mimc (x, y) вычисляется корректно. Значения x и y являются приватными входными данными, в то время как хеш — это публичный вход.

В пределах круговой области радиусом r:

Логика схем (circuits) реализована в папке: darkforest-v0.3/circuits/. Схемы реализованы с помощью Circom, а для построения доказательств используется протокол Groth16. Обе схемы довольно просты.

В версии V0.3 игры Dark Forest используется технология доказательств с нулевым разглашением (zero-knowledge proof) для подтверждения двух операций, связанных с расположением планеты:

  1. Инициализация планеты (init)
  2. Перемещение планеты (move)

Перемещение и атаки планет — это ключевой стратегический элемент игры. Поскольку атака осуществляется через перемещение, каждая планета имеет уникальные координаты. Чтобы усилить игровой опыт, координаты планет остаются скрытыми. Представьте себе бескрайнюю вселенную, в которой вы можете наблюдать (перебирать) только ограниченное окружающее пространство (с возможными коллизиями хешей), чтобы найти другие планеты. Чтобы доказать корректность перемещения планеты, не раскрывая координаты, используется технология доказательств с нулевым разглашением.

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

Планета имеет два «ресурса»: население и шахту (на данный момент поддерживается только серебро). И население, и шахта постепенно растут, но имеют верхний предел. В файле DarkForestInitialize.sol определено несколько типов планет.

Вселенная игры состоит из «Планет»:

darkforest-v0.3/eth/contracts

На данный момент Dark Forest выпустила версию v0.6. Однако код, связанный с реализацией циркулярных схем (circuit implementation), не опубликован на GitHub. Для облегчения понимания того, как используется технология доказательств с нулевым разглашением, рекомендуем ознакомиться с полным кодом версии v0.3, опубликованным на GitHub.

Посмотрите исходный код смарт-контракта, чтобы получить базовое представление о стратегии игры Dark Forest. Код находится в папке:

Схема инициализации

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

Стратегия игры

В этой статье будет рассмотрена базовая стратегия игры Dark Forest и то, как она применяет технологию доказательств с нулевым разглашением. В конце будет краткий обзор игрового опыта в последнем релизе версии v0.6 Round 3 с иллюстрациями и скриншотами.

address owner;
uint256 range;
uint256 population;
uint256 populationCap;
uint256 populationGrowth;
PlanetResource planetResource;
uint256 silverCap;
uint256 silverGrowth;
uint256 silver;
uint256 silverMax;
uint256 planetLevel;
PlanetType planetType;

}

uint256 id;
address player;
uint256 fromPlanet;
uint256 toPlanet;
uint256 popArriving;
uint256 silverMoved;
uint256 departureTime;
uint256 arrivalTime;

}

component rp = MultiRangeProof(2, 40, 2 ** 32);
rp.in[0] <== x;
rp.in[1] <== y;

/* check abs(x), abs(y), abs(r) < 2^32 */

if (_planet.population > _planetArrival.popArriving) {

} else {

);

_planetArrival.popArriving,
_planet.population

_planet.owner = _planetArrival.player;
_planet.population = SafeMath.sub(

_planet.silverMax,
SafeMath.add(_planet.silver, _planetArrival.silverMoved)

_planet.silver = Math.min(

}

}

);

}

} else {

);

);

_planet.population,
_planetArrival.popArriving

_planet.population = SafeMath.sub(

_planet.population,
_planetArrival.popArriving

_planet.population = SafeMath.add(

// simply increase the population if so

if (_planetArrival.player == _planet.owner) {

// checks whether the planet is owned by the player sending ships

) private {

DarkForestTypes.Planet storage _planet,
DarkForestTypes.ArrivalData storage _planetArrival

function applyArrival(

struct ArrivalData {

struct Planet {

if (_planet.population > _planetArrival.popArriving) {

} else {

);

_planetArrival.popArriving,
_planet.population

_planet.owner = _planetArrival.player;
_planet.population = SafeMath.sub(

_planet.silverMax,
SafeMath.add(_planet.silver, _planetArrival.silverMoved)

_planet.silver = Math.min(

}

}

);

}

} else {

);

);

_planet.population,
_planetArrival.popArriving

_planet.population = SafeMath.sub(

_planet.population,
_planetArrival.popArriving

_planet.population = SafeMath.add(

// simply increase the population if so

if (_planetArrival.player == _planet.owner) {

// checks whether the planet is owned by the player sending ships

) private {

DarkForestTypes.Planet storage _planet,
DarkForestTypes.ArrivalData storage _planetArrival

function applyArrival(

Картинка
Картинка

pub <== mimc.outs[0];

mimc.ins[0] <== x;
mimc.ins[1] <== y;
mimc.k <== 0;

*/
component mimc = MiMCSponge(2, 220, 1)

218882428718392752222464057452572750885
48364400416034343698204186575808495617

220 = 2 * ceil(log_5 p), as specified by
mimc paper, where p =

/*

/* check MiMCSponge(x,y) = pub */

pub1 <== mimc1.outs[0];
pub2 <== mimc2.outs[0];

mimc1.ins[0] <== x1;
mimc1.ins[1] <== y1;
mimc1.k <== 0;
mimc2.ins[0] <== x2;
mimc2.ins[1] <== y2;
mimc2.k <== 0;

component mimc2 = MiMCSponge(2, 220, 1);

component mimc1 = MiMCSponge(2, 220, 1);

component ltDist = LessThan(32);
signal firstDistSquare;
signal secondDistSquare
firstDistSquare <== diffX * diffX;
secondDistSquare <== diffY * diffY;
ltDist.in[0] <== firstDistSquare + secondDistSquare;
ltDist.in[1] <== distMax * distMax + 1;
ltDist.out === 1;

signal diffX;
diffX <== x1 - x2;
signal diffY;
diffY <== y1 - y2;

/* check (x1-x2)^2 + (y1-y2)^2 <= distMax^2 */

component comp = LessThan(32);
signal xSq;
signal ySq;
signal rSq;
xSq <== x * x;
ySq <== y * y;
rSq <== r * r;
comp.in[0] <== xSq + ySq
comp.in[1] <== rSq
comp.out === 1;

/* check x^2 + y^2 < r^2 */

Превью BlockFirst

С каждым новым обновлением Dark Forest добавляются новые функции. Хотя появляется всё больше схем доказательств, связанных с расположением, основные логики остаются похожими. Если вам интересно, можете свободно ознакомиться с ними.

Объединяет хеш-значения как исходных координат, так и координат после перемещения. Очевидно, что точные координаты являются приватными входными данными, тогда как хеш — публичным входом.

Каждая планета начинается с уровня 1. Цель третьего раунда — атаковать и захватить планеты уровней 3 и выше. Чем ближе планета к началу координат, тем больше очков и выше ранг получит игрок. В центре координат расположена планета уровня 9. Игрок, захвативший эту планету, станет лидером игры.

Разные планеты имеют разные свойства. Некоторые производят ресурсы шахты, некоторые — оборудование, некоторые поддерживают улучшения, а некоторые — нет и так далее.

Красный: текущее население / максимальный лимит населения. Синий: текущее количество ресурсов шахты / максимальный лимит ресурсов шахты.Розовый: уровень защиты (в процентах) / скорость перемещения / радиус атаки. Коричневый: оборудование.

Нажмите на определённую планету, чтобы ознакомиться с её характеристиками. Ниже показаны конкретные параметры планеты, которая была захвачена:

После входа в игру основной интерфейс выглядит так, как показано выше. Он состоит из 4 частей:

  1. Панель инструментов слева. Игрок может просматривать Планеты и Артефакты. Игра поддерживает различные плагины.
  2. История транзакций справа.
  3. Карта распределения космических планет в центре. С точки зрения игрока, вся вселенная состоит из тёмного фона и тумана. Тёмный фон означает, что эта часть мира исследована и развита. Туманная область — неразвитая. В развитом космическом мире существуют планеты разных уровней.
  4. Панель управления сканированием расположена внизу, она управляет процессом сканирования и начальными координатами.

Dark Forest — это MMO (массовая многопользовательская онлайн) игра. Перемещение и атаки планет являются ключевыми стратегическими элементами всей игры. Технология доказательств с нулевым разглашением используется для подтверждения корректности перемещения планет без раскрытия их координат.

Заключение

Было приятно опробовать последнюю версию Dark Forest — v0.6 Round 3. На данный момент для участия в игре требуется приглашение (invitation code).

Игровой опыт в версии v0.6 Round 3

Во время перемещения планеты схема move проверяет, что расстояние перемещения не превышает круговую область радиусом distMax:

Схема перемещения

Схема инициализации (init Circuit) гарантирует, что координата планеты при её создании попадает в допустимый диапазон. И координаты x, и y не должны превышать 2³².

Хеш-функция mimc (x, y) вычисляется корректно. Значения x и y являются приватными входными данными, в то время как хеш — это публичный вход.

В пределах круговой области радиусом r:

Логика схем (circuits) реализована в папке: darkforest-v0.3/circuits/. Схемы реализованы с помощью Circom, а для построения доказательств используется протокол Groth16. Обе схемы довольно просты.

В версии V0.3 игры Dark Forest используется технология доказательств с нулевым разглашением (zero-knowledge proof) для подтверждения двух операций, связанных с расположением планеты:

  1. Инициализация планеты (init)
  2. Перемещение планеты (move)

Перемещение и атаки планет — это ключевой стратегический элемент игры. Поскольку атака осуществляется через перемещение, каждая планета имеет уникальные координаты. Чтобы усилить игровой опыт, координаты планет остаются скрытыми. Представьте себе бескрайнюю вселенную, в которой вы можете наблюдать (перебирать) только ограниченное окружающее пространство (с возможными коллизиями хешей), чтобы найти другие планеты. Чтобы доказать корректность перемещения планеты, не раскрывая координаты, используется технология доказательств с нулевым разглашением.

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

Схема инициализации

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

component rp = MultiRangeProof(2, 40, 2 ** 32);
rp.in[0] <== x;
rp.in[1] <== y;

/* check abs(x), abs(y), abs(r) < 2^32 */

(Перевод)
Виталий Дорожко
Автор
Поделиться
Иконка поделиться
Ссылка
Иконка копировать
Иконка скопированно
Назад в блог
Кнопка назад
Оригинал статьи
кнопка вперед
Поделиться
Иконка поделиться
Ссылка
Иконка копировать
Иконка скопировано
Назад в блог
Кнопка назад
Оригинал статьи
кнопка вперед
сетка BlockFirst
сетка BlockFirst
сетка BlockFirst

Для запросов от пользователей

hello@blockfirst.io

Icon mail

Для бизнес запросов

business@blockfirst.io

Icon mail

Телеграм для быстрых ответов

Icon mail

компания

Сообщество

медиа

Подписываясь на рассылку, вы можете быть уверены, что мы не будем спамить Вам :)

Новости. Скидки. Анонсы

В начало
© 2025-2026 BlockFirst. Все права защищены.
Сетка BlockFirst
hello@blockfirst.io
Для коммерческих предложений
Компания
Телеграм для быстрых ответов
Кнопка копировать
Скопировано