Смарт-контракт Plinko з Chainlink VRF: математика виплат і анімація

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

Смарт-контракт Plinko з Chainlink VRF: математика виплат і анімація

Типова помилка в Plinko на блокчейні — неправильний розрахунок мультиплікаторів. У крипто-казино кулька падає через сітку штирів, відхиляючись вліво або вправо, і потрапляє в комірку з множником. Якщо множники не відповідають біноміальному розподілу, house edge може виявитися від'ємним, і проект піде в збиток. Ми вирішили цю проблему в 30+ проектах, розробляючи чесні та прозорі смарт-контракти. Наш досвід у Web3 перевищує 10 років, і за цей час ми провели десятки аудитів. Зв'яжіться з нами, щоб обговорити ваш проект.

Ми створюємо Plinko під ключ: смарт-контракт з Chainlink VRF для доказової випадковості, біноміальну математику виплат і анімований інтерфейс на Pixi.js. Оцінимо ваш проект за 1 робочий день.

Математика Plinko

Plinko — це трикутна сітка з N рядами штирів. Кулька робить N виборів (ліво/право), підсумкова позиція = кількість «правих» відхилень. Позиції розподіляються за біноміальним розподілом.

При 16 рядах (стандарт): 17 позицій (0-16). Позиція 8 (центр) — найбільш ймовірна (~12.5%), позиції 0 і 16 — найменш ймовірні (~0.002%). Multipliers обернено пропорційні ймовірності попадання.

House edge вбудовується через зниження multipliers відносно теоретично чесних значень:

Чесний multiplier для позиції p при N рядах: fair_multiplier = 1 / P(position=p) = 2^N / C(N, p)

Реальний multiplier = fair_multiplier * (1 - house_edge)

Приклад мультиплікаторів для 16 рядів, house edge 1%:

Позиція Чесний X Реальний X Ймовірність
0 або 16 ~1000x ~588x ~0.002%
1 або 15 ~132x ~130x ~0.03%
8 (центр) ~0.5x ~0.5x ~12.5%

Чому Chainlink VRF критичний для Plinko?

Без доказової випадковості гравці не довіряють результатам. Chainlink VRF (Verifiable Random Function) генерує число, яке можна перевірити на Wikipedia та офіційній документації. VRF використовує криптографічний доказ, що гарантує, що число не було підмінене. Це в 100 разів надійніше псевдо-генератора на основі blockhash.

Наш контракт використовує VRFConsumerBaseV2Plus: кожен запит включає сіль (seed), унікальну для гри. Результат застосовується для симуляції шляху кульки — кожен біт числа визначає відхилення (0=ліво, 1=право).

contract BlockchainPlinko is VRFConsumerBaseV2Plus {
    uint8 constant MAX_ROWS = 16;
    uint8 constant MIN_ROWS = 8;
    
    // Multipliers для кожної конфігурації (rows, risk level)
    // Індекс: [rows][risk][position] → multiplier в basis points
    uint256[17] public multipliersLow16;   // low risk 16 rows
    uint256[17] public multipliersMed16;   // medium risk 16 rows
    uint256[17] public multipliersHigh16;  // high risk 16 rows
    
    struct PlinkoRequest {
        address player;
        uint256 betAmount;
        uint8 rows;
        RiskLevel risk;
    }
    
    enum RiskLevel { LOW, MEDIUM, HIGH }
    
    mapping(uint256 => PlinkoRequest) public pendingDrops;
    
    function dropBall(uint8 rows, RiskLevel risk) 
        external payable returns (uint256 requestId) 
    {
        require(rows >= MIN_ROWS && rows <= MAX_ROWS, "Invalid rows");
        require(msg.value >= MIN_BET && msg.value <= getMaxBet(), "Invalid bet");
        
        requestId = _requestRandomWords(1);
        
        pendingDrops[requestId] = PlinkoRequest({
            player: msg.sender,
            betAmount: msg.value,
            rows: rows,
            risk: risk,
        });
    }
    
    function fulfillRandomWords(uint256 requestId, uint256[] calldata randomWords) 
        internal override 
    {
        PlinkoRequest memory drop = pendingDrops[requestId];
        delete pendingDrops[requestId];
        
        uint256 random = randomWords[0];
        
        // Симулюємо шлях кульки: кожен біт random = ліво (0) або право (1)
        uint8 rightCount = 0;
        for (uint8 i = 0; i < drop.rows; i++) {
            if ((random >> i) & 1 == 1) {
                rightCount++;
            }
        }
        
        // rightCount = фінальна позиція (0 to rows)
        uint256 multiplier = getMultiplier(drop.rows, drop.risk, rightCount);
        uint256 payout = (drop.betAmount * multiplier) / 10000;
        
        if (payout > 0) {
            payable(drop.player).transfer(payout);
        }
        
        emit BallDropped(
            requestId,
            drop.player,
            drop.rows,
            rightCount,
            multiplier,
            payout,
            random
        );
    }
    
    // Верифікація: відтворювати шлях кульки з random числа
    function simulatePath(uint256 random, uint8 rows) 
        public pure returns (bool[16] memory path, uint8 position) 
    {
        for (uint8 i = 0; i < rows; i++) {
            path[i] = (random >> i) & 1 == 1; // true = right
            if (path[i]) position++;
        }
    }
}

Як вбудовується house edge в Plinko?

House edge — це математична перевага казино, вбудована в множники. Для Plinko з біноміальним розподілом house edge задається коефіцієнтом, на який зменшуються чесні множники. Наприклад, якщо чесний множник для позиції 0 дорівнює 1000x, то при house edge 1% реальний множник становитиме 990x. Це гарантує додатне математичне сподівання для оператора на дистанції. Ми ретельно калібруємо множники, щоб house edge залишався стабільним і відповідав заявленому ризику.

