BSV 的 nLocktime 和 nSequence

BSV 的创世纪升级,恢复了交易的 nLockTime 字段和交易输入的 nSequence 字段的原始功能。这两个字段共同决定了这笔交易是否处于“最终状态”(finality)。

具体规则为:

  • 如果输入 nSequence 的值等于 0xFFFFFFFF,那么这个输入是 final 的
  • 如果输入 nSequence 的值小于 0xFFFFFFFF,那么这个输入是 non-final 的
  • 如果交易的所有输入都是 final 的,那么这个交易就是 final 的。此时不论 nLocktime 的值是多少,都会被忽略
  • 如果交易至少有一个 non-final 输入:
    • 如果 nLocktime 小于 500,000,000,那么它的值表示一个区块高度
      • 如果当前区块高度不小于这个值,那么这个交易是 final 的
      • 否则,这个交易是 non-final 的
    • 如果 nLocktime 不小于 500,000,000,那么它的值表示一个 Unix 时间戳
      • 如果当前 MTP 时间不小于这个值,那么这个交易是 final 的
      • 否则,这个交易是 non-final 的

节点会转发 non-final 交易,但只会打包 final 交易。也就是说,如果一个交易是 non-final 的,那么它一定是未确认的。

请注意,你可以在交易未确认时就花费它的输出,但有一个前提:这个交易必须是 final 的。花费 non-final 交易节点会报错

有两种方法,可以让交易从 non-final 变成 final:

  1. 等待,直到满足 nLocktime 的限制
  2. 被“新版本的自己”替换

如果节点收到了一个新交易,它能同时满足:

  • 新交易与之前收到的 non-final 交易具有相同顺序的相同输入
  • 新交易中每个输入 nSequence 的值都不小于 non-final 交易中对应输入 nSequence 的值
  • 新交易中至少有一个输入 nSequence 的值大于 non-final 交易中对应输入 nSequence 的值

节点就会认为这个新交易是比之前收到的 non-final 交易更“新”的版本,就会用它替换掉之前的 non-final 交易。如果这三个条件不能同时满足,节点就会拒绝这个新交易。

如果新交易的输入与之前 non-final 交易的输入相冲突(部分相同但又不完全一致),那么根据“先见”原则,新交易会被当成是“双花”交易,也会被拒绝。

参考