Build Your Own Blockchain dApp on QTUM

A complete, open-source reference implementation of a provably fair dice game. Learn how to build decentralized applications with smart contracts, MetaMask Snaps, and a full-stack TypeScript architecture.

QTUM Testnet MetaMask Snap Provably Fair Open Source

What Is QTUM Dice?

QTUM Dice is a fully functional, provably fair dice betting game running on the QTUM blockchain testnet. Players connect their wallet through MetaMask with the qtum-wallet extension, place bets on dice rolls (over or under a target number from 1-100), and receive automatic on-chain payouts.

More importantly, this project serves as a complete reference implementation for anyone who wants to learn how to build decentralized applications. Every component — from the Solidity smart contract to the React frontend to the Node.js backend — is documented and explained so you can understand how it works and adapt it for your own projects.

Why QTUM?

QTUM combines Bitcoin's UTXO security model with Ethereum's smart contract capabilities. This means you get Solidity-compatible smart contracts running on a battle-tested Bitcoin-derived blockchain. It's an excellent platform for learning dApp development because it supports familiar Ethereum tooling while introducing you to UTXO-based blockchain concepts.

How It Works

The game uses a commit-reveal scheme to ensure provably fair outcomes that neither the house nor the player can manipulate:

1

House Commits

The backend generates a secret seed, stores it, and sends the hash to the frontend.

2

Player Commits

The frontend generates a player seed, hashes it, and calls placeBet() on the smart contract with both hashes plus QTUM.

3

Both Reveal

After on-chain confirmation, the player sends their seed to the backend, which then calls revealAndResolve() with both seeds.

4

On-Chain Settlement

The contract computes keccak256(houseSeed + playerSeed + betId) % 100 + 1, determines the winner, and automatically sends the payout.

Technology Stack

Solidity Smart Contract

On-chain game logic, bet settlement, and payout handling deployed on QTUM testnet.

React + TypeScript Frontend

Vite-powered SPA with TailwindCSS, ethers.js for ABI encoding, and MetaMask Snap integration.

Node.js + Express Backend

Seed management, blockchain event monitoring, reveal coordination, and WebSocket real-time updates.

MetaMask + qtum-wallet

Wallet connection and transaction signing through MetaMask's Snap extensibility framework for QTUM support.

Explore the Guides

Each guide walks you through a different aspect of building this dApp from scratch:

Project Structure

qtum-dice-snap/ ├── contracts/ # Solidity smart contracts │ ├── DiceGame.sol # Main dice betting contract │ └── LuckySpin.sol # Wheel spin contract ├── backend/ # Node.js/Express server │ └── src/ │ ├── index.ts # Express setup, WebSocket, CORS │ ├── game.ts # Seed management, bet tracking │ ├── qtum.ts # QTUM RPC client wrapper │ ├── contractMonitor.ts # Blockchain event polling │ └── routes/ │ └── game.ts # API endpoints ├── frontend/ # React SPA │ └── src/ │ ├── App.tsx # Router and page layout │ ├── components/ │ │ ├── DiceGame.tsx # Main game page │ │ └── BetForm.tsx # Betting form UI │ ├── hooks/ │ │ ├── useQtumWallet.ts # Snap wallet integration │ │ └── useContract.ts # ABI encoding helpers │ └── utils/ │ ├── api.ts # Backend API client │ └── crypto.ts # Seed generation & hashing ├── docker-compose.yml # Local QTUM testnet node └── docs/ # This documentation site

Key Concepts

Provably Fair Gaming

The commit-reveal pattern ensures fairness without requiring trust. Both the house and the player contribute to the randomness. Since both parties commit their seeds before the bet is placed, neither side can manipulate the outcome. The final roll is computed from keccak256(houseSeed + playerSeed + betId) — a deterministic function that anyone can verify after the fact.

QTUM-Specific Details

  • Units: QTUM uses satoshis (1 QTUM = 108 satoshis), not wei like Ethereum
  • Addresses: Base58-encoded with q/Q prefix, not hex. Contracts use hex internally
  • Gas: Maximum gas price is 0.000001 QTUM per unit (use 0.0000004 for transactions)
  • Wallet: Requires MetaMask with npm:qtum-wallet (available in the official MetaMask Snaps directory)
  • RPC: The searchlogs call returns nested arrays and ignores topic filters — filter client-side

Contract Addresses (Testnet)

Contract Address Description
DiceGame 9840131735f93a4118d2452c9cd61f1233550762 Main dice betting game
LuckySpin c3749a3963ca03737b4be0cc2bf2ac0a5ef9b97b Wheel spin game