本文介绍了静默支付(Silent Payments)的基本概念,这是一种在实现静态收款标识符的同时兼顾隐私性的解决方案。文章详细解释了第一个关于静默支付的比特币强化提议 BIP352,并展望了静默支付的采用方式,以及分析了两种工作模式下的扫描负担,最后提及了静默支付的现在和未来发展。
作者:Anony
“静默支付(Silent Payments)” 是一种为实现静态收款标识符同时兼顾隐私性要求而提出的解决方案。使用它,支付接收者只需公开一个稳定不变的标识符(可以视为一种特殊的地址),发送者将在支付发送过程中为接收者创造出不重复的新比特币地址。
本文尝试解释其基本概念、第一个关于静默支付的比特币强化提议 BIP352 [5],并基于 BIP352 的规范展望静默支付的采用方式。
为理解静默支付的概念,我们先来回顾 “链上” 比特币(也即以区块链为交易确认方式)的支付过程:
此过程跟以下几点有关联:
在当前的比特币保管方案中,BIP-32 分层确定性钱包方案,解决了上述隐私性与备份便利性的矛盾 [2]:Bob 使用的密钥都从同一个种子经过确定的步骤派生出来;由于这些密钥都有同一个源头,因此 Bob 只需备份这个种子即可(最多需要额外备份极少量的派生步骤信息);而由于派生的步骤具有单向性,第三方无法从这些密钥的公钥中推断出他们属于同一个源头,也很好地保证了隐私性。
唯一尚不如人意的地方是,交互需求依然存在。每一个支付者都必须先跟 Bob 建立通信、获得一个新地址,然后才能发起支付。有没有能够实现静态的收款标识符(地址)、又不牺牲隐私性的办法呢?
静默支付概念的提出者 Ruben Somsen 曾在一场演讲中集中地讨论可能的解决方案 [3],静默支付也属于其中之一,而且显示了一种特殊的(可以说有些激进的)取舍:通过增加接收者 Bob 的扫描负担(即上述支付过程第 4 个步骤的复杂性),来消除交互需要。
静默支付运用了一个叫做 “迪菲-赫尔曼 密钥交互(Diffie–Hellman key exchange)” 的概念(它跟 “公钥密码学” 的概念同龄! [4]):如果 Alice 和 Bob 各有一对公私密钥对,那么他们只需知晓对方的公钥,凭借一个简单的操作,就可以获得一个只有他们彼此知晓的共享秘密信息:以己方的私钥乘以对方的公钥。
由于私钥与公钥间的数学关系,当 Alice 拿自己的私钥乘以 Bob 的公钥时,得到的数值会跟 Bob 以自己的私钥乘以 Alice 的公钥得出的结果相同。
我们以基于椭圆曲线的公私钥为例,Alice 的公钥 A 是私钥 a 与椭圆曲线点 G 运行点乘法得到的;Bob 的密钥对类同。那么:
a.B = a*b.G = b*a.G = b.A
。这叫做 “ECDH(椭圆曲线上的 DH 密钥交换)”。根据定义,只有知晓其中一个私钥的人才能获得这个秘密值,所以其他人都不知道,只有他们彼此知道。
设想一下,如果 Bob 提前公开了自己的一个公钥,那么 Alice 无需再与他交互,就可以凭借自己的私钥,得出一个新的秘密值,然后凭此秘密值派生出一个新的公钥(再派生出相应的地址)。比如说,这个新公钥是 Bob 的公钥加上共享秘密值的哈希值的椭圆曲线点: New PK = B + H(a.B).G
;这个公钥背后的私钥是: New sk = b + H(b.A)
。显然,只有 Alice 和 Bob 才能知道这个公钥是如何构造出来的,因为其中用到了只有他们知晓的共享秘密值;而且,只有 Bob 才能花费这个地址里的资金(因为其私钥 b 只有他知道,Alice 也不知道)。
这种办法满足了上述三个要求:(1)只要 Alice 不复用私钥,就不会得到相同的地址;(2)Alice 不再需要跟 Bob 交互,可以直接构造出只有 Bob 能够花费的地址;(3)Bob 也不需要为每一个新地址备份密钥材料,因为从一定意义上来说,它们也都是从同一个种子(密钥对)中派生出来的。
然而,问题是,Alice 怎么告诉 Bob 自己用到了哪一对密钥呢?如果 Bob 不知道 Alice 的公钥,这一套把戏不就没法玩下去了吗?
这就是静默支付与以往的类似概念更激进的地方:它要求 Alice 使用交易输入中用到的公钥,而不用其它手段传达这些信息(比如额外的 OP_RETURN 交易输出),从而,运用了上述密钥交换技巧的交易在外观上跟不使用这类技巧的交易看起来毫无分别!这就最大限度地满足了隐私性的要求,而发掘隐秘信息的任务就完全交给了 Bob。
以上就是静默支付的基本概念。接下来,我们看看 BIP352 如何为上述静默支付的骨架增加血肉、使之成为一种可用的技术,其各项规范又如何影响支付接收者 Bob 的扫描负担。
BIP352 编写得很好,在概述部分遵循了逐步推进的流程,详述部分也相当严谨。为平衡介绍其中内容的需要和本文的目的,将其主要设计目的和抉择重述如下:
以上即是 BIP352 的大致内容。
基于上述设计,支付接收者 Bob 在区块链上扫描与自己有关的静默支付交易时的流程大致如下:
敏锐的读者可以发现,上述 1 和 2 两个步骤,正是BIP352 在 “静默支付” 的基础概念上做出的两个关键设计的直接后果:(1)在派生支付发送方和接收方的共享秘密值时,使用全部交易输入的信息;(2)尽可能支持多种输入类型。这样的扫描负担,显然会影响静默支付的采用(或者说,这种成本会限制其应用场景)。
接下来,我们讨论 BIP352 静默支付钱包可能的工作模式,并使用比较法来理解其扫描负担。
分析上述接收者扫描流程可以发现:不论扫描者是 Bob 还是 Carol,他们都要运行扫描的前两个步骤,并且在两个步骤结束时得到的结果是相同的。也就是说,因为 BIP352 静默支付 “使用所有输入”,所以,一笔交易是否是潜在静默支付交易,以及(如果是)其 input_hash 和 A,是一种对所有静默支付接收者都同样有用的信息,一种可以复用的信息(实际上,接收者只需要获得这两者的乘积)。由此,可以想象的一种工作模式是 “服务端-客户端 模式” :由服务端运行扫描的前两个步骤,并给客户端提供得到的结果;客户端仅根据本地的密钥信息运行最后一个步骤。这种模式就类似于常规钱包中的 “全节点-轻节点” 模式,可以大大减少客户端的工作量。
与之相对的是 “集成模式”,即不分拆工作量,三个步骤都由同一台计算机完成。
然而,更细致地考虑上述扫描步骤,并联系起全节点的工作模式,你会有更进一步的发现:
扫描步骤 1 和 2 需要获得一笔交易的所有输入的脚本公钥,用于判断输入的脚本类型,并根据脚本的类型执行相应的公钥提取步骤,仅凭暴露在交易中的信息,包括 “脚本签名(ScriptSig)” 和 “见证(txinwitness)”,是不够的。然而,全节点在验证新到达的区块中的交易时,本身也要求这些信息,并且,获得这些信息仅需要在 UTXO 集中搜索,不需要访问历史区块和历史交易(不触发较深的硬盘读取)。
也就是说,如果在验证新区块内交易的同时执行上述扫描步骤,那就是顺带的,额外开销完全来自于计算(输入输出的类型检查、公钥提取、共享秘密值推导、ECDH,等),客观来说这些计算量也不会太大;然而,如果我们使用一个单独的进程来运行扫描,则不仅要付出额外的计算开销,还需要额外的、较深的硬盘读取,因为新区块一旦验证完成,其中的交易的输入的脚本公钥就不再能从 UTXO 集中获得,只能通过访问历史交易来获得(并且,这里还多一项存储空间开销:为区块链上的所有交易编制索引,如果这样的索引不存在,则实际上无法读取历史交易,而同步 验证-扫描 模式并不需要为历史交易编制索引)。
由于这种显著的开销区别 [8],我们补充 “集成模式” 的定义:扫描步骤作为区块验证的附属步骤,与区块验证同步完成。
请注意,补充完定义之后,“集成模式” 和 “服务端-客户端 模式” 的合集就不构成全集:有一种可能是,不分拆扫描的工作量,但扫描工作依然在一个独立的进程中完成。
构造这两种模式的定义仅仅是为了便于我们通过比较来理解 BIP352 静默支付接收者的扫描负担:由于定义的准确性,他们都有合适的比较对象,集成模式可以跟基于全节点的常规钱包作比较;服务端-客户端 模式可以跟基于 BIP158 区块过滤器 [9] 的轻节点的常规钱包作比较。
为此,我们对网络中出现的交易的数量与比例,以及钱包所控制的地址的数量,作出以下假设:
n
笔交易,它们总共有 m
个交易输入和 o
个交易输出;p
,而 P2TR 输出占单区块内所有输出的比例为 q
;1
个静默支付地址;20
个 P2TR 地址;在上述假设下,基于全节点的常规钱包的扫描负担是: 20 * o * q
,也即对区块中每一个 P2TR 输出运行 20 次地址匹配检查。而集成模式中的静默支付钱包的扫描负担是: n * p * I + o * q * 1
,第一项是静默支付扫描的前两个步骤带来的开销,它是以交易为单位的,这里的 I
是对一笔交易执行类型检查、公钥提取、ECDH 等操作所需的计算量,这里假设是一个常数;第二项则是对这些潜在交易的每一个 P2TR 输出执行地址匹配检查所需的计算量,给定钱包主人只公开过 1
个静默支付地址,就只需要执行 1
次。
至于基于轻节点的常规钱包,我们知道其工作模式是先验证区块过滤器;如果过滤器显示区块内没有自己关心的输入和输出,则不再下载完整的区块;如果区块过滤器显示有(这里存在一个极小的误判可能),则下载并检查地址匹配。我们把验证区块过滤器的负担当成一个常数(这不影响比较),则其扫描负担是: 1/x * 20 * o * q
,这里的 1/x
就是过滤器命中的概率,该值必定大于 BIP158 区块过滤器的误判概率,但实际大小取决于本钱包收取的交易在区块间的分布。
而基于 服务端-客户端 模式的静默支付钱包,其扫描负担是: n * p * I_1 + o * q * 1
。这个式子之所以跟集成模式这么相似,是因为:服务端仅仅只是完成了一部分扫描工作,而对每一笔可能的交易,客户端都仍需执行一部分工作(具体来说是 ECDH)(它只是 I
的一部分,因此记为 I_1
),而对 P2TR 输出的地址匹配检查,则完全无法从服务端的工作中受益,因此保持原样。
总结上面的分析:
性能/成本 毫无疑问会影响一项技术的采用。从上述分析中我们可以知道,不论在哪一种工作模式下,静默支付钱包都要付出相对常规钱包更大的代价。可以说这也在我们的意料之中,因为这是 “静默支付” 的先天特性。至少,在人们设想的应用场景(接受捐赠、以机构身份接受支付)中,静态收款方式的好处应该能盖过其额外开销。而且,给定 服务端-客户端 的可能性,一部分工作量是可以复用的。
当前,多个项目在尝试实现 BIP352 静默支付钱包,比如:
此外,开发者们也正在为了让静默支付能够兼容 coinjoin 交易而增加多种规范。在 coinjoin 交易中,多个参与者会各自为交易提供输入并指定输出;根据 BIP352,为了让这样的交易承载静默支付,支付者必须让每一个合格输入的私钥都参与共享秘密值的推导;同时,这不能造成真实私钥的泄露;此外,还需要工具能够在各方之间传递被构造的交易的信息(接收者的脚本必须在每一个参与者都参与计算之后才能得出)。与此相关的规范有:
人们还在探索与静默支付有关的协议设计空间。
(完)
https://www.btcstudy.org/2023/10/25/a-guide-for-recovering-your-bitcoin-wallets/ ↩
https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange ↩
https://github.com/bitcoin/bips/blob/master/bip-0352.mediawiki ↩
https://learnblockchain.cn/article/18048/#BIP30%EF%BC%9A%E7%A6%81%E6%AD%A2%E5%87%BA%E7%8E%B0%E7%9B%B8%E5%90%8C%E7%9A%84%E4%BA%A4%E6%98%93-ID ↩
8.这种显著的开销差异可能解释了为何一些开发者决心在 Bitcoin Core 中实现 BIP352。见: https://github.com/bitcoin/bitcoin/issues/28536 ↩
- 本文转载自: btcstudy.org/2025/03/28/... , 如有侵权请联系管理员删除。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!