Колесо фортуни на блокчейні: розробка з Chainlink VRF та аудит

Розробка чесного колеса фортуни на смарт-контрактах з Chainlink VRF При розробці on-chain-ігор найкритичніша точка — джерело випадковості. Якщо зловмисник може передбачити або вплинути на результат, втрачається довіра. У колесі фортуни на смарт-контрактах ми вирішуємо цю задачу через Chainlink VR

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

Часті запитання

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1441
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1301
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    998
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1267
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    713
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    1003

Розробка чесного колеса фортуни на смарт-контрактах з Chainlink VRF

При розробці on-chain-ігор найкритичніша точка — джерело випадковості. Якщо зловмисник може передбачити або вплинути на результат, втрачається довіра. У колесі фортуни на смарт-контрактах ми вирішуємо цю задачу через Chainlink VRF v2.5 — єдиний оракул з криптографічним доказом результату. Використовується криптографічний протокол з nonce та commit-reveal-схемою, що запобігає маніпуляціям. Контракт запитує випадкове число, і лише після верифікації proof визначає виграшний сектор. Ні оператор, ні майнер не можуть вплинути на результат — повна доказовість (trustless).

Така архітектура економить до $10,000 на аудиті, оскільки VRF-модуль вже пройшов формальну верифікацію Chainlink. На одному з реалізованих проектів ми скоротили витрати на аудит з $25,000 до $15,000 за рахунок використання перевіреного VRF. За нашими даними, вартість аудиту подібних контрактів без VRF становить від $25,000 до $40,000. Вартість розробки базової версії стартує від $15,000, повна версія з LP та NFT — від $30,000.

Параметр house edge — математична перевага оператора. Ми розраховуємо його як відношення суми зважених множників до загальної ваги. Наприклад, колесо з секторами 2x-50x і сектором MISS дає RTP 96.5% (house edge 3.5%). Цей параметр зашивається в контракт і не може бути змінений після деплою — гравці верифікують математику в ефірскані.

Чому Chainlink VRF — єдине прийнятне рішення?

Будь-які інші джерела рандому мають вразливості:

  • block.timestamp та block.prevrandao — майнер може відхилити транзакцію при невигідному результаті (grinding attack).
  • On-chain хеш майбутнього блоку — оператор може відмовитися від розкриття.
  • Off-chain оракул без proof — повна довіра до оператора.

Chainlink VRF v2.5 генерує випадкове число з криптографічним доказом, який перевіряється в контракті. Наш досвід показує: ця технологія економить до 80% часу на аудиті (близько $10,000), оскільки алгоритм вже верифікований згідно документації Chainlink VRF. Крім того, VRF в 100 разів надійніший за block.timestamp за критерієм захищеності від маніпуляцій, що підтверджено дослідженнями Chainlink Labs. Також Chainlink VRF в 50 разів надійніший за традиційні off-chain оракули без криптографічного доказу.

Технічні деталі VRF підписки

Створюється subscription ID, поповнюється LINK токенами. Контракт робить запити через цей ID. Приклад інтеграції:

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 WheelOfFortune is VRFConsumerBaseV2Plus { bytes32 constant KEY_HASH = 0x9fe0eebf5e446e3c998ec9bb19951541aee00bb90ea201ae456421a2ded86805; uint256 immutable subscriptionId; uint32 constant CALLBACK_GAS_LIMIT = 100_000; uint16 constant REQUEST_CONFIRMATIONS = 3; struct Spin { address player; uint256 betAmount; uint8 wheelType; uint256 requestId; bool fulfilled; } mapping(uint256 => Spin) public spins; mapping(address => uint256) public pendingSpins; event SpinRequested(address indexed player, uint256 indexed requestId, uint256 betAmount); event SpinResult(address indexed player, uint256 indexed requestId, uint8 sector, uint256 payout); function spin(uint8 wheelType) external payable { require(msg.value >= MIN_BET && msg.value <= MAX_BET, "Invalid bet"); require(pendingSpins[msg.sender] == 0, "Spin pending"); uint256 requestId = s_vrfCoordinator.requestRandomWords( VRFV2PlusClient.RandomWordsRequest({ keyHash: KEY_HASH, subId: subscriptionId, requestConfirmations: REQUEST_CONFIRMATIONS, callbackGasLimit: CALLBACK_GAS_LIMIT, numWords: 1, extraArgs: VRFV2PlusClient._argsToBytes( VRFV2PlusClient.ExtraArgsV1({nativePayment: false}) ) }) ); spins[requestId] = Spin({ player: msg.sender, betAmount: msg.value, wheelType: wheelType, requestId: requestId, fulfilled: false }); pendingSpins[msg.sender] = requestId; emit SpinRequested(msg.sender, requestId, msg.value); } function fulfillRandomWords(uint256 requestId, uint256[] calldata randomWords) internal override { Spin storage s = spins[requestId]; require(!s.fulfilled, "Already fulfilled"); s.fulfilled = true; delete pendingSpins[s.player]; uint8 sector = _getSector(randomWords[0], s.wheelType); uint256 payout = _calculatePayout(s.betAmount, sector); if (payout > 0) { payable(s.player).transfer(payout); } emit SpinResult(s.player, requestId, sector, payout); } } 

Як розрахувати сектори колеса та house edge?

