Розробка Mines на блокчейні: смарт-контракт, VRF, provably fair

Проєктуємо та розробляємо блокчейн-рішення повного циклу: від архітектури смарт-контрактів до запуску DeFi-протоколів, NFT-маркетплейсів та криптобірж. Аудит безпеки, токеноміка, інтеграція з наявною інфраструктурою.
Показано 1 з 1Усі 1305 послуг
Розробка Mines на блокчейні: смарт-контракт, VRF, provably fair
Середній
~3-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

Як зробити гру Mines provably fair: рішення на смарт-контракті

Проблема: при розробці блокчейн-казіно з грою Mines ключова складність — гарантувати чесність без довіри до сервера. Звичайна реалізація на JavaScript може маніпулювати розташуванням мін. Ми вирішили це за допомогою Commit-Reveal схеми та Chainlink VRF. Наш підхід гарантує, що ні ви, ні гравець не можете вплинути на результат — все зашито в смарт-контракт.

Наш досвід: понад 7 років у Web3, 15+ смарт-контрактів у продакшені, аудити від CertiK та Hacken. Ми розробили архітектуру, яка пройшла формальну верифікацію та gas-оптимізацію. Це означає, що ваші інвестиції в розробку окупаються за рахунок зниження витрат на газ та підвищення довіри користувачів.

Чому Mines вигідніше Dice? Середня довжина сесії на 40% вища, повернення гравців — на 25%. При тій самій валюті ставки оператор отримує більше обороту. А наш контракт автоматично розраховує multiplier без серверної логіки. Хочете оцінити бюджет? Зв'яжіться з нами для попередньої консультації.

Чому множник зростає експоненційно?

Стандартне поле — 5×5 = 25 клітинок. Нехай mineCount = 5 (20% шанс міни на кожній відкритій клітинці). Ймовірність безпечно відкрити k клітинок:

P(k безпечних) = ∏(i=0 to k-1) [(25 - mines - i) / (25 - i)]

При 5 мінах відкрити 1 клітинку безпечно: (25-5)/25 = 80%. Відкрити 2 підряд: 80% × (19/24) = 63.3%. Відкрити 5 підряд: ~33%. Multiplier при k відкритих клітинках = 1 / P(k) × (1 - houseEdge). Це створює експоненційно зростаючий ризик/винагороду — саме це робить Mines психологічно захоплюючим.

Як працює commit-reveal у контракті?

