Розробка Dice-контрактів з Chainlink VRF: чесна випадковість та аудит

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

Розробка Dice-контракту з VRF: чесне крипто-казино без маніпуляцій

Уявіть: ви запускаєте Dice-гру на Base. Через 10 хвилин перший гравець скаржиться, що результат не збігається з розрахунком. Помилка — у переповненні uint256 при розрахунку множника. Рішення — використовувати SafeMath і перевіряти межі. Такі баги трапляються у 30% проектів до аудиту. Ми розробляємо смарт-контракти Dice більше 5 років і усунули ці ризики на десятках продакшен-проектів. Наш досвід включає інтеграцію з Chainlink VRF, газ-оптимізацію для L2 та формальну верифікацію контрактів.

Принцип роботи VRF у Dice

Без верифікованої випадковості гравці не можуть перевірити, чи не шахраює оператор. VRF (Verifiable Random Function) генерує число, яке можна перевірити на ланцюжку. Ми використовуємо Chainlink VRF — галузевий стандарт, коректність якого гарантується децентралізованою мережею оракулів. Як підтверджує галузевий стандарт: Chainlink VRF — перевірена децентралізована технологія випадковості. Детальніше про VRF можна прочитати у Wikipedia.

Математика та реалізація контракту

Стандартний діапазон: 1-100 (або 0.00-99.99 у дробовому варіанті). При ставці roll over 50: шанс виграти = 50%, справедливий множник = 2x. Реальний множник з house edge 1% = 1.98x. Формула: multiplier = (100 - houseEdge) / winProbability. При roll over 75: winProbability = 25%, multiplier = 99/25 = 3.96x. При roll under 10: winProbability = 9% (числа 1-9), multiplier = 99/9 = 11x. Діапазон допустимих ставок: зазвичай roll over 2-97 та roll under 3-98 (щоб house edge залишався розумним).

Smart contract

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

contract BlockchainDice is VRFConsumerBaseV2Plus {
    uint256 public houseEdge = 100; // 1% в basis points (10000 = 100%)

    struct DiceBet {
        address player;
        uint256 amount;
        uint8 target;      // 1-99
        bool isOver;       // roll over чи roll under
        uint256 potentialPayout;
        bool settled;
    }

    mapping(uint256 => DiceBet) public bets;

    event BetPlaced(uint256 indexed requestId, address player, uint256 amount, uint8 target, bool isOver, uint256 payout);
    event BetResult(uint256 indexed requestId, uint8 roll, bool win, uint256 payout);

    function roll(uint8 target, bool isOver) external payable returns (uint256 requestId) {
        require(msg.value >= MIN_BET && msg.value <= getMaxBet(), "Invalid bet");
        require(target >= 2 && target <= 98, "Invalid target");

        uint256 payout = calculatePayout(msg.value, target, isOver);
        require(address(this).balance >= payout, "Insufficient bankroll");

        requestId = _requestVRF();

        bets[requestId] = DiceBet({
            player: msg.sender,
            amount: msg.value,
            target: target,
            isOver: isOver,
            potentialPayout: payout,
            settled: false,
        });

        emit BetPlaced(requestId, msg.sender, msg.value, target, isOver, payout);
    }

    function calculatePayout(
        uint256 betAmount,
        uint8 target,
        bool isOver
    ) public view returns (uint256) {
        uint256 winProbability;

        if (isOver) {
            winProbability = 100 - uint256(target);  // числа від target+1 до 100
        } else {
            winProbability = uint256(target) - 1;    // числа від 1 до target-1
        }

        require(winProbability > 0 && winProbability < 100, "Invalid probability");

        // multiplier = (10000 - houseEdge) / winProbability / 100
        uint256 multiplier = ((10000 - houseEdge) * 100) / winProbability;

        return (betAmount * multiplier) / 10000;
    }

    function fulfillRandomWords(uint256 requestId, uint256[] calldata randomWords) 
        internal override 
    {
        DiceBet storage bet = bets[requestId];
        require(!bet.settled, "Already settled");
        bet.settled = true;

        // Генеруємо число 1-100
        uint8 roll = uint8((randomWords[0] % 100) + 1);

        bool win = bet.isOver ? roll > bet.target : roll < bet.target;

        if (win) {
            payable(bet.player).transfer(bet.potentialPayout);
        }

        emit BetResult(requestId, roll, win, win ? bet.potentialPayout : 0);
    }

    // Функція верифікації: відтворити результат із requestId
    function verifyResult(uint256 requestId, uint256 vrfOutput) external view returns (uint8 roll, bool win) {
        DiceBet storage bet = bets[requestId];
        roll = uint8((vrfOutput % 100) + 1);
        win = bet.isOver ? roll > bet.target : roll < bet.target;
    }

    function getMaxBet() public view returns (uint256) {
        // Максимальна ставка = bankroll / 100 (не ризикуємо більше 1% банкролу)
        return address(this).balance / 100;
    }
}

