10.3 交易的独立校验
在第6章交易中,我们知道了钱包软件通过收集UTXO、提供正确的解锁脚本、构造一个新的支出(支付)给接收者这一系列的方式来创建交易。产生的交易随后将被发送到比特币网络临近的节点,从而使得该交易能够在整个比特币网络中传播。
然而,在交易传递到临近的节点前,每一个收到交易的比特币节点将会首先验证该交易,这将确保只有有效的交易才会 在网络中传播,而无效的交易将会在第一个节点处被废弃。
每一个节点在校验每一笔交易时,都需要对照一个长长的标准列表:
▷交易的语法和数据结构必须正确。
▷输入与输出列表都不能为空。
▷交易的字节大小是小于 MAX_BLOCK_SIZE 的。
▷每一个输出值,以及总量,必须在规定值的范围内 (小于2,100万个币,大于0)。
▷没有哈希等于0,N等于-1的输入(coinbase交易不应当被传递)。
▷nLockTime是小于或等于 INT_MAX 的。或者nLocktime and nSequence的值满足MedianTimePast(译者注:MedianTime是这个块的前面11个块按照block time排序后的中间时间)
▷交易的字节大小是大于或等于100的。
▷交易中的签名数量(SIGOPS)应小于签名操作数量上限。
▷解锁脚本( scriptSig )只能够将数字压入栈中,并且锁定脚本( scriptPubkey )必须要符合isStandard的格式 (该格式将会拒绝非标准交易)。
▷池中或位于主分支区块中的一个匹配交易必须是存在的。
▷对于每一个输入,引用的输出是必须存在的,并且没有被花费。
▷对于每一个输入,如果引用的输出存在于池中任何别的交易中(译者注:这笔输入引用的输出有人家自己的输入,不是你),该交易将被拒绝。
▷对于每一个输入,在主分支和交易池中寻找引用的输出交易。如果输出交易缺少任何一个输入,该交易将成为一个孤 立的交易。如果与其匹配的交易还没有出现在池中,那么将被加入到孤立交易池中。
▷对于每一个输入,如果引用的输出交易是一个coinbase输出,该输入必须至少获得 COINBASE_MATURITY(100)个确认。
▷使用引用的输出交易获得输入值,并检查每一个输入值和总值是否在规定值的范围内 (小于2100万个币,大于0)。
▷如果输入值的总和小于输出值的总和,交易将被中止。
▷如果交易费用太低以至于无法进入一个空的区块,交易将被拒绝。
▷每一个输入的解锁脚本必须依据相应输出的锁定脚本来验证。
这些条件能够在比特币标准客户端下的 AcceptToMemoryPool 、 CheckTransaction 和 CheckInputs 函数中获得更详细的阐述。 请注意,这些条件会随着时间发生变化,为了处理新型拒绝服务攻击,有时候也为交易类型多样化而放宽规则。
在收到交易后,每一个节点都会在全网广播前对这些交易进行独立校验,并以接收时的相应顺序,为有效的新交易建立一个验证池(还未确认),这个池可以叫做交易池,或者memory pool或者mempool。