跳到主要内容

005 · 累计支付需求

要解决什么​

买方验证 004 的内容后,才签出本次累计付款状态并交给卖方。费用池不为每个块独立扣一笔临时金额,而采用覆盖式的累计支付状态:同一池始终花费同一个基础输出,最新状态完整承接此前已付金额。

卖方把该远期交易提交给 BSV 非最终交易池。它在到期前只被节点验证、保存和覆盖,不进入区块;到期后最新状态才进入可打包状态。买卖双方若协商结束池子,则把同一状态改为立即最终化并提交。

最重要的规则:支付序号​

PaymentSequence 就是花费交易输入的 nSequence,描述费用池版本,不是文件块编号、请求编号,也不表达种子与块的顺序。

设当前最新状态为 N,卖方累计应得金额为 S。一次正常付款产生任意一个 N 以上、但小于 0xffffffff 的序号;卖方累计应得金额变为 S + 本次应付金额。

状态 7:卖方累计可得 1,000 sat
本次支付:80 sat
状态 8 或状态 20:卖方累计可得 1,080 sat

跳号不改变金额规则,也不允许生成两份相同或较小序号的不同状态。0xffffffff 专门表示主动关闭,不能用于正常内容付款。

买方签出付款交易后,卖方不需要再发一个“我确认该金额”的应用层反签报文。交易签名和非最终交易池接受结果本身就是可验证事实。

文件块、费用池与串行请求​

种子先用于发现文件块哈希列表;此后文件块可以按任意哈希、任意顺序购买。一个文件的不同块可使用不同费用池;同一费用池也可支付任意文件块,只要它属于相同买方、卖方和选定仲裁者组成的有效费用池。

但同一池在某个当前序号上只能有一笔待付款的内容请求。否则买方可以用同一余额同时请求多个块,卖方先交付后,买方却只签出其中一笔付款,造成免费内容交付。

因此 BitFS 的卖方行为是:

  1. 收到 003 时,针对其 OpeningProof 和费用池当前最新已接受状态验证该授权(目标 PaymentSequence = 当前序号 + 1,绝对累计金额),并确认池内不存在进行中的请求。
  2. 调用方应用在自己的数据库中原子地保存该进行中请求,并把精确签名 003 按 PaymentAuthorizationID 建立唯一索引,再交付 004。
  3. 接收最小 005(授权哈希加买方交易签名)时,先按哈希查回本地保存的精确原始 003——哈希是查找键,永远不可能解码出池 ID、金额或交易——再与本地保存的 ContentDeliveryState、OpeningProof 派生的 RefundTemplateTxID 和上一 PaymentState 交叉比较;用唯一的 BuildPaymentUpdate 实现本地重建未签名状态交易;对这笔精确重建的交易验证分离的买方签名;然后补签并合并。卖方是否接受基准状态仍是其业务最新记录的 005,以及应用何时可以花费或转交合并后的付款,都是应用决策:SDK 只针对显式传入的证据验证候选。
  4. 哈希无法解析到原始 003、交付上下文不匹配(错池、序号过时或重复)、或重建字节与该授权此前的任何重建不一致时,拒绝 005;绝不要求买方重发旧 wire raw 交易作为兜底。授权哈希只是查找原始 003 的键:同一个池可以同时存在多个不同授权哈希,按哈希加锁无法阻止两个请求同时消费同一份 previous state。全部 003 接受、004 交付与 005 合并必须按费用池串行化,以查回的 003 中的 RefundTemplateTxID 为并发键(数据库唯一键、事务、行锁或单队列——SDK 无锁)。买方要并行购买,应新开费用池。

同一资金池的交付风险串行化由调用方应用负责。应用可以使用数据库事务、唯一约束、CAS、行锁或单队列保存交付上下文,并在自己的节点策略确认后更新业务状态。SDK 只验证显式传入的 ContentDeliveryState、付款候选和签名,不提供门闩、Store hook、节点接口、uncertain 状态或自动释放逻辑。

到期与风险边界​

这是一条单向风险边界:卖方不提交任何付款交易,买方在到期后走初始全额退款;卖方提交最新累计付款交易,到期后交易按其中的累计金额与买方找零结算。买方不因卖方不作为向仲裁者起诉,也不需要卖方反签一个链下“金额确认”。

卖方无法正常提交一份买方已签出的付款交易时,才可按 007 请求仲裁者补足签名。Seller Claim 提供签名覆盖的 source amount/script、RefundTx、Buyer-signed 条款和精确 payload bundle;仲裁者独立重建精确付款交易,不接收完整 OpeningProof 或 Seller candidate raw。

为什么这是可行的​

普通 Bitcoin 的整数序号本身不是“较大即胜”的链上规则;本设计依赖 BSV 节点的非最终交易池:同一输入的远期交易以更高 nSequence 覆盖旧状态,并在到期后再进入可打包状态。因而调用方应用的广播策略必须使用支持该能力的节点提交接口,而不能把普通广播节点当作费用池状态机;这一节点行为属于调用方的广播策略,不是 SDK 的 005 实现接口。

具体 CBOR 字段与交易校验见累计支付规范。