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 的
- 如果 nLocktime 小于 500,000,000,那么它的值表示一个区块高度
节点会转发 non-final 交易,但只会打包 final 交易。也就是说,如果一个交易是 non-final 的,那么它一定是未确认的。
请注意,你可以在交易未确认时就花费它的输出,但有一个前提:这个交易必须是 final 的。花费 non-final 交易节点会报错“找不到交易输入”(Missing inputs)。
有两种方法,可以让交易从 non-final 变成 final:
- 等待,直到满足 nLocktime 的限制
- 被“新版本的自己”替换
如果节点收到了一个新交易,它能同时满足:
- 新交易与之前收到的 non-final 交易具有相同顺序的相同输入
- 新交易中每个输入 nSequence 的值都不小于 non-final 交易中对应输入 nSequence 的值
- 新交易中至少有一个输入 nSequence 的值大于 non-final 交易中对应输入 nSequence 的值
节点就会认为这个新交易是比之前收到的 non-final 交易更“新”的版本,就会用它替换掉之前的 non-final 交易。如果这三个条件不能同时满足,节点就会拒绝这个新交易。
如果新交易的输入与之前 non-final 交易的输入相冲突(部分相同但又不完全一致),那么根据“先见”原则,新交易会被当成是“双花”交易,也会被拒绝。