무엇이, 언제 커밋되나요?
Mines 게임은 하나의 온체인 트랜잭션(mines_start)으로 시작되며, 이 트랜잭션은 타일을 고르기 전에 세 가지 작업을 한꺼번에 수행합니다.
- 운영자 측 기여분을 커밋합니다. 백엔드가 무작위 32바이트
server_seed를 생성하고, 트랜잭션은 그 SHA-256 해시, 즉 커밋을 저장합니다. 시드 자체는 게임이 끝날 때까지 공개되지 않습니다. - 체인 엔트로피를 기록합니다. 프로그램이 Solana의
SlotHashessysvar에서 가장 최근 슬롯 해시를 읽어 게임에 저장합니다. - 조건을 고정합니다. 하우스 엣지, 지급 상한, 환불 타임아웃이 게임에 스냅샷으로 저장됩니다. 이미 진행 중인 보드의 조건은 그 무엇으로도 바꿀 수 없습니다.
Mines 보드는 어떻게 도출되나요?
25개 타일은 5×5 격자에서 행 순서대로 0부터 24까지 번호가 매겨집니다(index = row × 5 + column). 보드는 25비트 마스크이며, 비트 t가 1이면 타일 t에 지뢰가 숨어 있다는 뜻입니다.
- 해시 입력 순서는 정확히 다음과 같습니다: 시드, 슬롯 해시, 사용자 계정 주소, 논스(8바이트 리틀 엔디언), ASCII 태그
"mines", 그리고 블록 카운터(8바이트 리틀 엔디언, 0부터 시작). - 각 4바이트 조각은 빅 엔디언으로 읽습니다. 한 블록에서 최대 8번 추출할 수 있으며, 필요하면 다음 카운터 값으로 스트림을 채웁니다.
- 거부 샘플링 루프 덕분에 모든 추출은 정확히 균등합니다. 셔플에는 논란의 여지가 있는 편향이 없습니다.
프로그램은 어떤 지급 공식을 적용하나요?
안전한 타일을 하나 열 때마다 캐시아웃 금액에 생존 확률의 정확한 역수가 곱해지며, 하우스 엣지는 한 번만 적용됩니다.
지뢰 수와 공개 횟수를 어떻게 조합하든 기대 수익률은
1 − 하우스 엣지입니다. 현재 값은 수수료 및 한도에서 확인할 수 있습니다.
정산 시 프로그램이 강제하는 사항
정산 트랜잭션(mines_settle)은 server_seed를 공개하고 결과를 주장합니다. 공개한 타일 목록과 함께 캐시아웃하거나, 특정 타일에서 지뢰를 밟은 경우입니다. 그러면 프로그램이 온체인에서 모든 것을 검사합니다.
sha256(server_seed)는 게임 시작 시 저장된 커밋과 같아야 합니다. 다른 시드로는 게임을 정산할 수 없습니다.- 보드는 위 공식으로 처음부터 다시 도출됩니다. 공개했다고 주장한 타일이 실제로는 지뢰이면 거부되고, 지뢰를 밟았다고 주장한 타일이 지뢰가 아니면 거부되며, 지뢰를 밟은 타일이 공개한 타일로도 주장되면 역시 거부됩니다.
- 배수는 스냅샷된 하우스 엣지와 실제 공개 횟수를 바탕으로 온체인에서 계산되므로, 지급액을 허위로 보고할 수 없습니다.
- 정산 이벤트는 시드, 슬롯 해시, 전체 지뢰 마스크, 공개한 타일, 결과를 영구적으로 공개합니다.
보장되는 것과 보장되지 않는 것
프로그램이 강제하는 사항:- 보드는 첫 선택 전에 커밋과 저장된 슬롯 해시로 확정됩니다. 게임 도중 지뢰가 움직일 수 없습니다.
- 정산 시 운영자는 보드에 대해 거짓말을 할 수 없습니다. 잘못된 시드, 지뢰를 안전하다고 주장하는 것, 지뢰를 밟았다는 허위 주장은 모두 트랜잭션 실패로 이어집니다.
- 게임을 시작할 때의 조건(하우스 엣지, 지급 상한, 타임아웃)이 게임이 끝날 때까지 적용됩니다.
- 베팅액은 절대 묶이지 않습니다. 운영자가 끝내 정산하지 않으면 게임 타임아웃 이후 누구나 취소를 호출할 수 있고, 베팅액이 환불됩니다. 정상 운영 중에는 이런 상황까지 가지 않습니다. 방치된 보드는 타임아웃 전에 현재 배수로 캐시아웃되므로(Mines 참고), 베팅액만이 아니라 수익까지 지킬 수 있습니다. 누구나 호출할 수 있는 취소는 운영자가 사라진 경우를 대비한 최후의 보장입니다.
- 플레이 중에는 운영자가 보드를 알고 있습니다. 이는 이 설계만의 결함이 아니라 구조적인 특성입니다. 타일 공개는 오프체인에서 즉시 처리되며, 이를 처리하는 쪽은 지뢰의 위치를 알고 있어야 합니다. 어떤 난수 방식도 이를 없앨 수 없습니다. VRF로 생성한 보드라도 운영자는 첫 공개를 처리하는 순간 보드를 알게 됩니다. 커밋이 보장하는 것은 이 정보를 이용해 보드를 변경하거나 결과를 허위로 보고할 수 없다는 점입니다.
- 시작 타이밍. 보드는 게임 시작 시 기록되는 슬롯 해시에 따라 달라지며, 시작 트랜잭션은 백엔드가 제출합니다. 다른 게임과 동일한 타이밍 문제입니다. 보드를 미리 안다는 것은 플레이어의 선택을 예측할 수 있을 때만 의미가 있습니다. 클릭하는 위치를 바꾸면 타이밍을 이용한 보드 선택을 무력화할 수 있습니다.
- 무효 처리. 운영자는 진행 중인 게임(원칙적으로는 이기고 있는 게임도 포함)을 취소할 수 있습니다. 취소 시 베팅액 전액이 환불되며(몰수 경로는 없습니다), 항상 공개 이벤트가 발생하므로 누구나 온체인에서 무효 처리 빈도를 감사할 수 있습니다.
- 게임마다 새 시드를 사용해야 합니다. 공개된 시드는 누구나 볼 수 있으므로, 이를 재사용하면 다음 보드를 누구나 도출할 수 있게 됩니다. 프로그램은 연속 재사용을 온체인에서 거부하고, 백엔드는 전역 고유성을 보장합니다.
Mines 게임은 어떻게 검증하나요?
게임의 마지막 트랜잭션에 있는 정산 이벤트(MinesGameSettled)에는 server_seed, slothash, user, nonce, mines_count, mines_mask, revealed_mask, bust_tile, multiplier_bps, is_win이 담겨 있습니다. 검증 방법:
- 커밋 확인:
sha256(server_seed)가 게임 시작 트랜잭션(MinesGameStarted이벤트)에 공개된commit_hash와 같아야 합니다. 이로써 첫 선택 전에 보드가 고정되었음이 증명됩니다. - 위 공식으로 지뢰 마스크를 다시 도출하고 이벤트의
mines_mask와 비교합니다. - 마스크와 결과를 대조합니다.
revealed_mask의 모든 비트는 안전한 타일이어야 하고, 지뢰를 밟은 타일은 지뢰여야 합니다. - 지급 공식으로 배수를 확인합니다.