比特币钱包把同一收款地址的输出最多攒一百个:OUTPUT_GROUP_MAX_ENTRIES 与避免部分花费
avoidpartialspends(避免部分花费)是比特币钱包里一个偏隐私的选项:打开以后,钱包在花钱时会尽量把收款到同一个地址上的所有 UTXO(未花费输出)一起当输入花掉,而不是只挑其中几个。这样做的好处是隐私——只花同组的一部分,等于向全网宣告”这个地址名下的余额还没动完”,把一次消费变成了一个可被追踪的聚类线索。但这个”一起花”有一条不太起眼的上限:同地址攒够一百个输出,钱包就会把它切成多组分别处理。这个一百来自源码常量 OUTPUT_GROUP_MAX_ENTRIES。本文全部以 Bitcoin Core v31.0 源码为准。
分组是按收款脚本地址归拢的
钱包在选币(coin selection)阶段,会把所有可用 UTXO 按 scriptPubKey(即锁定的收款脚本,通常对应一个地址)归到同一个”输出组”(OutputGroup)里。这个组的意义就是把”同一把钥匙能花的所有零钱”打包成一个整体,方便策略统一决策。当你开着 avoidpartialspends 时,钱包面对的每一个输出组,都是一个”要么全花要么都不花”的候选单位。
满一百就另起一组
问题在于:一个被反复使用的地址,底下可能躺着成百上千笔小额收款。如果严格”全花”,一笔交易的输入会被撑得巨大,手续费也水涨船高,用户可能完全没料到。源码为此设了闸门——在 src/wallet/spend.cpp 里,常量 OUTPUT_GROUP_MAX_ENTRIES 取值为 100。组装输出组时,钱包会把同地址的输出往当前组里塞,一旦这个组已经攒到 100 个输出,就再新建一个组继续装。代码注释写得很直白:这么限流是为了避免给用户带来”意外高昂的手续费”。换句话说,一百并不是隐私规则,而是一道费用刹车:它保证即使你坚持不部分花费,单个待选组的规模也不会失控。
对普通用户意味着什么
日常中,几乎没人一个地址收到超过一百笔钱,所以这条上限通常不会触发,它只在地址长期复用、不断接收零钱(比如老的复用收款地址、测试网水龙汇聚)时才浮现。当它触发时,你会观察到:钱包把同一地址的花费拆成了几笔,或者在一笔里只装了其中一个百位分组。这不算 bug,也不违背 avoidpartialspends 的初衷——它防的是”同组只花一小部分”这种最刺眼的泄露,而不是承诺”同地址永远一次性清空”。
常见误区
第一,把这一百当成”地址只能装一百个 UTXO”的链上限制。链上没有这个概念,一百完全来自这台节点上钱包软件的选币实现。第二,以为开了 avoidpartialspends 就能修好历史上已经泄露的聚类:它只管当前这笔新交易,早已花过、早被关联的地址救不回来。第三,把它和另一个参数 maxapsfee 混为一谈:后者是”为隐私多花多少手续费”的预算上限,一百是”一个组最多装多少输出”的尺寸上限,两者独立。真要精细控制,读自己钱包构造出的原始交易、看它选了哪些输入,永远比读别人的经验帖更准。
怎么核对
如果怀疑某个地址触发了这条上限,可以在节点上对该地址跑 UTXO 扫描(例如 listunspent 限定地址、或 scantxoutset),先确认它名下到底有多少个未花费输出;数量明显超过一百时,钱包的分组成组行为就能解释你看到的”拆单”。核验前记下节点版本与查询时刻,避免把不同快照拼成一条时间线。
风险提示:本文为钱包选币机制科普,具体默认值、参数名可能随版本调整,请以 Bitcoin Core 源码与官方文档为准;不涉及任何手续费高低或隐私强弱的收益承诺,亦不构成投资建议。
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。