协议演进 / BIP/比特币改进提案 / BIP-326

BIP-326 Taproot 交易中的防手续费狙击

建议 Taproot 钱包以约一半概率改用 nSequence 实现防手续费狙击,为使用 PTLC 的链下协议扩大链上匿名集。本 BIP 目前处于草案状态。

一、档案卡

档案卡
编号BIP-326
标题Anti-fee-sniping in taproot transactions
作者Chris Belcher <[email protected]>
指定日期2021-06-10
讨论日期2021-06-10
层级Applications(应用)
类型Informational(信息类)
状态Draft(草案)
阅读版https://bips.dev/326
官方原文https://github.com/bitcoin/bips/blob/master/bip-0326.mediawiki

二、放在哪一族

钱包行为与隐私族,具体落在 Taproot 钱包的默认做法上。它不定义新地址、新脚本或新共识规则,而是建议钱包在构造 Taproot 花费时如何填写已有的时间锁字段。

它依赖的既有规则包括:

BIP-68:用序列号表达相对锁定时间,nSequence 的编码上限与语义出自这里

BIP-341:Taproot 的 SegWit v1 花费规则,本篇所说的 Taproot 交易即花费 BIP-341 输出的交易

与之形成对照的是现行主流做法:用 nLockTime 做防手续费狙击(anti-fee-sniping),原文提到该做法已在 Bitcoin Core 与 Electrum 中实现。链下协议一方则包括 CoinSwap、闪电网络与离散对数合约(DLC)等将采用 PTLC 的协议。

三、它要解决什么

3.1 PTLC 更私密,却会在关通道时露馅

Taproot 让点时间锁定合约(PTLC)成为哈希时间锁定合约(HTLC)更私密的替代:用 PTLC 关闭链下合约时,链上只看到一个普通的 Taproot 脚本,看不到哈希值与原像。

但若关闭时走的是时间锁路径,链上会出现 OP_CHECKSEQUENCEVERIFY 操作码或交易中的 nSequence 值。这类标记在当时并不常见,等于把“这是一笔链下结算”写在了脸上。

3.2 让普通钱包的日常交易来打掩护

本篇的思路是:让 Bitcoin Core 这类链上钱包在自己的 Taproot 交易里也日常地设置 nSequence(按 BIP-68 的方式),用它替代一部分原有的 nLockTime 防狙击保护。

这样,观察者再看到带 nSequence 的 Taproot 花费时,无法分辨它到底是普通钱包的日常花费,还是走了时间锁路径的链下结算。两类交易彼此不可区分,链下协议的隐私与可替代性(fungibility)随之改善。

原文强调时机:Taproot 刚加入比特币、钱包软件正要实现 Taproot 钱包,此时推动这一默认行为,才能让 nSequence 交易的匿名集从 Taproot 被钱包采用之初就开始积累。

3.3 背景概念:手续费狙击、防钉住

手续费狙击(fee sniping)是低通胀未来的一种假想激励扭曲:大矿工可能故意尝试挖两个区块来孤立当前最优区块。nLockTime 或 nSequence 式的防狙击保护会让这种攻击很快耗尽可放进第一个区块的交易,强化“向前推进链”的激励。

交易钉住(transaction pinning)则是利用节点防滥用规则抬高手续费替换成本的手段,会让多方合约协议的手续费管理更困难。给所有花费路径加上 1 个区块的相对时间锁(如 1 OP_CSV,或等价的 nSequence=1)可以让未确认 UTXO 无法被立即花费,从而缓解钉住;现实中大量链上交易本就花费一两块前刚产生的输入,这类 nSequence=1 的普通交易也能为链下交易提供掩护流量。

四、规则本身

4.1 二选一,各约一半概率

钱包在花费受 BIP-341 Taproot 保护的 UTXO 时,应设置 nLockTime 或 nSequence 来防手续费狙击:即让交易只能被打进链尖的下一个区块,而不是当前区块。本篇建议两者各以 50% 概率选用。

若选用 nSequence,应至少作用于交易的一个输入;多输入时,建议随机挑一个输入来设置。

4.2 再往回随机偏移

钱包还应有第二重随机分支:以一定概率把 nLockTime 或 nSequence 的值再往回拨。现有行为是:以 10% 概率随机选 0 到 99 之间的数,从当前区块高度中减去。这样做的目的是让签名后延迟广播的交易(例如经过高延迟混合网络)也有更好的隐私。

4.3 nSequence 的编码上限

nSequence 按 BIP-68 只能编码到 65535 个区块的距离。因此,若所花费的 UTXO 确认数超过 65535,钱包应改用 nLockTime。

伪代码还补充的细节包括:BIP-68 要求交易版本为 2;先按是否启用 RBF 初始化各输入的 nSequence;存在未确认输入、非 Taproot 输入或任一输入确认数超过 65535 等情形时走 nLockTime 分支;走 nSequence 分支时把 nLockTime 置 0,被选中的输入 nSequence 设为其确认数(随机回拨时最低不低于 1)。

五、谁必须动

普通持币人:无需手动操作。用不用这套做法,取决于所用钱包是否实现;个人资产的安全模型不因字段选法改变。

钱包开发者:这是本篇唯一真正要求行动的角色:在构造 Taproot 花费时按上述概率规则在 nLockTime 与 nSequence 之间选择,并处理确认数超限、RBF 标记、未确认输入等边界。原文指出,钱包本来就跟踪自家 UTXO 的确认数,所需信息现成可用。

全节点与矿工:无需改动。不涉及新的转发或打包规则。

共识层:明确无需共识变更。任何钱包都可单方面、渐进地采用。

六、现在算不算数,以及一个常见误读

状态为 Draft(草案),类型为 Informational(信息类)。也就是说,它是一份尚在草案阶段的行为建议:不强制任何钱包照做,也不代表已形成全网统一做法。原文没有给出各钱包实际采用情况的统计,本页不臆测采用进度。

常见误读:

“BIP-326 取消了 nLockTime 防狙击,改成只用 nSequence。”

不对。原文明确说绝对锁定时间仍在使用,应当保留 nLockTime,只是“也经常使用 nSequence”:建议是两者各约一半概率,并且在确认数超过 nSequence 编码上限、输入未确认等情形下仍走 nLockTime。

七、延伸

本页内容整理自 bitcoin/bips 仓库与 bips.dev,事实已与仓库核对;解读仅供学习参考。