> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mycryptocasino.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Mines 공정성

> 보드가 언제 커밋되는지, 어떻게 도출되는지, 그리고 정산 시 프로그램이 무엇을 다시 검사하는지 설명합니다.

Mines 보드는 타일을 하나도 고르기 전에 이미 확정됩니다. 게임 시작 트랜잭션은 무작위 서버 시드의 SHA-256 해시를 커밋하고 Solana 슬롯 해시를 기록하며, 보드는 이 둘만으로 결정되는 순수 함수입니다. 정산 시 프로그램은 온체인에서 보드 전체를 다시 도출하고, 이와 일치하지 않는 정산은 모두 거부합니다.

이 페이지에서는 모든 [Mines](/ko/docs/games/mines) 보드의 정확한 작동 방식을 설명합니다. 무엇이 언제 커밋되는지, 보드가 정확히 어떻게 도출되는지, 정산 시 프로그램이 무엇을 다시 검사하는지, 그리고 이 방식의 솔직한 한계까지 다룹니다. 배경 지식: [공정성 검증 개요](/ko/docs/provably-fair/overview).

## 무엇이, 언제 커밋되나요?

Mines 게임은 하나의 온체인 트랜잭션(`mines_start`)으로 시작되며, 이 트랜잭션은 **타일을 고르기 전에** 세 가지 작업을 한꺼번에 수행합니다.

1. **운영자 측 기여분을 커밋합니다.** 백엔드가 무작위 32바이트 `server_seed`를 생성하고, 트랜잭션은 그 SHA-256 해시, 즉 커밋을 저장합니다. 시드 자체는 게임이 끝날 때까지 공개되지 않습니다.
2. **체인 엔트로피를 기록합니다.** 프로그램이 Solana의 `SlotHashes` sysvar에서 가장 최근 슬롯 해시를 읽어 게임에 저장합니다.
3. **조건을 고정합니다.** 하우스 엣지, 지급 상한, 환불 타임아웃이 게임에 스냅샷으로 저장됩니다. 이미 진행 중인 보드의 조건은 그 무엇으로도 바꿀 수 없습니다.

보드는 커밋된 시드, 저장된 슬롯 해시, 사용자 계정, 게임 카운터만으로 결정되는 순수 함수입니다. **이 시점부터 보드는 확정됩니다.** 지뢰는 플레이어의 선택에 따라 움직일 수 없습니다. 플레이 중 타일 공개는 오프체인에서 처리되며(그래서 즉시 열립니다), 게임이 끝나면 정산 트랜잭션이 시드를 공개하고 프로그램이 **온체인에서 보드 전체를 다시 도출**하여 이와 일치하지 않는 정산은 모두 거부합니다.

<h2 id="the-exact-board-derivation">
  Mines 보드는 어떻게 도출되나요?
</h2>

25개 타일은 5×5 격자에서 행 순서대로 0부터 24까지 번호가 매겨집니다(`index = row × 5 + column`). 보드는 25비트 마스크이며, 비트 `t`가 1이면 타일 `t`에 지뢰가 숨어 있다는 뜻입니다.

```text theme={null}
입력값
  server_seed  32바이트   운영자 시드, 게임 시작 시 sha256(server_seed)로 커밋
  slothash     32바이트   시작 트랜잭션 실행 시점의 최신 Solana 슬롯 해시
  user         32바이트   온체인 사용자 계정의 주소
  nonce        8바이트    Mines 게임 카운터, 리틀 엔디언
  mines_count  1..24      선택한 지뢰 수

난수 스트림: SHA-256 블록을 4바이트씩 소비
  block(k)   = sha256( server_seed ‖ slothash ‖ user ‖ nonce ‖ "mines" ‖ k )
               // "mines" = ASCII 5바이트; k = 블록 카운터 0, 1, 2, …, 8바이트 리틀 엔디언
  next_u32() = 현재 블록에서 아직 읽지 않은 다음 4바이트, 빅 엔디언으로 읽음;
               블록을 다 쓰면 block(k+1)로 이동

0..bound 범위의 편향 없는 추출 (거부 샘플링, 모듈로 편향 없음)
  draw(bound):
    zone = 4294967295 − (4294967295 mod bound)
    v < zone이 될 때까지 v = next_u32() 반복
    v mod bound 반환

보드: 부분 Fisher–Yates 셔플
  tiles = [0, 1, …, 24]
  mine_mask = 0
  for i in 0..mines_count:
      j = i + draw(25 − i)
      tiles[i]와 tiles[j] 교환
      mine_mask = mine_mask OR (1 << tiles[i])
```