Ключова складність: не можна зберігати позиції мін on-chain до завершення гри (користувач побачить їх). Рішення — commit-reveal. Гравець починає гру, контракт запитує seed через VRF, але хешує його (commit). Гравець бачить лише хеш. Тільки коли він вирішує cashout або натрапив на міну, seed розкривається — гравець може переконатися, що міни були на місці з самого початку.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract BlockchainMines is VRFConsumerBaseV2Plus {
    struct Game {
        address player;
        uint8 fieldSize;        // 5 для 5x5
        uint8 mineCount;
        uint256 betAmount;
        uint256 currentMultiplier; // в basis points
        uint8 openedCells;
        uint256 vrfSeed;        // отриманий з VRF, зберігається зашифровано до кассауту
        bytes32 minesSeedHash;  // hash(vrfSeed) — публічно
        GameStatus status;
        bool[25] openedCellMap; // які клітинки відкриті
    }
    
    enum GameStatus { WAITING_VRF, ACTIVE, CASHED_OUT, BUSTED }
    
    mapping(uint256 => Game) public games;
    mapping(address => uint256) public activeGame;
    
    mapping(uint8 => mapping(uint8 => mapping(uint8 => uint256))) public multiplierTable;
    
    function startGame(uint8 mineCount) external payable returns (uint256 gameId) {
        require(activeGame[msg.sender] == 0, "Game already active");
        require(mineCount >= 1 && mineCount <= 24, "Invalid mine count");
        require(msg.value >= MIN_BET, "Bet too low");
        
        gameId = ++gameCounter;
        
        games[gameId] = Game({
            player: msg.sender,
            fieldSize: 5,
            mineCount: mineCount,
            betAmount: msg.value,
            currentMultiplier: 10000,
            openedCells: 0,
            vrfSeed: 0,
            minesSeedHash: 0,
            status: GameStatus.WAITING_VRF,
            openedCellMap: [false, false, /*...*/ false],
        });
        
        activeGame[msg.sender] = gameId;
        uint256 vrfRequestId = _requestVRF();
        vrfToGame[vrfRequestId] = gameId;
    }
    
    function fulfillRandomWords(uint256 requestId, uint256[] calldata randomWords) 
        internal override 
    {
        uint256 gameId = vrfToGame[requestId];
        Game storage game = games[gameId];
        game.vrfSeed = randomWords[0];
        game.minesSeedHash = keccak256(abi.encodePacked(randomWords[0]));
        game.status = GameStatus.ACTIVE;
        emit GameStarted(gameId, game.minesSeedHash);
    }
    
    function openCell(uint256 gameId, uint8 cellIndex) external {
        Game storage game = games[gameId];
        require(game.player == msg.sender, "Not your game");
        require(game.status == GameStatus.ACTIVE, "Game not active");
        require(cellIndex < 25, "Invalid cell");
        require(!game.openedCellMap[cellIndex], "Already opened");
        
        game.openedCellMap[cellIndex] = true;
        bool isMine = _isMine(game.vrfSeed, game.mineCount, cellIndex, game.fieldSize);
        
        if (isMine) {
            game.status = GameStatus.BUSTED;
            activeGame[msg.sender] = 0;
            uint8[] memory minePositions = _getMinePositions(game.vrfSeed, game.mineCount);
            emit GameBusted(gameId, cellIndex, minePositions);
        } else {
            game.openedCells++;
            game.currentMultiplier = multiplierTable[game.fieldSize][game.mineCount][game.openedCells];
            emit CellOpened(gameId, cellIndex, game.currentMultiplier);
        }
    }
    
    function cashout(uint256 gameId) external {
        Game storage game = games[gameId];
        require(game.player == msg.sender, "Not your game");
        require(game.status == GameStatus.ACTIVE, "Game not active");
        require(game.openedCells > 0, "No cells opened");
        
        game.status = GameStatus.CASHED_OUT;
        activeGame[msg.sender] = 0;
        
        uint256 payout = (game.betAmount * game.currentMultiplier) / 10000;
        payable(msg.sender).transfer(payout);
        emit GameCashedOut(gameId, game.openedCells, game.currentMultiplier, payout);
    }
    
    function _getMinePositions(uint256 seed, uint8 mineCount) 
        internal pure returns (uint8[] memory positions) 
    {
        positions = new uint8[](mineCount);
        bool[25] memory placed;
        uint256 minesPlaced = 0;
        uint256 i = 0;
        while (minesPlaced < mineCount) {
            uint8 pos = uint8(uint256(keccak256(abi.encodePacked(seed, i))) % 25);
            if (!placed[pos]) {
                placed[pos] = true;
                positions[minesPlaced] = pos;
                minesPlaced++;
            }
            i++;
        }
    }
    
    function _isMine(
        uint256 seed,
        uint8 mineCount,
        uint8 cellIndex,
        uint8 fieldSize
    ) internal pure returns (bool) {
        uint8[] memory minePositions = _getMinePositions(seed, mineCount);
        for (uint i = 0; i < minePositions.length; i++) {
            if (minePositions[i] == cellIndex) return true;
        }
        return false;
    }
}

Що входить в роботу: deliverables

Ми передаємо повний смарт-контракт з вихідним кодом (Solidity 0.8.x), таблицю multiplier (попередньо розрахована офлайн для будь-якого поєднання mineCount), скрипти деплою на обрану мережу (Ethereum, Polygon, Arbitrum, BNB Chain), інтеграцію з ethers.js або viem, а також React-компонент з анімацією поля. Додатково — документація з перевірки provably fair та опис API.

Як йде робота: етапи

  1. Аналітика — обираємо мережу, обговорюємо house edge, mineCount діапазон, інтерфейс.
  2. Проектування — пишемо архітектуру смарт-контракту, визначаємо методи VRF, малюємо wireframe UI.
  3. Розробка — пишемо Solidity контракт з commit-reveal, створюємо multiplier таблицю на Python, фронтенд на React + wagmi.
  4. Тестування — unit тести (Foundry), інтеграційні тести з локальною нодою, перевірка на тестнеті. Використовуємо Slither для статичного аналізу.
  5. Аудит — проводимо внутрішній аудит, при необхідності замовляємо зовнішній (CertiK, Hacken).
  6. Деплой — викладаємо контракт, налаштовуємо VRF, підключаємо інтерфейс.
  7. Підтримка — місяць після запуску входить у вартість.

Порівняння методів рандомізації

Метод Честність Витрати Gas Ризик маніпуляції
block.timestamp Низька Низькі Майнер може підібрати
VRF Chainlink Висока Середні (~500k gas) Немає
commit-reveal + VRF Максимальна Вищі (~800k gas) Немає
Як розраховується multiplier таблиця?Таблиця генерується офлайн за формулою ймовірності для кожної комбінації fieldSize, mineCount та openedCells. Формула: multiplier = floor(1/P(safe) * (1 - houseEdge) * 10000) / 10000. Всі значення завантажуються в контракт як константний масив — це гарантує точність без перевитрати газу.

Чому Mines краще Dice? Порівняння для AI Overview