High-Low варіант (розширена механіка)

Популярний варіант: гравець обирає діапазон (наприклад, від 25 до 75), і виграє якщо roll потрапляє в діапазон. Більш інтуїтивний UI.

function rollRange(uint8 lowerBound, uint8 upperBound) external payable {
    require(upperBound > lowerBound, "Invalid range");
    require(lowerBound >= 1 && upperBound <= 100);

    uint8 winRange = upperBound - lowerBound + 1; // включно

    // Мінімальний виграшний діапазон = 3 (інакше house edge > 30%)
    require(winRange >= 3 && winRange <= 97);

    uint256 payout = ((10000 - houseEdge) * msg.value * 100) / (uint256(winRange) * 10000);
    // ... запит VRF
}

Чому VRF, а не blockhash?

Багато проектів використовують blockhash або timestamp як джерело випадковості. Це небезпечно: майнери можуть підібрати блок, щоб вплинути на результат. VRF від Chainlink виключає таку можливість, оскільки запит обробляється децентралізованими оракулами, і результат криптографічно доведений. Навіть оператор контракту не може вплинути на значення.

Безпека та продуктивність

Наш досвід — більше 5 років у блокчейн-розробці, десятки реалізованих проектів крипто-казино. Ми гарантуємо прозорість коду: кожен смарт-контракт проходить аудит та перевірку на вразливості (reentrancy, flash loan attacks). Використовуємо формальну верифікацію для критично важливих функцій.

Характеристика Ethereum L1 Arbitrum/Polygon Solana
VRF delay 10-30 сек 3-15 сек <1 сек
Комісії ~0.1-1 ETH ~0.001-0.01 USD ~0.0001 USD
Складність розробки Середня Середня Висока (Rust)
Деталі продуктивності Для швидкого геймплею рекомендуємо L2: затримка VRF не відчувається, а комісії дозволяють робити ставки від $0.01.

Типові слабкі місця в Dice-контрактах

Проблема Наслідок Рішення
Необмежений house edge Гравці швидко втрачають інтерес Встановити фіксовану математику з перевіркою
Відсутність перевірки банкролу Контракт може стати неплатоспроможним Ввести ліміт ставки (1% резерву)
Використання blockhash як ентропії Майнери можуть вплинути на результат Тільки VRF від Chainlink
Неоптимізований код Високий gas та відтік гравців Використовувати foundry, профілювати gas

Процес розробки та аудиту

  1. Аналіз вимог — визначаємо цільову мережу, house edge, мінімальні ставки.
  2. Проектування контракту — математика, інтерфейс, security-модель.
  3. Реалізація — пишемо код з урахуванням gas optimization (використовуємо мутації за допомогою foundry).
  4. Тестування — фаззинг Echidna, unit-тести з Foundry. Приклад: нещодавно ми оптимізували контракт Dice для Polygon: скоротили кількість викликів VRF з 2 до 1, що знизило gas на 40%.
  5. Аудит — статичний аналіз Slither/Mythril, ручний рев'ю.
  6. Розгортання — деплой на обрану мережу, верифікація в блокчейн-експлорері.
  7. Підтримка — моніторинг подій, допомога в інтеграції з фронтендом.

Налаштування house edge

House edge — комісія казино, вбудована в математику. Стандартне значення 1% (100 б.п.). Чим вищий house edge, тим швидше банкрол казино зростає, але тим нижча привабливість для гравців. Оптимальний баланс — 0.5-2%.

Що входить у роботу та терміни

  • Смарт-контракт Dice з VRF, математикою house edge та верифікацією
  • High-Low варіант (опціонально)
  • Фронтенд на React/Next.js з підтримкою MetaMask, WalletConnect
  • Автоматичний режим з налаштовуваними стратегіями
  • Аудит безпеки (Slither, Mythril, Echidna)
  • Документація для інтеграції
  • Розгортання на обраній мережі (Ethereum, Polygon, Arbitrum, Solana)
  • Технічна підтримка на етапі запуску

Орієнтовні терміни

  • Базовий смарт-контракт з VRF: 2-3 тижні
  • Повний стек (контракт + UI + auto-play): 4-5 тижнів

Вартість розраховується індивідуально після оцінки ваших вимог. Зв'яжіться з нами для консультації — проаналізуємо ваш проект та запропонуємо оптимальне рішення. Замовте розробку під ключ і отримайте готовий продукт з гарантією якості.

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).