직접 다시 계산할 때 주의할 점:

* 해시 입력 순서는 정확히 다음과 같습니다: 시드, 슬롯 해시, 사용자 계정 주소, 논스(**8바이트 리틀 엔디언**), ASCII 태그 `"mines"`, 그리고 블록 카운터(**8바이트 리틀 엔디언**, 0부터 시작).
* 각 4바이트 조각은 **빅 엔디언**으로 읽습니다. 한 블록에서 최대 8번 추출할 수 있으며, 필요하면 다음 카운터 값으로 스트림을 채웁니다.
* 거부 샘플링 루프 덕분에 모든 추출은 정확히 균등합니다. 셔플에는 논란의 여지가 있는 편향이 없습니다.

<h2 id="the-payout-formula">
  프로그램은 어떤 지급 공식을 적용하나요?
</h2>

안전한 타일을 하나 열 때마다 캐시아웃 금액에 생존 확률의 정확한 역수가 곱해지며, 하우스 엣지는 한 번만 적용됩니다.

```text theme={null}
배수 = (1 − 하우스 엣지) × ∏(i = 0 … k−1) ( (25 − i) / (25 − M − i) )

M = 지뢰 수, k = 공개한 안전 타일 수
```

프로그램은 이 값을 정확한 정수 연산으로 계산하고 마지막에 한 번만 내림 나눗셈을 합니다(반올림 오차는 최대 1베이시스 포인트이며 하우스에 유리하게 처리됩니다). 현재 하우스 엣지 1.5% 기준:

| 보드 | 배수 |
| - | - |
| 지뢰 3개, 1회 공개 | 1.1193x |
| 지뢰 3개, 2회 공개 | 1.2792x |
| 지뢰 24개, 1회 공개 | 24.625x |
| 지뢰 1개, 올 클리어(24회 공개) | 24.625x |

지뢰 수와 공개 횟수를 어떻게 조합하든 기대 수익률은 `1 − 하우스 엣지`입니다. 현재 값은 [수수료 및 한도](/ko/docs/fees-and-limits)에서 확인할 수 있습니다.

## 정산 시 프로그램이 강제하는 사항

정산 트랜잭션(`mines_settle`)은 `server_seed`를 공개하고 결과를 주장합니다. 공개한 타일 목록과 함께 캐시아웃하거나, 특정 타일에서 지뢰를 밟은 경우입니다. 그러면 프로그램이 온체인에서 모든 것을 검사합니다.

* `sha256(server_seed)`는 게임 시작 시 저장된 커밋과 같아야 합니다. 다른 시드로는 게임을 정산할 수 없습니다.
* 보드는 위 공식으로 **처음부터 다시 도출**됩니다. 공개했다고 주장한 타일이 실제로는 지뢰이면 거부되고, 지뢰를 밟았다고 주장한 타일이 지뢰가 아니면 거부되며, 지뢰를 밟은 타일이 공개한 타일로도 주장되면 역시 거부됩니다.
* 배수는 **스냅샷된** 하우스 엣지와 실제 공개 횟수를 바탕으로 온체인에서 계산되므로, 지급액을 허위로 보고할 수 없습니다.
* 정산 이벤트는 시드, 슬롯 해시, 전체 지뢰 마스크, 공개한 타일, 결과를 영구적으로 공개합니다.

## 보장되는 것과 보장되지 않는 것

**프로그램이 강제하는 사항:**

