Перейти к содержимому

VRF (Проверяемая случайная функция)

Наши гача-автоматы используют проверяемую случайную функцию (VRF), чтобы каждый розыгрыш был доказуемо честным и защищённым от манипуляций. Ни сервер, ни пользователь не могут манипулировать результатом - и это может быть независимо проверено кем угодно.

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

VRF комбинирует энтропию как от сервера, так и от клиента для создания детерминированного, проверяемого случайного числа. Вот полный процесс:

sequenceDiagram
  participant User
  participant Client App
  participant Server
  participant Blockchain

  User->>Client App: Начать розыгрыш гача
  Client App->>Server: Запросить новую сессию розыгрыша
  Server->>Server: Генерация initialEntropy (nanoid)
  Server-->>Client App: Вернуть pullId + initialEntropy
  Client App->>Client App: Генерация clientEntropy (random)
  Client App->>Blockchain: Отправить платёж с pullId|clientEntropy
  Blockchain-->>Server: Платёж подтверждён
  Server->>Server: Объединить и подписать энтропию
  Server->>Server: Хеш → finalEntropy
  Server->>Server: Преобразовать в случайное число [1-10000]
  Server->>Server: Выбрать приз на основе диапазонов уровней
  Server-->>Client App: Вернуть приз + данные доказательства VRF
  Client App->>Client App: Проверить подпись и целостность хеша
  User->>User: Может независимо проверить результат

Процесс VRF шаг за шагом

1. Начальная энтропия (сторона сервера)

Когда вы начинаете розыгрыш гача, сервер генерирует случайную строку из 10 символов, используя nanoid. Это фиксируется в базе данных до того, как вы совершите платёж, что не позволяет серверу изменить это позже.

2. Клиентская энтропия (ваша сторона)

Ваше устройство генерирует свои собственные случайные данные. Эта энтропия включается в вашу транзакцию платежа на блокчейне, создавая неизменяемую запись, которую сервер не может изменить.

3. Объединённая энтропия

Два источника энтропии объединяются:

combinedEntropy = initialEntropy + clientEntropy

4. Подписанная объединённая энтропия

Сервер подписывает объединённую энтропию, используя Ed25519 (через TweetNaCl):

signedCombinedEntropy = Ed25519.sign(combinedEntropy, serverSecretKey)

Эта подпись доказывает, что сервер обработал именно ваши значения энтропии.

5. Финальная энтропия

Подпись хешируется с использованием SHA-256 для получения финальной энтропии:

finalEntropy = SHA256(signedCombinedEntropy)

6. Генерация случайного числа

Финальная энтропия преобразуется в число в диапазоне [1, 10000]:

randomNumber = (BigInt(finalEntropy) % 10000) + 1

Это даёт нам равномерно распределённое случайное число с точностью 0,01%.

7. Выбор уровня приза

Случайное число соответствует уровням призов на основе настроенных диапазонов вероятностей. Каждый гача-автомат имеет свою собственную конфигурацию уровней.

Почему это честно

flowchart TD
  subgraph ServerCantCheat ["Сервер не может обмануть"]
      A[Начальная энтропия зафиксирована<br/>до платежа] --> B[Нельзя изменить после<br/>получения клиентской энтропии]
  end

  subgraph UserCantCheat ["Пользователь не может обмануть"]
      C[Клиентская энтропия в<br/>транзакции блокчейна] --> D[Нельзя изменить после<br/>получения начальной энтропии]
  end

  subgraph Deterministic ["Результат детерминирован"]
      E[Одинаковые входные данные всегда<br/>дают одинаковый результат] --> F[Любой может проверить<br/>вычисление]
  end

  B --> G[Честный результат]
  D --> G
  F --> G

Сервер не может манипулировать результатами потому что:

  • Начальная энтропия фиксируется в базе данных до вашего платежа
  • Сервер не знает вашу клиентскую энтропию до фиксации
  • Изменение чего-либо сделает недействительной криптографическую подпись

Пользователи не могут манипулировать результатами потому что:

  • Клиентская энтропия встроена в транзакцию блокчейна
  • После отправки её нельзя изменить
  • Начальная энтропия сервера уже зафиксирована

Результаты проверяемы потому что:

  • Все значения энтропии возвращаются вам после розыгрыша
  • Публичный ключ для проверки подписи опубликован
  • Любой может воспроизвести точное вычисление

Проверка ваших результатов

После каждого розыгрыша гача вы получаете полные данные доказательства VRF:

  1. Initial Entropy - случайная строка сервера (зафиксирована до вашего платежа)
  2. Client Entropy - ваши случайные данные (из транзакции блокчейна)
  3. Signed Combined Entropy - подпись Ed25519 сервера
  4. Final Entropy - SHA-256 хеш подписи
  5. Random Number - полученное число [1-10000]
  6. Prize Tier - в какой уровень попал ваш бросок

Приложение автоматически проверяет:

  • ✓ Подпись соответствует публичному ключу
  • ✓ Хеш подписи равен финальной энтропии
  • ✓ Вычисление случайного числа корректно

Вы также можете проверить вручную, используя любую реализацию Ed25519 и SHA-256.

Технические спецификации

КомпонентРеализация
Initial entropynanoid(10) - 10-символьная строка
Signature algorithmEd25519 (TweetNaCl)
Hash functionSHA-256
Random range[1, 10000] включительно
Precision0,01% (100 базисных пунктов)

Публичный ключ

VRF публичный ключ для проверки подписи:

i5ScBBvmGh6my9B/X+NpcUIlvRSWz7+U8M7/GprNzYk=

Это 32-байтовый публичный ключ Ed25519, закодированный в base64. Для использования в проверке декодируйте из base64 для получения необработанных байтов, затем используйте любую реализацию Ed25519 (например, TweetNaCl) для проверки подписей с этим ключом.