Some checks failed
Build docker and publish / linux (1.24.5) (push) Failing after 39s
- 新增系统称号模板与效果配置表及相关CRUD接口 - 实现用户称号分配与抽奖效果应用逻辑 - 优化抽奖接口支持用户ID参数以应用称号效果 - 新增称号管理前端页面与分配功能 - 修复Windows时区错误与JSON字段初始化问题 - 移除无用管理接口代码并更新文档说明
82 lines
3.8 KiB
Markdown
82 lines
3.8 KiB
Markdown
# 头衔加概率与折扣的可验证设计
|
||
|
||
## 结论
|
||
|
||
* 采用“权重修饰”的方式为持有头衔的用户提升抽奖概率。
|
||
|
||
* 哈希算法(HMAC-SHA256 随机熵)保持不变;只扩展承诺与收据的字段以固化规则与有效权重,保证可验证性与不可篡改。
|
||
|
||
## 必要扩展
|
||
|
||
* 承诺扩展(IssueRandomCommitment)
|
||
|
||
* 新增 `AlgoRulesHash`:对“权重修饰规则(由头衔配置确定的纯函数)”做哈希并随期承诺固化。服务端在抽取前不能更改规则。
|
||
|
||
* 收据扩展(Receipt)
|
||
|
||
* 新增 `UserId`:明确本次抽取的用户。
|
||
|
||
* 新增 `WeightsTotalEffective`:按用户头衔修饰后的总权重,用于位置采样与第三方复核。
|
||
|
||
* 新增 `UserWeightFactorsRoot`:以 `reward_id -> factor` 做 Merkle 根,第三方可据此对 `Items(snapshot)` 重建有效权重。
|
||
|
||
* 编码消息扩展(不改算法,仅改输入)
|
||
|
||
* 仍使用 `HMAC(serverSubSeed, encodeMessage(...))`;`encodeMessage` 增加 `UserId` 与 `WeightsTotalEffective` 字段(保持确定性)。
|
||
|
||
## 规则与确定性
|
||
|
||
* 规则来源:头衔模板配置(百分比或加点),以及叠加策略(none|max|multiply)。
|
||
|
||
* 纯函数:`factor = F(user_titles, reward_id)`,只依赖用户持有的头衔与静态规则;不依赖随机数或服务端临时状态。
|
||
|
||
* 可复核:第三方得到 `ItemsRoot`、`AlgoRulesHash`、`UserWeightFactorsRoot`、`UserId` 与收据内快照,即可重建每个 `reward_id` 的有效权重与 `WeightsTotalEffective`,据同样的消息编码与哈希熵验证 `SelectedIndex`。
|
||
|
||
## 核心流程(抽奖不变,仅插入修饰步骤)
|
||
|
||
1. 读取承诺:`GetIssueRandomCommit(...)`(`internal/service/activity/random_commit.go:99`)。
|
||
2. 载入奖励池快照:同现有实现(`internal/service/activity/draw_execute.go:21-35`)。
|
||
3. 计算用户权重修饰:`effective_weight[i] = base_weight[i] * factor(user, reward_id[i])`;汇总 `WeightsTotalEffective`。
|
||
4. 使用 HMAC-SHA256 生成熵(算法不变),对 `encodeMessage(..., UserId, WeightsTotalEffective)` 取样位点。
|
||
5. 按有效权重的累加区间选中 `SelectedIndex/SelectedItemId`。
|
||
6. 返回收据,并包含 `UserWeightFactorsRoot` 与证明材料。
|
||
|
||
## 折扣集成(独立不影响随机)
|
||
|
||
* 抽奖订单创建(新增):以活动门票价 `PriceDraw`(`internal/repository/mysql/model/activities.gen.go:22`)为基价。
|
||
|
||
* 头衔折扣:按叠加策略计算 `discount_amount`,落到订单字段 `DiscountAmount/ActualAmount`(`internal/repository/mysql/model/orders.gen.go:22`)。
|
||
|
||
* 与优惠券/积分叠加:默认“优惠券优先 + 头衔折上折”,可通过 `stack_policy` 切到“取最大”。
|
||
|
||
## 接口与服务
|
||
|
||
* 管理端:头衔模板 CRUD + 发放;配置权重修饰参数与叠加策略。
|
||
|
||
* APP:
|
||
|
||
* 抽奖订单创建接口(新):返回计算后的金额。
|
||
|
||
* 抽奖接口:保持路径不变(`internal/api/activity/draw_app.go:28`),服务内执行权重修饰。
|
||
|
||
* 模拟与校验:
|
||
|
||
* 模拟接口增加 `user_id`,输出期望概率与观测分布。
|
||
|
||
* 校验接口以收据扩展字段重建有效权重,验证 `SelectedIndex`。
|
||
|
||
## 验收标准
|
||
|
||
* 头衔发放后,持有用户的抽奖订单能正确展示并结算折扣。
|
||
|
||
* 抽奖收据包含新增字段,第三方使用承诺与收据可重放选中过程;不持有头衔的用户与持有者的分布差异符合规则。
|
||
|
||
* 哈希熵算法未变,安全与不可预测性不受影响。
|
||
|
||
## 说明:关于“加概率是否影响哈希算法”
|
||
|
||
* 不影响哈希算法本身(仍是 HMAC-SHA256)。
|
||
|
||
* 影响的是“采样空间”——由原始 `weights_total` 改为 `WeightsTotalEffective`,并且将该值与用户标识作为消息输入的一部分来固定采样过程;承诺和收据的扩展确保服务端无法事后调参。
|
||
|