Crash-игра с честным рандомом на блокчейне

Проектируем и разрабатываем блокчейн-решения полного цикла: от архитектуры смарт-контрактов до запуска DeFi-протоколов, NFT-маркетплейсов и криптобирж. Аудит безопасности, токеномика, интеграция с существующей инфраструктурой.
Показано 1 из 1Все 1305 услуг
Crash-игра с честным рандомом на блокчейне
Средний
~5 дней
Часто задаваемые вопросы

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

Этапы блокчейн-разработки

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

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

Разработка блокчейн-игры Crash — это не просто смарт-контракт с рандомом. Главная дилемма: как дать игрокам абсолютную уверенность в честности результата, не жертвуя скоростью? Классические решения на Ethereum L1 тонут в газе и задержках — транзакция cashout идёт 12 секунд, а краш может произойти за 100 мс. L2-сети (Arbitrum, Polygon) и гибридные архитектуры с off-chain подписями решают эту задачу. Мы делаем ставку на provably fair через Chainlink VRF и batch settlement — это позволяет обрабатывать миллионы раундов с комиссией менее $0.01 за транзакцию.

Crash — игра, в которой множитель растёт от 1x вверх и в случайный момент «крашится». Игроку нужно успеть вывести ставку до краша. В децентрализованной версии результат раунда обязан быть provably fair: игрок может математически проверить, что множитель не был подтасован. Это достигается через commitment scheme и ончейн-рандом от Chainlink. При этом критически важна архитектура cashout — от неё зависит экономика и user experience. Ниже разберём ключевые узлы.

Как реализовать provably fair в блокчейн Crash?

Commitment + Reveal схема (без оракула)

Классическая схема: operator заранее публикует hash следующего seed, потом раскрывает seed после завершения ставок.

contract CrashGame {
    struct Round {
        bytes32 seedHash;
        bytes32 seed;
        uint64 crashPoint;
        uint256 totalBets;
        uint256 startTime;
        RoundStatus status;
    }
    
    enum RoundStatus { ACCEPTING_BETS, IN_PROGRESS, CRASHED, CASHOUT_PHASE }
    
    function commitNextRound(bytes32 seedHash) external onlyOperator {
        require(rounds[nextRoundId].status == RoundStatus.CRASHED, "Previous not finished");
        rounds[nextRoundId + 1].seedHash = seedHash;
    }
    
    function revealAndStart(uint256 roundId, bytes32 seed) external onlyOperator {
        Round storage round = rounds[roundId];
        require(round.status == RoundStatus.ACCEPTING_BETS, "Wrong status");
        require(keccak256(abi.encodePacked(seed)) == round.seedHash, "Seed mismatch");
        
        round.seed = seed;
        round.crashPoint = _calculateCrashPoint(seed, roundId);
        round.status = RoundStatus.IN_PROGRESS;
        round.startTime = uint64(block.timestamp);
        
        emit RoundStarted(roundId, round.crashPoint);
    }
}

Проблема commitment схемы: оператор знает seed заранее и может отказаться раскрывать невыгодный (griefing). Решение — VRF.

Chainlink VRF V2 Plus: trustless random

import {VRFConsumerBaseV2Plus} from "@chainlink/contracts/src/v0.8/vrf/dev/VRFConsumerBaseV2Plus.sol";

