Skip to main content
A Mines board is fixed before you pick a single tile. The opening transaction commits the SHA-256 hash of a random server seed and captures a Solana slot hash, and the board is a pure function of both. At settlement the program re-derives the entire board on-chain and rejects any settlement that does not match it. This page gives the exact mechanism behind every Mines board: what is committed and when, the precise board derivation, what the program re-checks at settlement, and the honest limits of the scheme. Background: Provably fair overview.

What is committed, and when

A Mines game starts with a single on-chain transaction (mines_start) that does three things at once, before you pick any tile:
  1. Commits the operator’s contribution. The backend generates a random 32-byte server_seed and the transaction stores its SHA-256 hash, the commitment. The seed itself stays hidden until the game ends.
  2. Captures chain entropy. The program reads the most recent slot hash from Solana’s SlotHashes sysvar and stores it in the game.
  3. Freezes the terms. The house edge, the payout cap and the refund timeout are snapshotted into your game; nothing can reprice a board you are already playing.
The board is a pure function of the committed seed, the stored slot hash, your account and your game counter. From this moment the board is fixed: the mines cannot move in response to your picks. During play, tile reveals are served off-chain (that is what makes them instant); at the end, the settlement transaction reveals the seed and the program re-derives the entire board on-chain, rejecting any settlement that does not match it.

How is the Mines board derived?

The 25 tiles are indexed 0 to 24, row by row on the 5×5 grid (index = row × 5 + column). The board is a 25-bit mask: bit t set means tile t hides a mine.
Details that matter when you recompute it:
  • The hash input order is exactly: seed, slot hash, user account address, nonce (8 bytes little-endian), the ASCII tag "mines", then the block counter (8 bytes little-endian, starting at 0).
  • Each 4-byte chunk is read big-endian. A block yields 8 draws at most; the stream refills with the next counter value as needed.
  • The rejection-sampling loop makes every draw exactly uniform: the shuffle has no bias to argue about.

What payout formula does the program enforce?

Each safe reveal multiplies your cash-out by the exact inverse of your survival odds, with the house edge applied once:
The program computes this with exact integer arithmetic and one final floor division (rounding, at most one basis point, is in the house’s favour). At the current 1.5% edge: The expected return is 1 − edge for every combination of mines and reveals. Current values are listed in Fees and limits.

What the program enforces at settlement

The settlement transaction (mines_settle) reveals the server_seed and claims an outcome: a cash-out with a set of revealed tiles, or a bust on a specific tile. The program then checks everything on-chain:
  • sha256(server_seed) must equal the commitment stored at game start; a different seed cannot settle the game.
  • The board is re-derived from scratch with the formula above. Any revealed tile that is actually a mine is rejected; a claimed bust tile that is not a mine is rejected; a bust tile that was also claimed as revealed is rejected.
  • The multiplier is computed on-chain from the snapshotted edge and your actual reveal count, so the payout cannot be misreported.
  • The settlement event publishes the seed, the slot hash, the full mine mask, your revealed tiles and the outcome, permanently.

What is guaranteed, and what is not

Enforced by the program:
  • The board is fixed before your first pick, by the commitment plus the stored slot hash. Mines cannot move mid-game.
  • At settlement, the operator cannot lie about the board: wrong seed, a mine claimed safe, or a fake bust all make the transaction fail.
  • The terms you started with (edge, payout cap, timeout) apply to the end of the game.
  • Your stake can never be locked: if the operator never settles, the cancel becomes callable by anyone after the game’s timeout, refunding your stake. In normal operation you never get there: an abandoned board is cashed out at its current multiplier before the timeout (see Mines), so you keep your winnings rather than just your stake. The permissionless cancel is the guarantee underneath, for the case where the operator is gone.
The honest caveats:
  • The operator knows the board while you play. This is structural, not a flaw of this particular design: reveals are served instantly off-chain, and whoever serves them must know where the mines are. No randomness scheme removes this: even a VRF-generated board would be known to the operator the moment it serves your first reveal. What the commitment guarantees is that this knowledge cannot be used to change the board or to misreport the outcome.
  • Start timing. The board depends on the slot hash captured when your game starts, and the start transaction is submitted by the backend, the same timing consideration as the other games. Knowing a board in advance only helps if your picks are predictable; varying where you click defeats timing-based board selection.
  • Voids. The operator can cancel a game in progress (including, in principle, one you are winning). A cancel refunds the full stake (there is no confiscation path) and always emits a public event, so the void frequency is auditable on-chain by anyone.
  • Each game must use a fresh seed: a revealed seed is public, and reusing it would make the next board publicly derivable. The program rejects back-to-back reuse on-chain, and the backend enforces global uniqueness.

How do you verify a Mines game?

The settlement event (MinesGameSettled) in your game’s final transaction carries server_seed, slothash, user, nonce, mines_count, mines_mask, revealed_mask, bust_tile, multiplier_bps and is_win. To verify:
  1. Check the commitment: sha256(server_seed) must equal the commit_hash published in your game’s start transaction (MinesGameStarted event), proving the board was locked before your first pick.
  2. Re-derive the mine mask with the formula above and compare it with the event’s mines_mask.
  3. Check the outcome against the mask: every bit of revealed_mask must be a safe tile, and a bust tile must be a mine.
  4. Check the multiplier with the payout formula.
See Verify a round for general tips on reading event data from an explorer. For how the game itself is played, see the Mines game guide.