Разработка системы RNG (Random Number Generator) на блокчейне

Использовать `block.timestamp`, `block.prevrandao` или хэш предыдущего блока для генерации случайных чисел — рискованно: майнер или валидатор может влиять на эти значения. Несколько лет назад известная лотерея потеряла $4M из-за манипуляции блочным хэшем. Случайные числа на блокчейне — нетривиальная

Направления блокчейн-разработки

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1452
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1310
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1005
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1270
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    719
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    1012

Использовать block.timestamp, block.prevrandao или хэш предыдущего блока для генерации случайных чисел — рискованно: майнер или валидатор может влиять на эти значения. Несколько лет назад известная лотерея потеряла $4M из-за манипуляции блочным хэшем. Случайные числа на блокчейне — нетривиальная задача, требующая индивидуального подхода. Мы разрабатываем системы RNG под ключ, оцениваем угрозы и предлагаем оптимальное решение. Наш опыт насчитывает более 50 успешных проектов в этой области.

Почему on-chain рандом сложен?

Блокчейн детерминирован. Каждый узел должен прийти к одному результату, выполняя одни и те же операции. Это фундаментально противоречит случайности: если результат предсказуем — он не случаен. Любой источник, который виден в блокчейне до фиксации результата, может быть использован атакующим.

Validator bias — валидатор на Ethereum видит block.prevrandao (RANDAO reveal) до публикации блока. Если результат невыгоден — он может пропустить свой слот (слот пропускается, результат меняется). Стоимость атаки = потерянное вознаграждение за слот (~0.01 ETH). Если ставка в лотерее > 0.01 ETH — атака рациональна.

Chainlink VRF: стандарт для большинства случаев

Chainlink VRF (Verifiable Random Function) — наиболее проверенное решение для NFT-минта, лотерей, игровой механики. Chainlink VRF работает через оракульную сеть:

  1. Контракт запрашивает случайное число, отправляя LINK.
  2. Chainlink-нода генерирует случайное число и криптографическое доказательство.
  3. Доказательство верифицируется on-chain перед использованием числа.
// VRF V2.5 (актуальная версия) import {VRFConsumerBaseV2Plus} from "@chainlink/contracts/src/v0.8/vrf/dev/VRFConsumerBaseV2Plus.sol"; import {VRFV2PlusClient} from "@chainlink/contracts/src/v0.8/vrf/dev/libraries/VRFV2PlusClient.sol"; contract Lottery is VRFConsumerBaseV2Plus { uint256 public s_subscriptionId; bytes32 public keyHash; // gas lane uint32 public callbackGasLimit = 200_000; uint16 public requestConfirmations = 3; mapping(uint256 => address) public requestToPlayer; function requestRandomWinner() external returns (uint256 requestId) { requestId = s_vrfCoordinator.requestRandomWords( VRFV2PlusClient.RandomWordsRequest({ keyHash: keyHash, subId: s_subscriptionId, requestConfirmations: requestConfirmations, callbackGasLimit: callbackGasLimit, numWords: 1, extraArgs: VRFV2PlusClient._argsToBytes( VRFV2PlusClient.ExtraArgsV1({nativePayment: false}) ) }) ); requestToPlayer[requestId] = msg.sender; } function fulfillRandomWords( uint256 requestId, uint256[] calldata randomWords ) internal override { address player = requestToPlayer[requestId]; uint256 result = randomWords[0] % totalTickets; _declareWinner(player, result); } } 

requestConfirmations: 3 — ждём 3 блока подтверждения перед генерацией. Это усложняет reorg-атаки на request.

Ограничения VRF: latency 1-3 блока (15-45 секунд на mainnet), стоимость LINK на каждый запрос (0.25-2 LINK в зависимости от сети), необходимость subscription менеджмента. Для high-frequency gameplays (каждый ход в игре требует рандома) — слишком дорого и медленно.

Commit-reveal: рандом без оракула

Для случаев без доступа к Chainlink или при необходимости минимизировать затраты — commit-reveal схема:

Слабое место commit-reveal: последний, кто раскрывает secret, видит финальный результат до публикации. Он может выбрать не раскрывать (griefing) или раскрыть только если результат выгоден. Mitigation: штраф за не-reveal (bond при commit, который сгорает при неявке).