contract CrashGame is VRFConsumerBaseV2Plus {
    uint256 private immutable s_subscriptionId;
    bytes32 private immutable s_keyHash;
    
    mapping(uint256 => uint256) public roundToVrfRequest;
    mapping(uint256 => uint256) public vrfRequestToRound;
    
    function closeAndRequestRandom(uint256 roundId) external onlyOperator {
        Round storage round = rounds[roundId];
        require(round.status == RoundStatus.ACCEPTING_BETS, "Wrong status");
        
        round.status = RoundStatus.IN_PROGRESS;
        
        uint256 requestId = s_vrfCoordinator.requestRandomWords(
            VRFV2PlusClient.RandomWordsRequest({
                keyHash: s_keyHash,
                subId: s_subscriptionId,
                requestConfirmations: 1,
                callbackGasLimit: 100_000,
                numWords: 1,
                extraArgs: VRFV2PlusClient._argsToBytes(
                    VRFV2PlusClient.ExtraArgsV1({nativePayment: false})
                )
            })
        );
        
        roundToVrfRequest[roundId] = requestId;
        vrfRequestToRound[requestId] = roundId;
    }
    
    function fulfillRandomWords(
        uint256 requestId,
        uint256[] calldata randomWords
    ) internal override {
        uint256 roundId = vrfRequestToRound[requestId];
        Round storage round = rounds[roundId];
        
        uint256 rand = randomWords[0];
        round.crashPoint = _calculateCrashPoint(rand);
        round.seed = bytes32(rand);
        
        emit RoundActive(roundId, round.startTime = uint64(block.timestamp));
    }
}

Chainlink VRF documentation: "VRF provides cryptographic proofs that the random number was generated using the block data and the oracle's secret key."

Формула crash point

Математика crash point с house edge 1%

Целевое распределение: P(crash >= X) = 0.99/X. Минимальный crash = 1.00x.

function _calculateCrashPoint(uint256 rand) internal pure returns (uint64) {
    uint256 h = rand % 1_000_000_000;
    
    if (h < 10_000_000) return 100; // 1.00x
    
    uint256 crashPoint = 990_000_000 * 100 / h;
    
    if (crashPoint < 100) return 100;
    if (crashPoint > 100_000) return 100_000;
    
    return uint64(crashPoint);
}

Верификация: любой игрок может взять VRF randomWords[0] из on-chain данных и воспроизвести формулу — получит тот же crash point.

Почему ручной cashout — узкое место и как его обойти?

Ставки и cashout механика

struct Bet {
    address player;
    uint256 amount;
    uint64 autoCashoutAt;
    bool cashedOut;
    uint64 cashoutMultiplier;
}

mapping(uint256 => mapping(address => Bet)) public bets;

function placeBet(uint256 roundId, uint64 autoCashoutAt) external payable {
    Round storage round = rounds[roundId];
    require(round.status == RoundStatus.ACCEPTING_BETS, "Not accepting bets");
    require(msg.value >= MIN_BET && msg.value <= MAX_BET, "Invalid amount");
    require(bets[roundId][msg.sender].amount == 0, "Already bet");
    
    bets[roundId][msg.sender] = Bet({
        player: msg.sender,
        amount: msg.value,
        autoCashoutAt: autoCashoutAt,
        cashedOut: false,
        cashoutMultiplier: 0
    });
    
    rounds[roundId].totalBets += msg.value;
    emit BetPlaced(roundId, msg.sender, msg.value, autoCashoutAt);
}

function cashout(uint256 roundId) external {
    Round storage round = rounds[roundId];
    Bet storage bet = bets[roundId][msg.sender];
    
    require(round.status == RoundStatus.IN_PROGRESS, "Round not active");
    require(bet.amount > 0 && !bet.cashedOut, "No active bet");
    
    uint64 currentMultiplier = _getCurrentMultiplier(round.startTime);
    require(currentMultiplier <= round.crashPoint, "Round already crashed");
    
    bet.cashedOut = true;
    bet.cashoutMultiplier = currentMultiplier;
    
    uint256 payout = bet.amount * currentMultiplier / 100;
    payable(msg.sender).transfer(payout);
    
    emit CashedOut(roundId, msg.sender, currentMultiplier, payout);
}

function _getCurrentMultiplier(uint64 startTime) public view returns (uint64) {
    uint256 elapsed = block.timestamp - startTime;
    uint256 multiplier = 100 + (elapsed * elapsed * 2);
    return uint64(multiplier > 100_000 ? 100_000 : multiplier);
}

Manual cashout on-chain имеет latency. Игрок нажимает cashout в UI → транзакция в mempool → включается в блок (10–12 сек на Ethereum). За это время раунд может крашнуться. На L2 (Arbitrum: 250 мс, Solana: 400 мс) это более приемлемо, но всё равно не идеально. Комиссия за транзакцию на Arbitrum — менее $0.01, что делает частые cashout экономически оправданными.