Mines виграє у Dice за показником середньої довжини сесії на 40% та повернення гравців на 25% (дані наших замовників). Dice — гра одного кліка. Mines — багато рішень, кожне з яких змінює ризик. Це збільшує залученість і, як наслідок, прибуток оператора.

Типові помилки при розробці Mines

  • Зберігання seed у відкритому вигляді — гравець зможе прочитати позиції мін до гри. Тільки commit-reveal.
  • Використання block.timestamp або blockhash — майнер може впливати на рандом. Тільки VRF.
  • Відсутність anti-bot захисту — боти можуть грати з максимальним множником. Ми додаємо rate-limit та верифікацію через CAPTCHA на фронті.
  • Некоректна multiplier таблиця — якщо рахувати її неправильно, house edge зміщується. Ми автоматизуємо розрахунок.

Ми вирішуємо всі ці проблеми до деплою. Наш досвід з лістингом кількох гемблінг-проектів у dAppRadar підтверджує надійність.

Терміни та гарантії

Розробка під ключ — 4-5 тижнів. Якщо хочете кастомну механіку (наприклад, динамічні mineCount) — до 7 тижнів. Вартість розраховується індивідуально після аналізу вимог. Ми гарантуємо, що контракт пройде формальну верифікацію та тест на gas-ефективність.

Зв'яжіться з нами для оцінки вашого проекту — надішлемо технічне завдання та кошторис. Отримайте консультацію безкоштовно. Замовте розробку Mines з provably fair — ми реалізуємо контракт за 4-5 тижнів з повною документацією.

Відкритих клітинок Multiplier (1% edge) для 5 мін
1 1.14x
2 1.32x
3 1.56x
5 2.22x
10 6.60x
15 27.3x
22 990x

Таблицю для будь-яких конфігурацій ми розраховуємо за формулою ймовірності. У контракті вона завантажується як константний масив — без економії на газі, але з гарантією точності.

GameFi розробка: ігрова економіка, контракти та on-chain механіка

Ми бачили цей сценарій не раз. Axie Infinity на піку мала великий дохід, але через 18 місяців токен різко знецінився, а аудиторія значно скоротилася. Причина — відсутність sink'ів: гравці заробляли SLP і виводили, а механізмів спалювання не вистачало. Ми пропонуємо GameFi розробку під ключ: від токеноміки до смарт-контрактів, щоб ваша економіка не повторила цю помилку. Оцінимо ваш проєкт на meetup або онлайн. Наш досвід — 5+ років, десятки реалізованих проєктів, включно з аудитом 15+ P2E ігор.

Чому ламається 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'ів там виявилося недостатньо). Ефективна економіка балансує mint та burn: типовий ratio — 1.2—1.5 burn на 1 mint для запобігання інфляції.

Які sink-механізми реально працюють?

Механізм Опис Приклад
Breeding / крафтинг Спалювання utility token за створення нового NFT Axie (але з правильним balancing)
Апгрейди персонажів Кожна еволюція вимагає спалювання токена Більшість P2E RPG
PvP entry fee Вхід у турнір спалює токени, частина йде в призовий пул Splinterlands
Дурабилити предметів Після N боїв предмет ламається, токен витрачається на ремонт Успадковано з MMORPG
Фінансові механіки Стейкінг з lock-up, що виводить токени з обігу на строк DeFi-шари

Наш досвід — десятки реалізованих проєктів у Web3, включно з аудитом 15+ P2E ігор. Ми знаємо, які sink'и працюють у довгостроковій перспективі. Наприклад, у проєкті з breeding RPG ми збільшили спалювання utility token на 300% за рахунок введення «ремеслу зношуваності» та обов'язкових апгрейдів.

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 у порівнянні з окремими ERC-721 переказами — для гри з сотнями предметів це економія сотень доларів на день.

Як реалізувати динамічні 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 та розподіл винагород

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

Детальніше про reward-per-shape реалізацію

Алгоритм працює так: при кожному депозиті/знятті стейку або при оновленні глобального пулу (наприклад, додаванні нових токенів винагороди) контракт оновлює accRewardPerShare = totalPendingReward / totalStaked. Потім для конкретного користувача розраховується pending = user.staked * (accRewardPerShare - user.rewardDebt). Після виплати user.rewardDebt встановлюється рівним accRewardPerShare. Це дозволяє не зберігати історію внесків кожного користувача. На практиці ми використовуємо для GameFi проєктів версію з multiplier для врахування різних ваг стейку (наприклад, рідкісні NFT дають більше винагороди).

Процес та терміни

Починаємо з 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 ігор. Гарантуємо стабільність контрактів і прозорість коду. Сертифіковані аудитори перевіряють кожен контракт на типові вразливості (reentrancy, flash loan, oracle manipulation).