142 / 736SELECT

Coin Selection

为交易选择 UTXO

付款时,钱包会选择花掉哪些过去收到的款项。这个选择会影响手续费、找零,以及别人能从中了解多少关于你的资金的信息。

Coin Selection 指钱包为一笔比特币交易挑选资金的过程。余额并不是一个可以任意扣减的整体,而是由过去交易留下的、尚未花费的独立输出组成,这些输出叫作 UTXO。钱包需要选出足够的资金,支付款项和手续费。通常由钱包自动完成;手动挑选则称为 Coin Control。网络会检查最终交易是否有效,但不会要求所有钱包采用同一种选择方法。

UTXO 合并计算器比较两种模型手续费:以后一起花费 UTXO,或今天合并、以后花费一个输入。

安娜想支付 60000 sat。付款由她的钱包准备:钱包是让她接收和发送比特币的应用程序或设备。sat 是 satoshi(聪)的缩写,也是比特币交易中记录金额的最小单位。她有一个价值 100000 sat 的 UTXO。就像拿一张纸币付款一样,她不能只扣掉其中一部分:新交易的一个输入会把这个输出整体花掉。新交易为商家创建一个 60000 sat 的输出;如果手续费为 1000 sat,就再为安娜创建一个 39000 sat 的输出。后者就是找零,也叫 change。它不是商家事后退款,而是在她自己的交易里同时生成的。手续费等于输入总额减去所有输出的总额。 [1] [7]

钱包可以使用不同的 UTXO 来完成同一笔付款。但输入越多,通常需要的数据就越多,在相同费率下手续费也就越高。手续费不是按转账金额的百分比收取,而是取决于交易的虚拟大小,单位为 vB,即虚拟字节。这个指标考虑了交易各部分不同的权重。例如,一个 10000 sat 的 UTXO,花费它所需的输入估计占 68 vB。在 10 sat/vB 的费率下,该输入本身的成本为 680 sat,能用于其余付款部分的金额是 9320 sat,这就是它的有效价值。交易其他部分仍有各自的成本;输入的实际大小取决于脚本中规定的花费条件和签名数据。脚本是一段描述花费条件的小程序。进行普通付款时,钱包会用私钥这一秘密数值生成数字签名,也就是可以验证的花费授权。 [2] [3] [7]

安娜可能陆续收到许多小额款项。把它们合并成一个属于自己的较大输出,叫作归集。这样以后付款可能需要更少的输入,但归集现在就要付手续费,还会公开关联被使用的输出,因此不宜自动把所有资金都合在一起。Bitcoin Core 还会用 waste metric 比较成本。这个评分考虑输入在当前费率和假定长期费率下的成本差,再加上创建和日后花费找零的成本,或者作为手续费付出的多余金额。长期费率是计算时采用的假设,不是预测。这个评分衡量成本,不衡量隐私。 [2] [6]

安娜把一笔收入标记为工资,另一笔标记为礼物。把两笔资金一起花掉,会给区块链观察者一个线索:它们可能有关联。但这并不能证明所有输入都属于同一个人,因为交易也可以由多方共同构建。Coin Control 允许挑选具体的 UTXO,标签则帮助记住其来源。标签是钱包中的备注,不是写入区块链的消息。BIP 329 描述如何转移这些备注,以及关于钱包是否把某个输出视为可以花费的信息。这是钱包的本地设置,不会改变比特币网络的规则。该格式本身不负责选币。导出的标签可能泄露敏感关系,即使交易没有找零,也不代表一定匿名。 [4] [6]

界面显示的余额不一定全部能立即使用。有些输出被钱包主动排除,有些还在等待确认或满足花费条件。选择时还要遵守交易大小和权重的限制。如果花费一笔尚未确认的收入,新付款就依赖于产生这笔收入的上一笔交易;在这里,上一笔交易被称为祖先交易。要让整条依赖链确认,可能需要额外手续费。RPC 是程序控制 Bitcoin Core 29.0 的接口,其中 walletcreatefundedpsbt 提供 include_unsafe 选项,允许加入有风险的未确认输入。如果原交易被替换,导致所需输出不再存在,依赖它的付款就无法确认。但仅仅把原交易暂时从某个节点的内存中移除,并不会改变该交易本身的有效性。 [3] [5]

钱包如何探索不同方案?Branch-and-bound,简称 BnB,会尝试不同的输入组合,并放弃不可能产生合适结果的搜索分支。它的目标是完成付款而不创建单独的找零输出。金额不必完全吻合:允许的范围可以包含多余金额,上限是创建找零并在以后花费找零的成本。这部分多余金额会成为手续费,不会偷偷留在钱包里。因此,没有找零的付款不一定是所有方案中最便宜的。搜索次数有限,可能找不到已经存在的解,也未必找到所有组合中的最优解。 [2]

Bitcoin Core 29.0 会比较 BnB、Knapsack 和 Single Random Draw(SRD)给出的候选方案。这些都是寻找合适输入组合的不同方法。当有效费率超过长期费率的三倍时,还会使用 CoinGrinder;该方法寻找带有找零且权重较低的组合。候选方案通过前面解释过的 waste metric 进行比较。如果用户选择从收款人的金额中扣除手续费,就会跳过 BnB。这里介绍的是这个具体版本,不是所有钱包必须遵循的流程,也不是对最新版本行为的说明。 [3]

普通付款不需要了解程序参数,但在签名前,需要看懂收款人、金额、总手续费和自己的找零。对进阶用户来说,Bitcoin Core 29.0 的 walletcreatefundedpsbt 可以用 txid 和 vout 指定输入:前者是原交易的标识符,后者是其中输出的序号。add_inputs 控制钱包是否可以补充其他输入。注意单位不同:fee_rate 使用 sat/vB,而 feeRate 使用 BTC/kvB,也就是每 1000 虚拟字节对应多少比特币。结果是一个 PSBT,用于把准备好的交易交给相关方签名。单纯创建 PSBT 不会发送任何资金,也不代表付款已经确认。手动选择和 PSBT 格式都不能保证收款人正确,或未确认输入有效。 [5]

要获得更完整的理解,请将本词条与以下词条结合阅读: UTXO, Coin Control, Change Address, Fee Rate, PSBT, Bitcoin 隐私. 反向关联还来自: Watch-only Wallet, Change Address, Inventing Bitcoin.

DOC · 001Bitcoin Developer Guide — Transactions文档 DOC · 002Bitcoin Core — Coin selection implementation一手来源 DOC · 003Bitcoin Core 29.0 — Transaction creation一手来源 DOC · 004BIP 329 — Wallet Labels Export Format规范 DOC · 005Bitcoin Core 29.0 — walletcreatefundedpsbt RPC文档 DOC · 006Bitcoin Design — Coin selection and privacy文档 DOC · 007Bitcoin Developer Guide — Wallets文档
修订日期: 来源优先 · 非投资建议