Решение для low-latency: гибридная архитектура. Off-chain cashout: игрок подписывает cashout request → game server сохраняет подписанный timestamp → при settlement on-chain game server доказывает, что игрок запросил cashout до краша. Требует доверия к game server, но с cryptographic accountability.

Off-chain batch settlement

struct CashoutRecord {
    address player;
    uint64 multiplier;
    bytes signature;
}

function settleBatch(
    uint256 roundId,
    CashoutRecord[] calldata cashouts
) external onlyOperator {
    Round storage round = rounds[roundId];
    require(round.status == RoundStatus.CRASHED, "Round not crashed");
    
    for (uint i = 0; i < cashouts.length; i++) {
        CashoutRecord calldata c = cashouts[i];
        Bet storage bet = bets[roundId][c.player];
        
        require(!bet.cashedOut, "Already settled");
        require(c.multiplier <= round.crashPoint, "Invalid multiplier");
        
        _verifyCashoutSignature(roundId, c.player, c.multiplier, c.signature);
        
        bet.cashedOut = true;
        bet.cashoutMultiplier = c.multiplier;
        
        uint256 payout = bet.amount * c.multiplier / 100;
        payable(c.player).transfer(payout);
    }
}

Сравнение сетей для блокчейн Crash

Сеть Время блока Gas cost (типичный) Подходит для MVP Резюме
Ethereum L1 12-15 sec Высокий (~$50/tx) Нет Только для high-roller из-за latency и fees
Arbitrum One ~250 ms Низкий ($0.01-$0.05) Да Лучший balance: скорость, безопасность, экосистема
Polygon PoS ~2 sec Очень низкий ($0.001) Да Ещё дешевле, но меньше децентрализации
Solana ~400 ms Минимальный ($0.0001) Да Максимальная скорость, но Rust-разработка сложнее

Гибридный cashout и batch settlement позволяют экономить до $5000 ежемесячно на газе при высокой активности игроков. Средняя комиссия на Arbitrum — $0.01-0.03 за cashout, что делает микротранзакции рентабельными.

Процесс работы над проектом

  1. Аналитика и спецификация — определение механик, house edge, RNG, требований к latency.
  2. Проектирование смарт-контракта — архитектура, выбор паттернов (commitment, VRF, batch settlement).
  3. Реализация контрактов — Solidity, Foundry, тщательное тестирование (unit, integration, fork).
  4. Разработка backend и frontend — Node.js game server, WebSocket, React с real-time графикой.
  5. Аудит и формальная верификация — Slither, Echidna, Mythril, при необходимости — auditor третья сторона.
  6. Деплой и мониторинг — контракты в mainnet, настройка Tenderly, дэшборды.
  7. Регуляторный compliance — подготовка документов для лицензии, интеграция KYC/AML.
Этап Длительность Результат
Аналитика и спецификация 1-2 недели Документ с требованиями, UI mockups
Проектирование контракта 1-2 недели Архитектура, ERC-имплементация
Реализация контрактов 3-4 недели Готовые контракты, тесты, CI
Backend и frontend 4-6 недель Game server, WebSocket, UI
Аудит и верификация 2-3 недели Audit report, исправления
Деплой и мониторинг 1 неделя Контракты в сети, мониторинг

Что входит в работу (deliverables)

  • Исходный код смарт-контрактов (Solidity) с полным набором тестов.
  • Развёрнутая документация по архитектуре, формулам, процедуре верификации.
  • Game server (Node.js) с WebSocket и интеграцией с контрактами.
  • Frontend (React) с визуализацией и кошельком (MetaMask, WalletConnect).
  • Инструкция по деплою и управлению (Tenderly, Etherscan).
  • Поддержка при запуске (24/7 в первую неделю).

Наш опыт и метрики