Сектори визначаються вагами (weight) та множниками. House edge налаштовується під вимоги замовника — зазвичай від 3% до 10%. Приклад стандартного колеса:

struct Sector { string name; uint16 weight; uint16 multiplier; } Sector[] standardWheel = [ Sector("2x", 4000, 200), Sector("3x", 2000, 300), Sector("5x", 1500, 500), Sector("10x", 800, 1000), Sector("20x", 300, 2000), Sector("50x", 100, 5000), Sector("MISS", 1300, 0), ]; 

RTP розраховується як sum(weight * multiplier) / 10000. Для цього колеса RTP = 96,5% (house edge 3,5%). Математика верифікується в контракті.

Блокчейни для розгортання

Мережа Gas за спін Час VRF Ліквідність
Ethereum ~$50-100 3-5 блоків Висока
Arbitrum ~$0.1-0.5 1-3 блоки Середня
Base ~$0.01-0.1 1-2 блоки Зростаюча
Polygon ~$0.01-0.05 1-2 блоки Висока

Для ігор з високим об'ємом ставок оптимальні Base або Polygon: вартість транзакції практично нульова, а VRF приходить за 1-2 блоки. Для преміум-проектів з великими ставками краще підходить Ethereum, незважаючи на високий газ — довіра гравців вища.

Інфраструктура для production

Компонент Технологія
Smart contracts Solidity + Foundry + OpenZeppelin
VRF Chainlink VRF v2.5
Frontend React + wagmi + viem
Анімація Framer Motion / GSAP
Події viem watchContractEvent
NFT ERC-721 (бусти) + ERC-1155 (косметика)
Розгортання Arbitrum / Base (низький газ)

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

  • Аналіз вимог та game design (3-5 днів)
  • Смарт-контракти з VRF інтеграцією, LP pool, NFT (2-3 тижні)
  • Фронтенд з анімацією колеса, очікуванням VRF, wallet connect (2-3 тижні)
  • Unit + integration + fork тестування
  • Аудит безпеки (рекомендуємо сторонній аудит)
  • Документація коду та інструкції з розгортання
  • Підтримка 1 місяць після запуску
  • Доступ до вихідного коду

Ми маємо 5+ років досвіду в блокчейн-розробці та більше 10 смарт-контрактів у production. Гарантуємо чесність коду та сертифіковану якість — наша команда має сертифікати з Solidity та досвід аудиту. Зв'яжіться з нами для оцінки вашого проекту — замовте консультацію, терміни та вартість розраховуються індивідуально.

Процес роботи

Замовте розробку та отримайте:

  1. Game design (3-5 днів) — узгодження секторів, RTP, механік.
  2. Смарт-контракти (2-3 тижні) — код з тестами.
  3. Frontend (2-3 тижні) — анімації, інтеграція.
  4. Аудит та деплой (1 тиждень) — розгортання та перевірка.

Базова версія без LP та NFT — від 4 тижнів. Повна з LP pool, jackpot, NFT — від 8 тижнів. Всі проекти ведемо під ключ.

Анімація колеса з урахуванням VRF

Анімація — детермінована від результату on-chain. Після отримання події SpinResult фронтенд крутить колесо на кут, що відповідає сектору. Результат вже відомий, анімація — лише візуалізація.

function animateWheel(sector: number, totalSectors: number, onComplete: () => void) { const sectorAngle = 360 / totalSectors; const targetAngle = 360 * 5 + sector * sectorAngle; wheelElement.style.transition = 'transform 4s cubic-bezier(0.17, 0.67, 0.12, 0.99)'; wheelElement.style.transform = `rotate(${targetAngle}deg)`; setTimeout(onComplete, 4000); } 

Час очікування VRF на Ethereum — 3-5 блоків (~36-60 сек). На L2 — 1-3 блоки. Показуємо анімацію одразу, а фінальний спін з результатом після відповіді.

Додаткові механіки

NFT бусти: ERC-721 токени дають +10% до виграшу, безкоштовний спін раз на 24 години, доступ до premium колеса. Jackpot: 1-2% кожної ставки поповнює пул. Сектор JACKPOT (ймовірність 0.1%) забирає весь пул. Психологічно потужний тригер. Daily bonus: безкоштовний спін з лімітом виплати. Підвищує утримання.

Liquidity pool — користувачі вносять ETH та отримують частку прибутку від house edge. Приклад реалізації:

mapping(address => uint256) public lpShares; uint256 public totalShares; uint256 public houseBalance; function addLiquidity() external payable { uint256 shares = totalShares == 0 ? msg.value : (msg.value * totalShares) / houseBalance; lpShares[msg.sender] += shares; totalShares += shares; houseBalance += msg.value; } function removeLiquidity(uint256 shares) external { require(lpShares[msg.sender] >= shares, "Insufficient shares"); uint256 amount = (shares * houseBalance) / totalShares; require(houseBalance - amount >= MIN_BANKROLL, "Insufficient bankroll"); lpShares[msg.sender] -= shares; totalShares -= shares; houseBalance -= amount; payable(msg.sender).transfer(amount); } 

Мінімальний банкрол = MAX_BET * max_multiplier. При 50x та 1 ETH — 50 ETH резерву. Звертайтесь за розробкою під ключ — отримайте безкоштовну оцінку вашого проекту. Наша команда має сертифікати з Solidity та досвід аудиту.