为什么随机数是 WarmUp 的根基
在概率游戏里,随机数就是结果,结果就是钱。谁能预测或左右随机数,谁就能稳定地从另一方拿走资金。
对 WarmUp 来说,随机数可不可信,决定了三件事:
- 玩家的资金安全:结果一旦可以被操纵,再合理的赔率、再充足的资金池也没有意义。
- 平台的信用:平台既是庄家,又是运营方。它需要证明的不是“我保证不作弊”,而是“我想作弊也做不到,做了也会被发现”。
- 链的意义:WarmUp 链存在的理由,是让每一笔下注、每一次开奖都公开可查。如果随机数本身不可信,链上记录的只是一份公开的、被操纵过的账本。
常见做法的局限
| 做法 | 局限 |
|---|---|
| 服务器生成随机数(传统在线游戏) | 结果在黑箱里产生,玩家只能选择相信运营方 |
| 用区块哈希、区块时间戳当随机数 | 出块者能提前看到,甚至挑选。现阶段 WarmUp 链由平台运行的验证节点出块,这类随机源对平台完全透明,我们不使用 |
| 只由平台事先承诺种子 | 平台改不了种子,但可以挑选接受哪些下注,把自己会输的注单拒之门外 |
| 第三方随机数预言机 | 要等外部回调,慢,要付费,而且依赖外部链的基础设施 |
设计目标与威胁模型
我们按最坏的情况设计:不假设平台是诚实的,而是假设它会尽一切可能为自己谋利。
不可预测下注截止之前,任何一方(包括平台)都无法知道结果
不可操纵任何一方都无法在知道结果之后改变它,也不能靠拒绝、拖延、作废来换一个结果
可验证任何人只凭链上公开数据和自己的计算,就能复算每一局
一定能结束任何一方不配合,游戏都能结束:要么按规则兜底,要么判不配合的一方输
快单人游戏点击后约 2 秒出结果;多人局截止后数秒内开奖
假设平台本身就是对手
| 参与方 | 它能做什么 | 设计上如何应对 |
|---|---|---|
| 平台(运营方,也是庄家) | 运行验证节点、转发玩家的交易、掌握自己的种子 | 种子事先上链承诺;玩家的随机数在下注前对平台保密;平台不开奖就判玩家赢;合约里没有作废入口;平台签过的收据可以在链上索赔;拒收行为可以被玩家当场发现 |
| 玩家 | 修改自己的浏览器代码、故意不配合 | 玩家揭示之前看不到平台的种子;不揭示就由 drand 兜底,得不到任何好处 |
| 验证节点的时钟 | 链上时间由验证节点给出 | 独立的观察节点比对出块时间(建设中) |
| drand 网络 | 由多家独立机构联合生成,任何单一机构都无法控制 | 签名在链上用公钥验证,无法伪造;只用于兜底和多人局 |
三条原则
- 多方贡献:结果由互不信任的多方共同决定,其中一方是玩家自己的浏览器。
- 事先承诺,事后公开:每一份随机数在被使用之前就已经固定下来,使用时公开,并在链上校验。
- 不配合就判负,不留作废通道:任何一方停止配合,都换不来一个对自己更有利的结果。
三方各出一份随机数
以抛硬币为例(单人、秒级出结果):
| 来源 | 什么时候确定 | 谁能提前知道 | 作用 |
|---|---|---|---|
| 你的浏览器 | 下注时在本机用系统密码学随机数生成 32 字节“秘密”,只把它的哈希写上链 | 只有你 | 平台在你下注时算不出结果,没法挑注单 |
| 平台 | 开局前就把一批种子的哈希写上链,下注时按顺序自动分配给这一注 | 只有平台,开奖时公开 | 你也算不出结果;平台事后换不了种子 |
| drand(只兜底) | 由全球多家机构联合生成,每 3 秒一轮,签名在链上可验证 | 谁都不能提前知道 | 你的秘密没能在 10 秒内揭示时,用它代替 |
结果 = keccak256(平台种子, 你的秘密, 注单编号) 的最后一位
1 = 正面,0 = 反面 · 猜中拿回 1.98 倍
1 = 正面,0 = 反面 · 猜中拿回 1.98 倍
公式写在合约里,由合约计算,任何一方都改不了。
一注是怎么跑的
正常情况下约 2 秒出结果。关键是两步:平台必须先给你签一张收据,你的浏览器每局都会独立重算。
- 1平台 → 合约预先提交一批种子的哈希
- 2你的浏览器在本机生成秘密 s
- 3浏览器 → 合约下注:金额、正反、hash(s)
- 4浏览器 → 平台交出秘密 s
- 5平台 → 浏览器签名收据:注单、hash(s)、收到时间
- 6平台 → 合约公开种子和 s;合约核对两个哈希、算出结果,赢了当场付款(约 2 秒)
- 7你的浏览器独立重算:本该赢却被扣 → 凭收据索赔
- 出问题时
- !10 秒没揭示 → 用 drand 开奖
- !10 分钟不开奖 → 任何人调用
forfeit,判你赢
为什么平台改不了结果
- 种子先于你的下注上链:下注时自动分配下一个未用的种子。开奖时,合约会核对种子的哈希和当初的承诺是否一致,不一致就拒绝。
- 平台看不到你的秘密:下注时链上只有哈希,平台没法只接会输的注单。
- 结果由合约计算:种子和秘密都要与各自的哈希对得上,公式固定。
- 不开奖就判你赢:平台 10 分钟内不开奖,任何人都能调用
forfeit,直接按你赢结算。 - 赔付一定付得出:你下注的同时,资金池里应赔的部分就被锁住了。
你的浏览器:本地的可信终端
传统的在线游戏,结果在服务器里算,你只能选择相信它。在 WarmUp,你的浏览器是一名独立的裁判:它不听平台的,只听你自己和链上的合约。
- 随机数自己生成:秘密由你的浏览器在本机生成,下注之前平台拿不到。每一局都有你自己的一份随机数参与。
- 每次交出秘密,都拿一张签名收据:平台用密钥签一张“第几注、哪个秘密、几点收到”的收据。浏览器当场到链上验证签名,有效才算数,并把收据保存下来。
- 每局结束都重算一遍:平台开奖时必须公开种子。浏览器用这个种子和你自己的秘密,算出“本该是什么结果”,判断平台有没有扣下你的揭示。
- 游戏页面跑在沙箱里:只能操作本游戏,碰不到你的余额和提现。
所以你不需要相信平台,只需要相信两样东西:你自己的浏览器,和任何人都能读的合约代码。
站在玩家视角:怎么发现、怎么举证
| 平台可能的小动作 | 你会看到什么 | 你能做什么 |
|---|---|---|
| 收了你的秘密、签了收据,却没上链,拖到 drand 开奖,而你本该赢 | 页面标红“本该赢:平台扣下了你的揭示”,并出现“凭收据索赔”按钮 | 点按钮。合约核对收据签名、收到时间和你的秘密,确认你本该赢,就从资金池补发奖金(每注一次)。平台自己签的收据就是它的“认罪书” |
| 收了你的秘密却不签收据,拖到 drand 开奖,而你本该赢 | 页面标红“平台未签收你的揭示,而你本该赢”,并累计本次打开页面以来的次数 | 记下注单编号和开奖交易。偶尔一次可能是网络问题,反复出现就是作弊信号,可以公开举报。这种情况目前只能发现,不能在链上强制赔付(见诚实的边界) |
| 迟迟不开奖 | 注单一直停在“等待开奖” | 10 分钟后点“超时判赢”,按你赢结算 |
| 想换一个种子 | 不会发生 | 合约会拒绝哈希不符的种子,不用你做任何事 |
| 调慢验证节点的时钟(影响 drand 兜底和多人局) | 观察节点会报警(正在建设) | 查看公开的观察节点面板 |
不依赖页面,自己核对一注
在区块浏览器里打开抛硬币合约 0xE7F619E13AB088Ed5565F5870A59917d4DAdFA37:
- 找到你的
BetPlaced事件,记下注单编号、种子编号(commitIndex)和你的秘密哈希。 - 确认对应的种子哈希是在你下注之前由
HouseCommitted事件写上链的。 - 在
BetSettled事件里取出公开的平台种子和开奖方式。正常开奖时,keccak256(种子, 你的秘密, 注单编号) 的最后一位就是结果。 - 如果是 drand 兜底,用的是合约
drandRoundOf(注单编号)给出的那一轮。这一轮的公开签名可以在 drand 官方接口查到,和链上用到的一致。
多人局(如 Ladykiller)
多人局也由每位玩家的浏览器出随机数,截止后 1~2 秒出结果(Ladykiller v5)。和抛硬币相比,多人局多一个风险:平台可能用自己控制的账户混进一局,看到别人的秘密后选择不揭示。下面的规则专门处理这一点。
- 庄家种子提前锁定。庄家生成一条哈希链,把链尾写进合约。第 k 局用哪个种子,链建好时就定了(换链只对还没开始的局生效);每公开一个种子,合约都核对它的哈希等于上一个。
- 下注时只交指纹。浏览器生成秘密,只把它的哈希随下注提交。
- 截止后一起揭示。截止后,合约先在链上关闭下注;浏览器亲眼看到“已关闭”的区块后才发出秘密(之前发,平台就能拿着大家的秘密补一注),1 秒内送达,平台每收到一个都要签收据,收据上写明收到的时刻。以收据时刻为准,1 秒内收到的都必须计入。
- 一笔交易开奖。收齐的秘密和本局庄家种子一起提交,合约算出 结果 = keccak256(庄家种子, 所有秘密),同时完成结算。
| 情况 | 结果怎么定 | 截止后多久 |
|---|---|---|
| 所有人都揭示(正常情况) | 庄家种子 + 所有秘密 | 1~2 秒 |
| 有玩家没揭示 | 改用开奖交易上链 1 秒后才公布的那一轮 drand。缺席者的下注冻结,7 天内补交秘密才退回本金,否则本金分给本局其他玩家 | 约 3~4 秒 |
| 庄家没按时公开种子 | 本局锁定的全部准备金按下注额分给玩家。这笔钱不少于任何一种结果下庄家要赔的总额,所以扣着种子对庄家永远不划算 | 超时(10 分钟)后 |
| drand 暂时停摆 | 等它恢复。只会变慢,不会出错 | — |
- 缺席为什么换成 drand,而不是只算到场的人。平台手里有收到的全部秘密。如果规则是“缺席就不算”,平台让自己的账户缺席与否,两种结果它都能提前算出,等于二选一。换成窗口关闭后才公布的 drand,缺席换来的是一个谁都不知道的新结果,只能盲抽。
- 盲抽也要付代价。缺席账户想拿回本金,必须补交秘密;一补交,任何人都能算出“如果当时揭示,结果是什么”。如果缺席总是把庄家要赔的局变成庄家赢的局,几次之后就一目了然。不补交,本金归本局其他玩家,不归庄家。
- 庄家缺席只罚不兜底。只有庄家能最先看到完整结果。如果它不公开种子也走 drand,它就能在要输时免费重抽。所以这一条只罚:把本局锁定的全部准备金分给玩家。
- 任何人都能开兜底。drand 那一轮公布后,任何人都能提交它来结算,你在页面上也可以点“自己开奖”。合约里没有任何把一局作废的入口。
诚实的边界
下面这些是现阶段还没解决、或者只能发现不能阻止的问题。我们把它们写在这里,而不是藏起来。
- 拒收揭示只能发现、不能强制赔付:目前平台是唯一的转发者,也是唯一的出块者。引入独立验证节点后,你的揭示可以经由别人的节点上链,到时这一条会变成可强制执行。上 wUSD 之前,还会公布“凭页面证据赔付”的规则。
- 多人局还剩一次“盲抽”:平台用自己的账户缺席,可以把一局的结果换成 drand 重抽一次。它挑不了结果,而且每次都要赔上本金,或者留下公开证据。等有了独立验证节点,改用验证节点之间的门限签名生成随机数,这一点也就堵上了。
- 验证节点的时钟要准:drand 兜底和多人局都依赖链上时间。观察节点的时钟监控正在建设。
- 当前是测试币:以上都运行在 sbUSD 测试币上,不涉及真钱。