Более 5 лет мы разрабатываем блокчейн-решения для GameFi. В портфолио — 10+ проектов, включая Crash, Dice и NFT-лотереи. Наши контракты прошли аудит в ведущих фирмах и обработали более 1 млн транзакций. Закажите аудит смарт-контрактов перед релизом — это снизит риски на 90%. Для запуска собственной Crash-игры свяжитесь с нами для консультации.

Ориентировочные сроки

  • MVP (Chainlink VRF, ручной cashout on-chain, базовый UI): 4–6 недель.
  • Production (гибридный cashout, batch settlement, bankroll management, регуляторный compliance): 10–14 недель.

Стоимость рассчитывается индивидуально исходя из объёма работ и выбранного стека. Для точной оценки свяжитесь с нами — мы подготовим коммерческое предложение. Получите консультацию перед стартом: обсудим архитектуру и KPI.

Игровая экономика, контракты и on-chain механика

Мы видели этот сценарий не раз. Axie Infinity на пике генерировал $800M в месяц, но через 18 месяцев токен рухнул на 98%, аудитория — на 95%. Причина — отсутствие sink'ов: игроки зарабатывали SLP и выводили, а механизмов сжигания не хватало. Исследование экономики Axie (Collins Dictionary) подтвердило: модель превратилась в схему Понци. Мы предлагаем GameFi разработку под ключ: от токеномики до смарт-контрактов, чтобы ваша экономика не повторила эту ошибку. Оценим ваш проект на meetup или онлайн.

Где ломается Play-to-Earn экономика

Инфляционная токеномика без sink'ов. Игрок получает токены за геймплей. Если sink'ов (механизмов сжигания или потребления) недостаточно — supply растёт быстрее demand. Цена падает. Доход игрока в fiat уменьшается. Игроки уходят. Смертельная спираль.

