99% RTP LAB
Cryptographic Verification Lab · HMAC-SHA256

Stake原创游戏公平验证方法:种子哈希解码与开奖结果还原步骤

传统电子游戏依赖黑盒随机数生成器(RNG),玩家无法得知后台是否根据注码大小动态干预胜率。Stake Originals全系游戏采用可验证公平(Provably Fair)加密承诺机制,通过 HMAC-SHA256 算法将平台预设种子与玩家自定义参数绑定,使每一局掉球路径、雷区分布与骰子点数均可通过开源数学公式100%逆向复盘。

核心生成公式 (Byte Generator) 零篡改承诺
Result_Bytes = HMAC_SHA256(Key = Server_Seed, Message = Client_Seed : Nonce : Cursor)
加密哈希标准
256-Bit
单向不可逆摘要
单次哈希字节流
32 Bytes
每4字节转化1个浮点数
理论返还率基准
99.00% RTP
1% 恒定数学庄家优势
cryptographic_commitment_flow.svg
VERIFIED
Stake原创游戏Provably Fair加密哈希验证架构示意图
1. 下注前锁定:服务器种子哈希 (SHA-256)
9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
2. 玩家注入变量:Client Seed + Nonce
stake_lab_2025 : 1042 : 0
3. 轮换后公开:明文还原结果
Float: 0.49281042 -> Dice: 49.77 MATCH 100%
SECTION 01 // CRYPTOGRAPHIC PARAMETERS

拆解Server Seed、Client Seed与Nonce的协同生成逻辑

在可验证公平体系中,没有任何一方能够单独决定开奖结果。系统将随机性拆分为四个相互制约的数学输入变量,分别由平台服务器与玩家客户端掌握控制权。

HMAC 密钥 (Key)

1. 服务器种子 (Server Seed)

由平台服务器生成的64位十六进制高熵随机字符串。在种子处于活跃状态时,玩家只能看到它经过 SHA-256 加密后的哈希值(Server Seed Hash)。

  • 防作弊作用:先给哈希后下注,相当于将底牌锁进透明保险箱。
  • 生命周期:直到玩家主动点击“更换种子”后才公开明文。
示例明文: a8f5f167f44f4964e6c998dee827110c...
玩家控制变量

2. 客户端种子 (Client Seed)

完全由玩家端决定的任意字符串(支持字母、数字及符号)。由于服务器在生成初始Server Seed时无法预知玩家将输入什么Client Seed,因此无法预先筛选有利平台的结果序列。

  • 最佳实践:切勿长期使用默认字符串,每次轮换时手动修改。
  • 参与位置:作为HMAC消息体(Message)的第一段前缀参数。
示例输入: MyCustomLuckySeed_2025
单调递增计数器

3. 随机数局号 (Nonce)

代表在当前这组“服务器种子 + 客户端种子”配对下进行的第几局游戏。从 0(或1)开始,每完成一次有效投注,Nonce严格自动加1。

  • 雪崩效应:即便前两项种子不变,Nonce从10变为11也会产生截然不同的哈希值。
  • 重置条件:一旦更换种子配对,Nonce立即归零重新计数。
序列递增: 0 → 1 → 2 → 3 ... → N
多事件字节扩展

4. 字节游标 (Cursor / Round)

单次HMAC-SHA256仅生成32字节(最多转化8个浮点数)。当单局游戏需要超过8个随机判定时,系统自动递增Cursor(0, 1, 2...)拼接更多哈希块。

  • Dice / Limbo:仅需1个随机数,Cursor恒定为 0。
  • Plinko / Mines:16行掉球需16个随机数(Cursor 0~1);扫雷24次洗牌需Cursor 0~2。
消息格式: ClientSeed:Nonce:Cursor

加密参数权限与全周期可见性对照表

审计标准:SHA-256 & HMAC-SHA256
参数名称 生成与控制方 游戏进行中(活跃期) 更换种子后(核验期) 数学验证方法
Server Seed (明文) 平台加密随机数发生器 严格隐藏 (Hidden) 公开64位十六进制明文 对其执行 SHA256() 比对初始哈希
Server Seed (Hash) 由明文通过SHA-256派生 公开展示可复制 保留在历史投注记录中备查 等于 SHA256(Unhashed_Seed)
Client Seed 玩家浏览器生成 / 手动输入 完全公开且支持预设下一局 完整记录于每笔注单详情 直接作为 HMAC Message 前缀
Nonce (局数编号) 系统按投注顺序自增 实时显示当前累计局数 每笔注单绑定唯一固定Nonce 检查历史序列是否连续无跳号
SECTION 02 // SEED ROTATION PROTOCOL

