Provably fair blockchain casino 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
Provably fair blockchain casino development
Complex
from 2 weeks to 3 months
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

Provably Fair Blockchain Casino Development

Provably fair is mathematical guarantee of fairness each result player can verify independently. Not "trust us", but "check the math". Key competitive advantage blockchain casino vs traditional online gambling where player trusts RNG certificates.

How Provably Fair Works

Two main approaches: VRF on-chain and commit-reveal off-chain.

Chainlink VRF On-chain

VRF generates random number with cryptographic proof that number truly random and can't be predicted or changed by operator.

Process:

  1. Contract requests randomness from Chainlink VRF
  2. Chainlink oracle generates number and proof
  3. On-chain: proof verified, number accepted
  4. Anyone can check: this proof = this number, no other number matches this proof

Player sees: requestId → blockHash → randomness. Public and verifiable.

Commit-Reveal Off-chain

Classic provably fair for off-chain systems:

1. Casino generates server_seed (random string)
2. Casino publishes hash(server_seed) before each game
3. Player provides client_seed
4. After game casino reveals server_seed
5. Result = HMAC-SHA256(server_seed, client_seed + nonce)
6. Anyone can reproduce: knowing server_seed + client_seed + nonce → same result

Casino can't change server_seed after publishing hash. Player can't change client_seed: fixed in bet. Result deterministic but unpredictable until round ends.

On-chain Implementation with Chainlink VRF

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

contract ProvablyFairCasino is VRFConsumerBaseV2Plus {
    struct BetRecord {
        address player;
        uint256 amount;
        uint8 gameId;
        bytes betParams;
        uint256 vrfRequestId;
        uint256 randomResult;
        bool settled;
        uint256 payout;
    }
    
    mapping(uint256 => BetRecord) public betRecords;
    
    event BetPlaced(
        uint256 indexed requestId,
        address indexed player,
        uint8 gameId,
        uint256 amount,
        bytes betParams
    );
    
    event BetSettled(
        uint256 indexed requestId,
        uint256 randomness,      // actual random—public
        uint256 payout,
        bool isWin
    );
    
    function placeBet(uint8 gameId, bytes calldata betParams) 
        external payable returns (uint256 requestId) 
    {
        require(msg.value >= MIN_BET[gameId], "Below minimum");
        require(msg.value <= MAX_BET[gameId], "Above maximum");
        require(msg.value <= getMaxBet(), "Exceeds bankroll limit");
        
        requestId = s_vrfCoordinator.requestRandomWords(
            VRFV2PlusClient.RandomWordsRequest({
                keyHash: KEY_HASH,
                subId: SUBSCRIPTION_ID,
                requestConfirmations: 3,
                callbackGasLimit: 200_000,
                numWords: 1,
                extraArgs: VRFV2PlusClient._argsToBytes(
                    VRFV2PlusClient.ExtraArgsV1({nativePayment: false})
                )
            })
        );
        
        betRecords[requestId] = BetRecord({
            player: msg.sender,
            amount: msg.value,
            gameId: gameId,
            betParams: betParams,
            vrfRequestId: requestId,
            randomResult: 0,
            settled: false,
            payout: 0,
        });
        
        emit BetPlaced(requestId, msg.sender, gameId, msg.value, betParams);
    }
    
    function fulfillRandomWords(
        uint256 requestId,
        uint256[] calldata randomWords
    ) internal override {
        BetRecord storage bet = betRecords[requestId];
        require(!bet.settled, "Already settled");
        
        bet.randomResult = randomWords[0];
        bet.settled = true;
        
        uint256 payout = _resolveGame(bet.gameId, bet.amount, bet.betParams, randomWords[0]);
        bet.payout = payout;
        
        bool isWin = payout > 0;
        
        if (isWin) {
            payable(bet.player).transfer(payout);
        }
        
        // randomWords[0] public in event—anyone can verify
        emit BetSettled(requestId, randomWords[0], payout, isWin);
    }
}

Off-chain Commit-Reveal Implementation

class ProvablyFairEngine {
  async createSession(userId: string): Promise<Session> {
    const serverSeed = crypto.randomBytes(32).toString("hex");
    const serverSeedHash = crypto
      .createHash("sha256")
      .update(serverSeed)
      .digest("hex");
    
    const session = await db.createSession({
      userId,
      serverSeed: this.encrypt(serverSeed),
      serverSeedHash,
      nonce: 0,
      createdAt: new Date(),
    });
    
    return { sessionId: session.id, serverSeedHash };
  }
  
  async resolve(
    sessionId: string,
    clientSeed: string,
    gameType: string,
    betAmount: number
  ): Promise<GameResult> {
    const session = await db.getSession(sessionId);
    const serverSeed = this.decrypt(session.serverSeed);
    
    const nonce = ++session.nonce;
    const hashHex = crypto
      .createHmac("sha256", serverSeed)
      .update(`${clientSeed}-${nonce}`)
      .digest("hex");
    
    const rawResult = parseInt(hashHex.slice(0, 8), 16);
    const gameResult = this.applyGameLogic(gameType, rawResult);
    
    await db.saveGameRecord({
      sessionId,
      nonce,
      clientSeed,
      serverSeedHash: session.serverSeedHash,
      gameType,
      result: gameResult.outcome,
      betAmount,
      payout: gameResult.payout,
    });
    
    return gameResult;
  }
  
  async rotateSession(sessionId: string): Promise<void> {
    const session = await db.getSession(sessionId);
    const serverSeed = this.decrypt(session.serverSeed);
    
    // Publicly reveal—now all games verifiable
    await db.revealServerSeed(sessionId, serverSeed);
    await this.createSession(session.userId);
  }
}

Verification on Player Side

Player must have UI for self-verification:

function verifyGameResult(
  serverSeed: string,
  clientSeed: string,
  nonce: number,
  gameType: string,
  claimedResult: string
): boolean {
  const hmac = createHmac("sha256", serverSeed);
  hmac.update(`${clientSeed}-${nonce}`);
  const hash = hmac.digest("hex");
  
  const rawValue = parseInt(hash.slice(0, 8), 16);
  const calculatedResult = applyGameLogic(gameType, rawValue);
  
  return calculatedResult.outcome === claimedResult;
}

Bankroll Management for Fair Casino

Provably fair about randomness AND bankroll transparency. Public metrics:

interface PublicCasinoStats {
  totalBetsCount: number;
  totalWagered: bigint;
  totalPaidOut: bigint;
  currentBankroll: bigint;
  theoreticalRTP: number;
  actualRTP: number;
  biggestWin: { amount: bigint; txHash: string; date: Date };
  recentResults: Array<{
    gameType: string;
    result: string;
    serverSeedHash: string;
  }>;
}

Public data builds trust. Player sees claimed 97% RTP matches actual.

Stack

Component Technology
Smart contract Solidity + Chainlink VRF v2.5
Off-chain engine Node.js + TypeScript
DB PostgreSQL
Encryption AES-256-GCM
Frontend verifier React
Monitoring Grafana

Timeline

  • Basic games with VRF (Dice, Coinflip, Crash): 4-6 weeks
  • Commit-reveal off-chain engine: 3-4 weeks
  • Verification UI: 2-3 weeks
  • 5-8 games: add 4-8 weeks
  • Security audit: mandatory, 4-6 weeks
  • Total: 3-5 months