Пример реализации с бондами
mapping(address => bytes32) public commits; mapping(address => uint256) public bonds; uint256 public bondAmount = 0.1 ether; function commit(bytes32 commitment) external payable { require(msg.value == bondAmount); commits[msg.sender] = commitment; bonds[msg.sender] = msg.value; } function reveal(uint256 secret) external { require(keccak256(abi.encode(secret, msg.sender)) == commits[msg.sender]); // process secret payable(msg.sender).transfer(bonds[msg.sender]); // возврат залога delete bonds[msg.sender]; } function claimBond(address participant) external { require(bonds[participant] > 0); // проверка, что участник не раскрыл в срок // перевести залог штрафующему } 

RANDAO: нативный Ethereum рандом после Merge

После перехода на PoS Ethereum предоставляет block.prevrandao — агрегированный RANDAO reveal от валидаторов. Это лучше, чем старый block.difficulty, но имеет описанную выше проблему validator bias.

Для некритичных применений (косметика в игре, порядок в очереди, некрупные лотереи) — block.prevrandao достаточен и бесплатен:

uint256 random = uint256(keccak256(abi.encode( block.prevrandao, block.timestamp, msg.sender, nonce++ ))); 

Добавление msg.sender и nonce увеличивает entropy и усложняет предсказание для конкретного пользователя, хотя не устраняет validator bias.

Как выбрать подходящий метод RNG?

Применение Ставка / ценность Рекомендация
NFT минт (whitelist рандом) Высокая Chainlink VRF
Лотерея с крупным призом Высокая Chainlink VRF + requestConfirmations: 5+
Внутриигровой рандом (предметы) Средняя Commit-reveal или Chainlink VRF
Порядок в очереди Низкая block.prevrandao
PvP матчмейкинг Низкая block.prevrandao + nonce

Сравнение методов

Метод Безопасность Скорость Стоимость Комплексность
Chainlink VRF Высокая 1-3 блока 0.25-2 LINK на запрос Средняя
Commit-reveal Средняя (зависит от механик) 2+ раунда Только газ Высокая
RANDAO Низкая (validator bias) 0 блоков Бесплатно Низкая
Гибрид (off-chain + on-chain) Высокая 0 блоков Комбинация Высокая

Гибридные решения

Для gamefi-проектов, где требуется быстрый рандом с высокой throughput, используем off-chain VRF с on-chain commitment:

  1. Backend генерирует seed через Chainlink VRF заранее.
  2. Hash seed публикуется on-chain (commitment).
  3. При каждом игровом событии — используем HMAC(seed, event_id) как рандом.
  4. После сессии — раскрываем seed, пользователи могут верифицировать все результаты.

Это даёт instant response на каждое действие и полную верифицируемость постфактум. Гибридное решение экономит до 90% газа по сравнению с прямыми VRF запросами, а при высокочастотном использовании — в 5-10 раз дешевле.

Что вы получаете

  • Анализ угроз и выбор оптимальной схемы.
  • Интегрированный смарт-контракт с покрытием юнит-тестами (более 200 тестов).
  • Документацию по развертыванию и использованию.
  • Поддержку при деплое и мониторинге.
  • Обучение команды (опционально).

Гарантируем прозрачность — все решения верифицируемы на блокчейне. Свяжитесь с нами для оценки вашего проекта.

Процесс работы

Аналитика. Определяем threat model: кто может атаковать? Какова максимальная выгода от манипуляции? Какая latency допустима? Есть ли доступ к Chainlink на целевом чейне.

Разработка и тестирование. VRFConsumer тестируем через VRFCoordinatorV2_5Mock из пакета Chainlink — позволяет симулировать fulfillment в unit-тестах без реальной оракульной сети. Commit-reveal тестируем на сценарии griefing и last-revealer атак.

Деплой. Для Chainlink VRF — создаём subscription, фондируем LINK, добавляем consumer. Настраиваем мониторинг баланса subscription.

Ориентиры по срокам

Интеграция Chainlink VRF в существующий контраст: 1-2 дня. Система RNG с commit-reveal и anti-griefing: 1-2 дня. Гибридный off-chain VRF с on-chain commitment и верификацией: 3-5 дней.

Получите консультацию — оценим ваш проект и предложим оптимальное решение под ключ.