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 */
Одна планета может перемещать ресурсы на другую, и для такого перемещения задана скорость. При отправке можно указать, какие ресурсы следует перевезти. По прибытии, если высаженное население превышает текущее население планеты, игрок может захватить эту планету.
Подробную логику можно посмотреть в функции applyArrival (вызывается по завершении перемещения) в файле:
darkforest-v0.3/eth/contracts/DarkForestLazyUpdate.sol.
С каждым новым обновлением Dark Forest добавляются новые функции. Хотя появляется всё больше схем доказательств, связанных с расположением, основные логики остаются похожими. Если вам интересно, можете свободно ознакомиться с ними.
Объединяет хеш-значения как исходных координат, так и координат после перемещения. Очевидно, что точные координаты являются приватными входными данными, тогда как хеш — публичным входом.
Каждая планета начинается с уровня 1. Цель третьего раунда — атаковать и захватить планеты уровней 3 и выше. Чем ближе планета к началу координат, тем больше очков и выше ранг получит игрок. В центре координат расположена планета уровня 9. Игрок, захвативший эту планету, станет лидером игры.
Разные планеты имеют разные свойства. Некоторые производят ресурсы шахты, некоторые — оборудование, некоторые поддерживают улучшения, а некоторые — нет и так далее.
Красный: текущее население / максимальный лимит населения. Синий: текущее количество ресурсов шахты / максимальный лимит ресурсов шахты.Розовый: уровень защиты (в процентах) / скорость перемещения / радиус атаки. Коричневый: оборудование.
Нажмите на определённую планету, чтобы ознакомиться с её характеристиками. Ниже показаны конкретные параметры планеты, которая была захвачена:
После входа в игру основной интерфейс выглядит так, как показано выше. Он состоит из 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) для подтверждения двух операций, связанных с расположением планеты:
- Инициализация планеты (init)
- Перемещение планеты (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 {