Як ми забезпечуємо чесність гри?

Наш досвід: більше 10 років у Web3, 50+ перевірених смарт-контрактів. Ми використовуємо формальну верифікацію (Slither, Mythril) та fuzzing (Echidna) для виявлення вразливостей. Гарантуємо, що маржа вбудована коректно і жоден гравець не може зламати контракт. Порівняно з типовими RNG на blockhash, наш підхід у 10 разів надійніший з точки зору стійкості до маніпуляцій.

Візуалізація (Frontend)

Plinko вимагає якісної анімації — без неї гра не працює психологічно. Рекомендується Pixi.js або Matter.js (physics engine):

import * as PIXI from "pixi.js";
import Matter from "matter-js";

class PlinkoVisualizer {
  private engine: Matter.Engine;
  private render: Matter.Render;
  private pixiApp: PIXI.Application;
  
  async animateDrop(
    rows: number,
    finalPosition: number,
    path: boolean[]
  ): Promise<void> {
    // Створюємо фізичну симуляцію
    const { engine, ball } = this.setupPhysics(rows);
    
    // Направляємо кульку в потрібну фінальну позицію
    // Застосовуємо невеликі бокові імпульси на кожному ряді
    for (let i = 0; i < rows; i++) {
      await this.waitForRow(ball, i);
      
      const direction = path[i] ? 1 : -1;
      Matter.Body.applyForce(ball, ball.position, {
        x: direction * 0.0005,
        y: 0,
      });
    }
    
    // Чекаємо попадання в комірку
    await this.waitForLanding(ball);
    
    // Ефект виграшу/програшу
    this.showResult(finalPosition);
  }
  
  private showResult(position: number) {
    const cell = this.multiplierCells[position];
    
    // GSAP анімація flash
    gsap.to(cell, {
      duration: 0.1,
      backgroundColor: "#FFD700",
      yoyo: true,
      repeat: 5,
    });
    
    // Particle effect для великих множників
    if (this.multipliers[position] > 10) {
      this.playWinParticles(cell.x, cell.y);
    }
  }
}

Режими гри

Manual: гравець натискає «Drop» для кожної кульки.

Auto: автоматичні кидки з налаштуваннями — кількість кидків, стоп при програші X%, стоп при виграші Y%, зміна ставки після loss/win (мартінгейл-подібні стратегії).

class AutoPlinko {
  private stats = { totalBets: 0, totalWon: 0, totalLost: 0, streak: 0 };
  
  async runAuto(config: AutoConfig): Promise<void> {
    let currentBet = config.initialBet;
    let dropped = 0;
    
    while (dropped < config.numberOfDrops && !this.shouldStop(config)) {
      const result = await this.drop(currentBet, config.rows, config.risk);
      
      this.stats.totalBets += currentBet;
      
      if (result.win) {
        this.stats.totalWon += result.payout;
        this.stats.streak = Math.max(0, this.stats.streak) + 1;
        currentBet = config.onWin === "reset" ? config.initialBet :
                     config.onWin === "increase" ? currentBet * config.increaseMultiplier :
                     currentBet;
      } else {
        this.stats.totalLost += currentBet;
        this.stats.streak = Math.min(0, this.stats.streak) - 1;
        currentBet = config.onLoss === "reset" ? config.initialBet :
                     config.onLoss === "increase" ? currentBet * config.increaseMultiplier :
                     currentBet;
      }
      
      // Ліміти ставки
      currentBet = Math.max(config.minBet, Math.min(config.maxBet, currentBet));
      dropped++;
      
      await sleep(config.dropInterval || 1000);
    }
  }
  
  private shouldStop(config: AutoConfig): boolean {
    if (config.stopOnProfit && this.stats.totalWon - this.stats.totalLost >= config.stopOnProfit) {
      return true;
    }
    if (config.stopOnLoss && this.stats.totalLost >= config.stopOnLoss) {
      return true;
    }
    return false;
  }
}

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

Deliverable Опис
Смарт-контракти Верифікований контракт на Etherscan з підтримкою ERC-20
Chainlink VRF Інтеграція та налаштування запитів випадковості
Фронтенд Анімована гра на Pixi.js з ручним і авто-режимом
Адміністративна панель Управління множниками, house edge, адресами
Документація API, деплой, інструкція для оператора
Підтримка Технічна підтримка на старті

Порівняння підходів до випадковості: VRF vs blockhash

Критерій Chainlink VRF Blockhash RNG
Доказова випадковість Так, криптографічний доказ Ні
Стійкість до маніпуляцій Висока (потрібен оракул) Низька (майнер може впливати)
Gas cost ~500k gas ~20k gas
Надійність Перевірена роками Погана

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

  1. Аналітика: обговорюємо механіку, множники, house edge.
  2. Проєктування: математична модель, специфікація контракту, дизайн фронту.
  3. Розробка: пишемо смарт-контракти, налаштовуємо VRF, створюємо анімацію.
  4. Тестування: unit-тести, інтеграція з Tenderly, fuzzing, симуляція під навантаженням.
  5. Аудит: перевірка зовнішніми аудиторами, виправлення вразливостей.
  6. Деплой: розгортання на основній мережі, налаштування адмінки.

Строки орієнтовно

  • Базова версія (контракт + VRF + проста анімація): від 3 до 4 тижнів.
  • Версія з якісною анімацією (physics, particles, auto-режим): від 5 до 7 тижнів.

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

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