Правильная конструкция — dual-token модель с чётким разделением: governance/value token с ограниченным supply и utility/reward token для внутриигровой экономики. Utility token должен активно потребляться: крафтинг предметов, апгрейды, entry fees, breeding. Примеры: GODS/FLUX в Gods Unchained, AXS/SLP в Axie (хотя sink'ов там оказалось недостаточно).

Какие sink-механизмы реально работают?

  • Breeding / крафтинг — сжигание utility token за создание нового NFT (как в Axie, но с правильным balancing).
  • Апгрейды персонажей — каждая эволюция требует сжигания токена.
  • PvP entry fee — вход в турнир сжигает токены, часть идёт в призовой пул.
  • Дурабилити предметов — после N боёв предмет ломается, токен тратится на ремонт.
  • Финансовые механики — стейкинг с lock-up, что выводит токены из обращения на срок.

On-chain vs Off-chain: где проходит граница

Всю игровую логику on-chain выносить не нужно — каждая транзакция стоит газа и длится 12 секунд. Игровой цикл — миллисекунды. Баланс:

Компонент On-chain Off-chain Примеры
Ownership активов + NFT предметы, land
Передача/торговля + Маркетплейсы
Финансы (стейкинг, rewards) + Staking vaults, DAO
Random generation + (через VRF) Chainlink VRF
Игровой процесс + Боевая система, движение
State игрового мира + Координаты, health points
Матчмейкинг + Серверная логика

Результаты геймплея переносятся на блокчейн через signed message от сервера или ZK-proof. Verifiable off-chain с ZK: игровой сервер генерирует ZK-proof корректности сессии, контракт верифицирует proof и начисляет награду. Реализации: Cartridge (Starknet), zkSync game rollups.

Реализация NFT игровых предметов

Стандарт: ERC-1155 для взаимозаменяемых предметов (ресурсы, consumables) + ERC-721 для уникальных (персонажи, land). ERC-1155 даёт до 60% экономии на газе при batch transfer.

Как реализовать динамические NFT без перегрузки блокчейна?

Характеристики предмета меняются в процессе игры (experience, durability, upgrades). Два подхода:

  • Fully on-chain: атрибуты хранятся в mapping контракта, tokenURI генерируется из атрибутов через SVG/JSON encoding. Дорого по газу при частом обновлении. Используется для land и ключевых активов.
  • Hybrid: атрибуты хранятся off-chain, в tokenURI — hash состояния. Обновление подписывается сервером, верифицируется on-chain при transfer или продаже. Дешевле, но требует доверия к серверу или ZK.

Breeding и crafting. Контракт: два родительских NFT → оплата utility token (burn) → минт нового NFT с атрибутами, зависящими от родителей + Chainlink VRF для случайности. Без VRF майнеры могут манипулировать рандомом через выбор блока.

// Simplified breeding with Chainlink VRF
function breed(uint256 parent1Id, uint256 parent2Id) external {
    require(ownerOf(parent1Id) == msg.sender);
    require(ownerOf(parent2Id) == msg.sender);
    require(breedingToken.burnFrom(msg.sender, BREEDING_COST));

    uint256 requestId = vrfCoordinator.requestRandomWords(...);
    pendingBreeds[requestId] = BreedRequest(parent1Id, parent2Id, msg.sender);
}

function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal override {
    BreedRequest memory req = pendingBreeds[requestId];
    uint256 childAttributes = deriveAttributes(req.parent1Id, req.parent2Id, randomWords[0]);
    _mintWithAttributes(req.requester, childAttributes);
}

Маркетплейс и роялти

Встроенный маркетплейс даёт контроль над fee структурой и кастомной логикой (запрет торговли предметами до определённого уровня). Роялти по EIP-2981 — стандарт, но не enforceable: Blur и другие маркетплейсы игнорируют on-chain роялти. Для enforcement — whitelist-only transfer (только через контракты, платящие роялти). Жертвуем composability ради защиты прав.

Staking и rewards distribution

Staking NFT — механика для удержания игроков. Проблема: начисление rewards при тысячах стейкеров требует постоянных транзакций (дорого). Решение — reward-per-share паттерн (как в MasterChef от SushiSwap): глобальный accRewardPerShare, при claim или change state пересчитывается задолженность по формуле pendingReward = stakedAmount * (accRewardPerShare - userRewardDebt). O(1) сложность независимо от числа стейкеров. Экономия газа — до 70% по сравнению с поэлементным начислением.

Процесс и сроки

Начинаем с game economics документа: token flows, mint/burn механики, projected supply schedule, sink analysis. До написания кода экономика моделируется (Cadence, Python simulation).

Как мы строим GameFi: 5 этапов

  1. Экономическое моделирование — 1-2 недели. Разрабатываем dual-token модель, рассчитываем sink'ы, прописываем стимулы для long-term holding.
  2. Разработка токен-контрактов — 2-3 недели. ERC-20 для governance, ERC-20 для utility, с настраиваемой политикой mint/burn.
  3. Смарт-контракты NFT — 3-5 недель. ERC-721 / ERC-1155 с dynamic metadata, breeding/crafting, Chainlink VRF.
  4. Staking + rewards — 2-3 недели. Контракт на базе reward-per-share, интерфейсы для frontend.
  5. Маркетплейс (опционально) — 2-4 недели. Кастомный маркетплейс с enforced royalty.

Что входит в работу

  • Исходный код всех смарт-контрактов с тестами (Foundry/Hardhat)
  • Документация архитектуры и экономики
  • Интеграция с Chainlink, Tenderly для мониторинга
  • Аудит кода и формальная верификация (Slither, Mythril, Echidna)
  • Обучение команды работе с контрактами
  • Поддержка после деплоя (3 месяца)

Базовый GameFi стек (токены + NFT + staking + маркетплейс) — от 8 до 16 недель. Полная игра с on-chain рандомом, breeding, dynamic NFT — 4-8 месяцев. ZK-based verifiable gameplay — отдельный проект от 6 месяцев.

Свяжитесь с нами для аудита вашей токеномики — оценим риски и доработаем sink-механизмы. Закажите разработку GameFi проекта — получите готовый продукт с проверенной экономикой. Гарантируем стабильность контрактов и прозрачность кода. Наш опыт — десятки реализованных проектов в Web3, включая аудит 15+ P2E игр.