* 보드는 첫 선택 전에 커밋과 저장된 슬롯 해시로 확정됩니다. 게임 도중 지뢰가 움직일 수 없습니다.
* 정산 시 운영자는 보드에 대해 거짓말을 할 수 없습니다. 잘못된 시드, 지뢰를 안전하다고 주장하는 것, 지뢰를 밟았다는 허위 주장은 모두 트랜잭션 실패로 이어집니다.
* 게임을 시작할 때의 조건(하우스 엣지, 지급 상한, 타임아웃)이 게임이 끝날 때까지 적용됩니다.
* 베팅액은 절대 묶이지 않습니다. 운영자가 끝내 정산하지 않으면 게임 타임아웃 이후 **누구나** 취소를 호출할 수 있고, 베팅액이 환불됩니다. 정상 운영 중에는 이런 상황까지 가지 않습니다. 방치된 보드는 타임아웃 전에 현재 배수로 캐시아웃되므로([Mines](/ko/docs/games/mines) 참고), 베팅액만이 아니라 수익까지 지킬 수 있습니다. 누구나 호출할 수 있는 취소는 운영자가 사라진 경우를 대비한 최후의 보장입니다.

**솔직한 한계:**

* **플레이 중에는 운영자가 보드를 알고 있습니다.** 이는 이 설계만의 결함이 아니라 구조적인 특성입니다. 타일 공개는 오프체인에서 즉시 처리되며, 이를 처리하는 쪽은 지뢰의 위치를 알고 있어야 합니다. 어떤 난수 방식도 이를 없앨 수 없습니다. VRF로 생성한 보드라도 운영자는 첫 공개를 처리하는 순간 보드를 알게 됩니다. 커밋이 보장하는 것은 이 정보를 이용해 보드를 *변경*하거나 결과를 *허위로 보고*할 수 없다는 점입니다.
* **시작 타이밍.** 보드는 게임 시작 시 기록되는 슬롯 해시에 따라 달라지며, 시작 트랜잭션은 백엔드가 제출합니다. 다른 게임과 동일한 타이밍 문제입니다. 보드를 미리 안다는 것은 플레이어의 선택을 예측할 수 있을 때만 의미가 있습니다. 클릭하는 위치를 바꾸면 타이밍을 이용한 보드 선택을 무력화할 수 있습니다.
* **무효 처리.** 운영자는 진행 중인 게임(원칙적으로는 이기고 있는 게임도 포함)을 취소할 수 있습니다. 취소 시 **베팅액 전액이 환불**되며(몰수 경로는 없습니다), 항상 공개 이벤트가 발생하므로 누구나 온체인에서 무효 처리 빈도를 감사할 수 있습니다.
* 게임마다 새 시드를 사용해야 합니다. 공개된 시드는 누구나 볼 수 있으므로, 이를 재사용하면 다음 보드를 누구나 도출할 수 있게 됩니다. 프로그램은 연속 재사용을 온체인에서 거부하고, 백엔드는 전역 고유성을 보장합니다.

<h2 id="verify-a-game">
  Mines 게임은 어떻게 검증하나요?
</h2>

게임의 마지막 트랜잭션에 있는 정산 이벤트(`MinesGameSettled`)에는 `server_seed`, `slothash`, `user`, `nonce`, `mines_count`, `mines_mask`, `revealed_mask`, `bust_tile`, `multiplier_bps`, `is_win`이 담겨 있습니다. 검증 방법:

1. 커밋 확인: `sha256(server_seed)`가 게임 시작 트랜잭션(`MinesGameStarted` 이벤트)에 공개된 `commit_hash`와 같아야 합니다. 이로써 첫 선택 전에 보드가 고정되었음이 증명됩니다.
2. 위 공식으로 지뢰 마스크를 다시 도출하고 이벤트의 `mines_mask`와 비교합니다.
3. 마스크와 결과를 대조합니다. `revealed_mask`의 모든 비트는 안전한 타일이어야 하고, 지뢰를 밟은 타일은 지뢰여야 합니다.
4. 지급 공식으로 배수를 확인합니다.

익스플로러에서 이벤트 데이터를 읽는 일반적인 방법은 [라운드 검증](/ko/docs/provably-fair/verify-a-round)을 참고하세요.

게임 플레이 방법은 [Mines 게임 가이드](/ko/docs/games/mines)를 참고하세요.
