比特币 比特币技术 - BTC 钱包优化 UTXO 选择的挑战

wenweihuang · 2024年01月28日 · 48 次阅读

比特币钱包不同 UTXO 选择器算法的利弊对比

BTC UTXO coin slection

当我们谈论比特币存储在区块链上时,大多数人都使用“地址余额”的专业术语,这从会计角度是有意义的,但这并不是币在区块链的数据结构中实际表示的方式。与其说地址“包含币”,不如说“币”实际上存储为“未花费交易输出”(UTXO)。UTXO 可以与比特币地址关联,尽管你也可以有许多不同的与同一个比特币地址关联的 UTXO。“地址余额”是与该地址关联的所有 UTXO 值的总和。要从非技术角度了解更多关于 UTXO 的信息,我建议阅读 Richard Gendel Brown 的《欢迎来到比特币岛》。要了解技术概述,请查看开发者指南

BTC transaction construct. 比特币交易数据结构由输入和输出构成,未花费的输出就是 BTC

当比特币钱包软件创建新交易时,它在如何安排交易的内部数据方面有相当大的灵活性。这是因为用户指示钱包:“向地址 Y 发送 X 比特币”,钱包需要查找用户的 UTXO,以找到足够的输出,其总值达到 X 比特币的目标。不幸的是,并没有一个简单直接的方法来选择 UTXO,因为有几个考虑因素。

粗暴方法是简单地寻找大于你想要花费的金额的最小输出并使用它,否则开始添加下一个最大的输出,直到你有足够的输出来满足支出目标。然而,这会导致输出的零碎,直到钱包被无法花费的“尘埃”所淹没。这既可能是性能问题,也可能会对最终用户产生干扰,如果他们曾试图清理仅剩微小余额的钱包 - 在一个经历了许多交易的钱包中,这可能会导致有太多 UTXO,无法在一个交易中全部花费。

尽管比特币交易可以包含数百个输入和数百个输出,但这是有代价的。交易中输入和输出越多,交易的数据大小就越大。比特币节点将拒绝大于 100KB 的交易。此外,由于区块的大小是受限制的(目前为 1MB),你正在与其他人竞争,以便让矿工将其添加到区块中确认你的交易。如果你广播一个没有费用或微不足道的费用的大数据大小交易,你将面临节点拒绝广播它的风险,你将面临矿工选择优先确认具有更高每字节数据费用的交易而不是你的交易。作为参考,我使用Statoshi追踪了一些关于交易和费用的数据指标 - 你可以在这里看到,撰写时的平均费用目前约为 30 satoshi 每字节交易数据。

BTC transaction size and fee
比特币交易大小和对应手续费图表

如果我们要优化钱包选择 UTXO 用于交易创建的算法,首先决定我们的目标是什么,然后要优化哪些交易属性。优化 UTXO 选择的四个广泛目标如下:

  1. 防止区块链膨胀
    A) 在可能的情况下,应避免创建小的找零输出。它们对钱包和消费区块链的所有人都有性能成本。由于比特币节点的粉尘规则和费用的市场竞争,对最终用户而言,花费这些输出也可能更加昂贵。
    B) 小 UTXO 的合并:随着时间的推移,钱包自然会控制许多小的 UTXO。为了减少钱包的 UTXO 集合大小,从而减少整个区块链的 UTXO 集合大小,最好在单个交易中花费许多非常小的 UTXO 以将它们从 UTXO 集合中移除。

  2. 支持高交易量
    A) 对于发送多个交易的高交易量钱包,重要的是保持足够数量的确认 UTXO 可用。否则,钱包将不得不花费未确认的 UTXO,这使得交易在父交易首次确认之前不可能确认。因此,如果钱包没有许多已确认 UTXO,则可能需要创建多个找零输出。

  3. 隐私
    A) 应该随机选择 UTXO,并且尽可能少地涉及不同的公钥。当钱包选择 UTXO 时,应该优先选择分配给同一公钥的任何其他 UTXO。
    B) 小输入如果明显小于找零的大小,并且与较大的输入不共享它们的公钥,则不应使用,因为它们会增加交易费用并降低隐私。
    C) 如果必须创建找零输出,则最好创建一个与支付价值相同量级的找零输出。这有助于掩盖哪个输出发送给收件人,哪个是发件人的找零。
    D) 对于有多个输出的交易,应该在随机位置插入找零输出,而不总是插入首位或末位。

  4. 最少化交易费用
    A) 优先选择成本较低的交易输入集。这意味着交易应尽可能简单且数据大小尽可能小,包括少量输入和输出。优先考虑只使用单个 UTXO 作为交易的输入。
    B) 此外,通过发送币龄较早的比特币,可以优先选择按币龄选择 UTXO - 这样一来,交易将有资格被矿工确定为“高优先级”,并且不需要附加费用即可确认。
    C) 如果消耗 UTXO 的成本(通过额外的费用要求)比其对交易输出价值的贡献要高,就不应该将其添加进去。

现实世界的钱包是如何工作的呢?对于比特币核心钱包来说,它使用了一些相当复杂的逻辑:

  1. 如果任何一个单独的 UTXO 恰好匹配目标(花费价值),则将使用该 UTXO。
  2. 如果所有小于目标金额的 UTXO 的总和恰好匹配目标金额,它们将被使用。(这可以防止在清理钱包时出现错误。)
  3. 如果小于目标金额的所有 UTXO 的总和不超过目标金额,那么将使用大于目标金额的最小 UTXO。
  4. 比特币节点进行了 1000 轮随机组合未花费交易输出,直到它们的总和大于或等于目标金额。如果找到了完全匹配的情况,它会提前停止并使用该组合。在代码注释中解释这一步的理由:“随机性并没有实际的安全目的,只是为了防止退化行为”。
  5. 否则,最终会选择大于目标金额的最小 UTXO 或在第 4 步中发现的 UTXO 组合中的较小者。
  6. 在构建最终交易时,如果有任何找零输出金额足够小以被视为“粉尘”,比特币节点不会创建这些找零输出,而是将这部分价值捐赠给矿工作为交易费。

比特币节点的优化逻辑是“以最少化找零输出”,即上面列出的目标 1A。但这是否是选择 UTXO 的“最佳”或“正确”方式?这取决于你的观点 - 如果你重视隐私、最小化交易费用或 UTXO 合并,那么这种方式就不是最优的。

比特币网络 UTXO 视图
比特币网络 UTXO 视图

很明显,对于这个问题并不存在“一刀切”的解决方案,事实上,上面概述的三个广泛的优化目标往往是直接相互对立的。鉴于这些相互冲突的目标,钱包作者的答案可能是让最终用户更多地控制钱包的 UTXO 选择算法。这应该是针对高级用户的高级功能,但我可以设想一种简单的下拉框,用户可以在“费用/性能/隐私”之间进行选择优化。

这些实施选择由钱包工程师决定,我呼吁他们成为区块链的良好管理者。请记住,我们正在向共享资源写入数据;我们最好谨慎行事。在撰写本文时 2015 年,有 17.6M 个 UTXO 需要 596MB 的数据来存储。如果比特币继续增加其受欢迎程度,这些数字必然会上升。但通过成为负责任的区块链工程师,至少我们可以防止 UTXO 集合的增长超过必要的速度。

英文原文链接

暂无回复。
需要 登录 后方可回复, 如果你还没有账号请 注册新账号