更换种子(Rotate Seed)与解哈希核验标准流程

许多刚接触Stake原创游戏的玩家会疑惑:为什么点击某局刚结束的注单,系统提示“需要更换种子才能验证”?这是因为只要当前服务器种子仍在服役,公开其明文就会导致后续所有未发生的赌局结果被提前推算。

双重锁定核验法则(必做两步)

完整的公平验证并非只看点数是否对得上,而是包含两个缺一不可的密码学校验环节:

校验一:验证承诺未被篡改 (Commitment Check)

将揭晓的 Server Seed (Unhashed) 放入任意SHA-256工具计算,所得结果必须与下注前展示的 Server Seed (Hashed) 逐字吻合。

校验二:验证开奖结果计算准确 (Outcome Check)

使用该明文种子、Client Seed与对应局数的Nonce运行HMAC-SHA256,还原出的游戏点数/雷区必须与实际开奖界面一致。

Stake公平性设置面板更换客户端种子与解密服务器种子操作界面
Fairness Modal -> Rotate Seed Pair SHA-256 Unhashing

四步完成种子轮换与明文提取 预计耗时: < 30秒

01

记录当前活跃服务器种子哈希 (Active Hash)

游戏开始前 / 轮换前

点击游戏界面右下角的“公平性(Fairness)”按钮,切换到“种子(Seeds)”标签页。复制并保存“活跃服务器种子(哈希)”框中的64位字符串,系统同时还提前展示了“下一个服务器种子(哈希)”供后续轮换使用。

02

输入自定义新客户端种子并执行轮换

注意:需先结束未完成局

在“新的客户端种子(New Client Seed)”输入框中填写您自己设定的随机字符(如 StakeCN_Audit_889),点击绿色的“更改(Change)”按钮。注意:如果当前有正在进行中的Mines扫雷或Hilo牌局,必须先结算才能更换种子。

03

从历史注单提取已解密的明文种子 (Unhashed Seed)

明文已解锁

打开“我的投注(My Bets)”,点击您刚才想要核查的那一局游戏记录。此时原本显示“需要更换种子以揭晓”的栏位,已经变为可复制的64位明文服务器种子(未哈希),同时列出了当时的Client Seed和准确的Nonce序号。

04

比对SHA-256摘要并代入验证计算器

闭环验证完成

点击注单底部的“验证(Verify)”按钮,或将这三项参数复制到下方的独立验证模拟器中。首先确认明文的SHA-256哈希值与第01步保存的Hash一致,随后查看字节转换出的最终开奖数字。

SECTION 03 // BYTE-TO-FLOAT CONVERSION WALKTHROUGH

开奖结果是如何算出来的?从十六进制哈希到浮点数的数学推导

拿到HMAC-SHA256输出的64位十六进制字符串后,系统并非直接取末尾数字,而是遵循严格的4字节分组加权除法(Byte-to-Float Conversion),将其映射为 [0, 1) 区间内的高精度均匀分布浮点数。

STAGE 01 // HMAC OUTPUT

生成64位十六进制摘要

计算 HMAC_SHA256(ServerSeed, "ClientSeed:Nonce:0"),输出32个字节(64个Hex字符)。

7c029b60f9e2441b8a...
截取前8个Hex字符(即前4个Bytes)
STAGE 02 // HEX TO DECIMAL

拆分为4个十进制字节

每2个十六进制字符构成1个字节(Byte),将其分别转换为0~255之间的十进制整数:

Byte[0]: 0x7c = 124
Byte[1]: 0x02 = 2
Byte[2]: 0x9b = 155
Byte[3]: 0x60 = 96
STAGE 03 // NORMALIZATION

256幂次加权求和

将4个字节分别除以 256^1, 256^2, 256^3, 256^4 后相加,得到基础浮点数 Float:

124 / 256¹ = 0.4843750000
+ 2 / 256² = 0.0000305176
+ 155 / 256³ = 0.0000092387
+ 96 / 256⁴ = 0.0000000224
= 0.4844147787
STAGE 04 // GAME MAPPING

映射为具体游戏结果

根据不同游戏的规则公式,将该浮点数乘以事件总数并向下取整(Floor):

Dice: ⌊0.48441477 × 10001⌋ / 100 = 48.44
Plinko方向: ⌊0.4844 × 2⌋ = 0 (向左)
Mines首雷: ⌊0.4844 × 25⌋ = 索引 12

Stake Originals 种子哈希解码与结果还原模拟器

实时演示 Server Seed + Client Seed + Nonce → 4字节拆解 → 游戏开奖结果

对应 SHA-256 承诺哈希 (下注前展示值) 哈希锁定匹配
1 颗雷 24 颗雷
当前 HMAC 消息拼接字符串 (Cursor 0):
HMAC-SHA256 十六进制输出流:
首组4字节转浮点数过程 (Bytes 0~3)
DICE 最终还原点数 (0.00 ~ 100.00)
计算式:
总可能结果数: 10,001 个
大于 50.50 判定:
PLINKO 16行钉子左右偏移路径还原 (L=0, R=1)

说明:每一行消耗1组浮点数,若 Math.floor(Float × 2) === 1 则小球向右(R)弹跳,最终向右的总次数即为底部第几个赔率格(从左0至右16编号)。

MINES 5×5 雷区 Fisher-Yates 洗牌还原

系统初始化包含0~24号格子的数组,每一步用 Math.floor(Float × 剩余格子数) 抽取地雷坐标并移出候选池,确保地雷绝不重叠。

提示:修改上方任意种子字符或Nonce,观察雪崩效应对结果的即时改变。 算法标准:RFC 2104 HMAC-SHA256
SECTION 04 // GAME-SPECIFIC DECODING ALGORITHMS

三大主力原创游戏哈希解码规则与实战还原案例

所有Stake原创游戏共用同一套底层字节生成器(Byte Generator),但在最后一步将 [0, 1) 浮点数转化为游戏画面时,各自采用专属的数学映射模型。

Plinko 掉球路径解码 消耗字节: 64 Bytes (16行)

二项分布左右偏移累加

Plinko的钉子金字塔共有8至16行可选。小球每下落一层遇到钉子,只存在向左(0)或向右(1)两种等概率分支(各50%)。

16行高风险模式解码公式:
Direction[i] = Math.floor(Float[i] × 2)
Bucket_Index = ∑ Direction[0...15]
• 若16次判定全部为0(全左),落入最左侧第0槽(1000x)
• 若8次为0、8次为1,落入正中央第8槽(0.2x)
为什么Cursor需要用到 0 和 1?

因为单次哈希(Cursor=0)产生的32字节只能提供前8层钉子的方向;第9层至第16层钉子的方向必须由 ClientSeed:Nonce:1 生成的第2组32字节提供。

Mines 扫雷坐标解码 算法: Fisher-Yates 洗牌

无放回动态缩减抽样

5×5网格共有25个位置(编号0至24,左上角为0,右下角为24)。为了防止两个浮点数算到同一个格子上,系统采用经典的Fisher-Yates不放回抽样算法。

前3颗地雷抽取示例:
第1雷索引 = ⌊Float[0] × 25⌋ → 移除该格
第2雷索引 = ⌊Float[1] × 24⌋ → 在剩余24格中取
第3雷索引 = ⌊Float[2] × 23⌋ → 在剩余23格中取
核心防作弊结论:开局即定死全图

无论您在游戏过程中点击哪个格子,25个格子的排序在点击“开始游戏”那一刻已由当期Nonce唯一锁定。不存在“点哪格哪格变雷”的后台动态追踪。

Dice 与 Limbo 解码 消耗字节: 仅需前 4 Bytes

单浮点数线性与反比例映射

Dice和Limbo每局只需1个随机结果,因此仅截取 Cursor = 0 哈希流的前8个十六进制字符即可完成验证,核验速度最快。

