Blockchain dice game development

We design and develop full-cycle blockchain solutions: from smart contract architecture to launching DeFi protocols, NFT marketplaces and crypto exchanges. Security audits, tokenomics, integration with existing infrastructure.
Showing 1 of 1 servicesAll 1306 services
Blockchain dice game development
Medium
~3-5 business days
FAQ
Blockchain Development Services
Blockchain Development Stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1214
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    852
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1041
  • image_logo-advance_0.png
    B2B Advance company logo design
    561
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    823

Blockchain Dice Game Development

Dice—basic casino game: player chooses number (threshold) and direction (roll over/roll under), places bet. If result matches condition—win. Simplest mechanic but requires attention to math of house edge and mandatory verifiable randomness.

Dice Mathematics

Standard range: 1-100 (or 0.00-99.99 fractional).

Roll over 50: win chance = 50%, fair multiplier = 2x. Actual with 1% house edge = 1.98x.

Formula: multiplier = (100 - houseEdge) / winProbability

Roll over 75: winProbability = 25%, multiplier = 99/25 = 3.96x. Roll under 10: winProbability = 9%, multiplier = 99/9 = 11x.

Valid range: roll over 2-97 and roll under 3-98 (to keep house edge reasonable).

Smart Contract

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

contract BlockchainDice is VRFConsumerBaseV2Plus {
    uint256 public houseEdge = 100; // 1% in basis points

    struct DiceBet {
        address player;
        uint256 amount;
        uint8 target;      // 1-99
        bool isOver;       // roll over or 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);
        } else {
            winProbability = uint256(target) - 1;
        }
        
        require(winProbability > 0 && winProbability < 100, "Invalid probability");
        
        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;
        
        // Generate number 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);
    }
    
    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) {
        return address(this).balance / 100;
    }
}

High-Low Variant

Player chooses range (e.g., 25 to 75), wins if roll in range. More intuitive UI.

function rollRange(uint8 lowerBound, uint8 upperBound) external payable {
    require(upperBound > lowerBound, "Invalid range");
    require(lowerBound >= 1 && upperBound <= 100);
    
    uint8 winRange = upperBound - lowerBound + 1;
    require(winRange >= 3 && winRange <= 97);
    
    uint256 payout = ((10000 - houseEdge) * msg.value * 100) / (uint256(winRange) * 10000);
}

UX for Fast Gameplay

Dice is fast game. Players place dozens bets per minute. UX must support:

  • Quick presets (½x, 2x bet, max bet)
  • Auto mode with custom strategies
  • Instant feedback (dice animation, sounds)
  • Bet history with results

On L2 (Arbitrum, Polygon): VRF delay 3-15 sec—acceptable. Mainnet may be uncomfortable.

Developing Dice contract with VRF—2-3 weeks. With frontend (React + animations) and auto mode—4-5 weeks.