TON Dice
Русский
Играть

Доказуемая честность

Исход каждой игры фиксируется до ставки и пересчитывается кем угодно — нам не нужно верить на слово.

Как это работает

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

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

Комиссия площадки — 1%. Выплата считается как ставка × 99 ÷ шанс в процентах, то есть игроку возвращается 99% математического ожидания. Это единственное, чем игра отличается от честной монетки; других удержаний нет.

Сиды

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

Третье слагаемое — nonce, номер ставки в текущей паре. Он растёт на единицу с каждой игрой, поэтому два броска одной парой не могут совпасть по входным данным.

Как получается число

Серверный сид, клиентский сид и nonce сворачиваются в HMAC-SHA512. Полученную строку из 128 hex-символов читаем окнами по пять: первое же число, меньшее 1 000 000, делим по модулю 10 000 — получается бросок от 0 до 9999, то есть от 0.00 до 99.99.

Порог отсечения нужен ради честности: окно из пяти hex-символов даёт числа до 1 048 575, а этот диапазон не делится на 10 000 нацело — без отбраковки маленькие исходы выпадали бы чаще больших. 1 000 000 делится, поэтому все 10 000 исходов равновероятны. Вероятность, что отклонятся все 25 окон, — порядка 10⁻³³.

hex = HMAC_SHA512(key = serverSeed, msg = clientSeed + "-" + nonce)

Читаем hex окнами по 5 символов подряд (0-4, 5-9, …):
первое значение < 1 000 000 → roll = значение % 10000
(если отклонены все 25 окон — roll = 9999)

Меньше: выигрыш при roll < target · Больше: выигрыш при roll > target
Выплата = ставка × 9900 / chanceUnits (округление вниз) · комиссия 1%

Код движка

Ровно то, что считает броски на сервере, и ровно то, что пересчитывает их в вашем браузере. Совпадение сторон закреплено тестом.

const WINDOW = 5;          // hex-символов в окне: 20 бит, 0..1048575
const REJECT = 1_000_000;  // наибольшее кратное 10000 в пределах окна

function roll(serverSeed, clientSeed, nonce) {
  const hex = createHmac("sha512", serverSeed)
    .update(`${clientSeed}-${nonce}`)
    .digest("hex");                        // 128 символов

  // окна по 5 hex-символов подряд: 0-4, 5-9, ... 120-124
  for (let i = 0; i * WINDOW + WINDOW <= hex.length; i++) {
    const lucky = parseInt(hex.slice(i * WINDOW, i * WINDOW + WINDOW), 16);
    if (lucky < REJECT) return lucky % 10000;   // 0..9999
  }
  // отклонены все 25 окон (вероятность ~1e-33)
  return 9999;
}

// выплата: 1% комиссии, округление вниз
const payout = (amount, chanceUnits) => amount * 9900n / BigInt(chanceUnits);

Как проверить свою игру

В мини-приложении: Честность в нижней панели, или «Проверить игру» в карточке любой ставки.

  1. Вкладка «Сиды» — здесь хеш действующего серверного сида. Он зафиксирован до ваших ставок.
  2. Смените пару сидов. Прежний серверный сид раскроется; ваш клиентский останется вашим.
  3. Вкладка «Раскрытые» — раскрытый сид лежит рядом со своим хешем. Сверьте: SHA-256 сида обязан совпасть с тем, что показывался до ставок.
  4. Вкладка «Проверка» — вставьте серверный сид, клиентский сид и nonce нужной ставки. Бросок пересчитается прямо в браузере и сравнится с результатом игры.

Расчёт идёт на вашем устройстве и к нашему серверу не обращается. По формуле выше его можно повторить в любом языке — HMAC-SHA512 есть везде.