当我通过BTC的listtransactions
接口获取查询最近发生的钱包交易时,需要将用户的充值记录写到数据库时,发现了一些令人巨大的误解。
例如,txid字段并不是唯一的,所以写到数据库时,会有交易哈希重复的可能性(有可能你的两个用户在币安交易所同时发起了BTC提现到你的钱包中,为节省手续费及上链时间,那么这两笔交易就有可能在同一笔交易中)
那么如何解决交易的唯一性呢,只有与神秘的“vout”字段结合使用时,它才是独一无二的。
vout是基于 0 的输出索引。它可能不仅仅是0or 1,但这些往往是最常见的,因为人们不会进行具有大量输出的交易。
要了解vout,您必须了解比特币交易的实际运作方式。比特币交易使用交易输出作为输入,并创建交易输出。它可以消费多个交易输出,并创建多个交易输出。此外,这些交易输出可以被不同的交易消费,因此每一个交易都需要能够被唯一标识。因此,唯一标识符包含两项:
- txid:用于标识输出所属交易的交易 id,
- vout: 以及指向该特定交易中输出列表中位置的索引。
vout:与计算机科学中的许多事物一样,它是一个基于 0 的计数器,因此第一项位于 index 0,第二项位于1,依此类推。
listsinceblock, listtransactions, 和 Bitcoin Core 中的一些其他 RPC 实际上并没有列出比特币交易。相反,他们列出了合乎逻辑的交易——人类倾向于想到的交易。这是因为单笔比特币交易既可以将比特币从你身边发送出去,也可以让你接收比特币。
在单个比特币交易中,您可以使用自己的交易输出,因此该交易会将您的比特币发送出去。然而,并非所有交易都包含来自同一个人的输入。该交易可能涉及另一个人,该人拥有自己的交易输出作为该交易的输入。也许他们正在创造一个你可以消费的产出。所以这个交易也在向你发送比特币。然后,这个单一的比特币交易将包含两个逻辑交易——一个是你发送的地方,一个是你接收的地方。
这通常会发生在更改输出中,但软件不应该向您显示这些,因为它足够聪明,可以隐藏它们,而不是将它们视为一个独特的逻辑事务。更改输出是指您创建的交易输出将比特币发回给您自己。它们的存在是因为交易输出必须全部花费,但您实际发送的金额通常与您花费的输出的确切金额不完全匹配。因此,您必须创建一个输出,将剩余部分发回给您自己。
比特币资金在未使用的交易输出 (UTXO)中进行跟踪。每当您发送比特币时,您的钱包软件都会声明使用了哪些特定的 UTXO,并创建新的 UTXO 以将资金分配给付款方。即使在最简单的情况下,一笔交易通常也会产生两种新的输出:一种用于支付收款人,另一种用于将剩余的零钱重新分配给发送者。
由于交易可以有多个输出,因此txid不足以唯一地识别 UTXO。但是,由于交易中输出的顺序是固定的,并且每个位置只能出现一次,因此 UTXO 可以由创建它的交易加上输出列表中的位置来唯一标识。vout是交易输出列表中 UTXO 的索引。我们称其txid:vout为UTXO的外点。
在这个来自blockstream.info的带注释的屏幕截图中,您可以看到 transaction 39b6bcf049fbfba73c2e594327cafd4f93b1c23979e138d4c56ab3b7d04172ad。它花费了一个 UTXO,即 transaction 的第 5 个输出(vout:4,我们从 0 开始计数) ,并创建了 7 个标识为through的cc90096df338a6894aeef47043b995942758a1dfe52e579560e39730602a7ca4新 UTXO 。39b6bc…4172ad:039b6bc…4172ad:6