Dice & Limbo 核心转换公式:
Dice: Roll = ⌊Float × 10001⌋ / 100
Limbo: Crash = ⌊(16777216 / (⌊Float × 16777216⌋ + 1)) × 0.99 × 100⌋ / 100
0.99 系数是如何体现 99% RTP 的?

在Limbo公式中,原始反比例乘数直接乘以了 0.99(即扣除1%庄家优势);而在Dice中,50%胜率对应的赔率为 99 / 50 = 1.98x。

verify_stake_originals.js — 本地独立核验脚本(零依赖 Node.js 原生 Crypto 库)
可在任意电脑终端离线运行
const crypto = require('crypto');

function verifyDiceAndBytes(serverSeed, clientSeed, nonce, cursor = 0) {
  // 1. 验证下注前的 SHA-256 承诺哈希是否吻合
  const commitmentHash = crypto.createHash('sha256').update(serverSeed).digest('hex');
  
  // 2. 生成 HMAC-SHA256 32字节输出流
  const message = `${clientSeed}:${nonce}:${cursor}`;
  const hmac = crypto.createHmac('sha256', serverSeed).update(message).digest();
  
  // 3. 取前4个字节转换为 [0, 1) 区间高精度浮点数
  let floatVal = 0;
  for (let i = 0; i < 4; i++) {
    floatVal += hmac[i] / Math.pow(256, i + 1);
  }
  
  // 4. 映射为 Dice 0.00 ~ 100.00 开奖结果
  const diceRoll = Math.floor(floatVal * 10001) / 100;
  return { commitmentHash, message, floatVal, diceRoll };
}

console.log(verifyDiceAndBytes(
  'a8f5f167f44f4964e6c998dee827110c9082b47c341d91a032b8d12a7e6c4501',
  'StakeCN_Audit_2025',
  1042
));
SECTION 05 // VERIFICATION FAQ

公平验证与种子机制常见疑问解答

针对玩家在实际核验种子、使用自动投注脚本及评估连黑波动时最常遇到的密码学与概率疑问,提供客观的技术解答。

核验安全准则提示

可验证公平(Provably Fair)保证了每一局开奖结果不受人为操控,但并不能消除高波动策略下的自然方差(Variance)。请将公平验证与科学的止损倍投策略结合使用。

不能。在您开始第一局游戏之前,服务器种子(Server Seed)已经生成并通过SHA-256单向加密展示了其哈希值(Hash)。由于SHA-256具有抗碰撞特性,只要明文发生哪怕一个字符的改变,生成的哈希值都会完全不同。因此,只要您在轮换种子后对比明文的SHA-256值与事先记录的Hash值一致,就证明平台在整个种子周期内从未修改过预设序列。
当前正在使用的服务器种子处于加密隐藏状态(Hashed),目的是防止玩家或外部程序逆向推算出未来几局的开奖结果。只有当您点击更换种子时,旧的服务器种子才会停止使用并公开明文(Unhashed Server Seed)。拿到这段明文后,您才能结合当时的客户端种子与Nonce局数,完整还原并核验此前每一局的真实性。
系统默认会在您的浏览器端生成一段随机字符串作为Client Seed。为了达到最高级别的安全与心理确信,建议在每次更换种子时,手动输入一段只有您自己知道的自定义文本(例如特定日期、短语或随机敲击的字符)。这样服务器在生成初始哈希时,完全无法预知您将注入什么客户端变量,彻底杜绝了“预计算特定种子”的可能性。
一次标准的HMAC-SHA256运算固定输出32字节(Bytes)的数据,而系统每生成1个0到1之间的随机浮点数需要消耗4个字节。这意味着单次哈希最多只能提供8个独立随机事件(32 ÷ 4 = 8)。Dice每局只需1个随机数,因此Cursor恒为0;但16行Plinko需要16次左右偏移判定,Mines则需要排列24个格子的位置,单次哈希不够用,必须通过递增Cursor(0, 1, 2...)来扩展生成足够多的字节流。
不会。每一局的HMAC-SHA256哈希运算都是数学上完全独立的随机事件,99%的理论返还率是由赔率乘数与命中区间的数学公式决定的,而非由种子周期控制。更换种子只是开启了一组全新的随机序列,既不会“清除坏运气”,也不会改变下一局命中高倍率的客观数学概率。