
比特币白皮书的第 8 章节里描述了简易支付验证(Simplified Payment Verification,简称SPV)。 它允许交易接收者仅需利用 Merkle 证明,而无需下载完整的区块链,就能证明交易发送者对其所支付的资金具有控制权。 但这并不能保证这笔资金之前没有被花费掉,将交易提交给比特币矿工才能获得这种保证。尽管如此,若这笔资金此前被花费掉了,SPV 证明也可以被当作是受法律认可的数字签名技术,从而成为欺诈行为的有力证据。
SPV 允许用户之间安全地进行点对点交易,而节点之间则形成结算层。
优点
就所需数据量而言,使用 SPV 的优势很明显:
- 一个钱包就能将所有必要的区块头存储在大约 50MB 中——这涵盖了整个区块链(截至 2020 年 1 月,每个区块 80 字节,链上大约有 620,000 个区块)。总量以每年约 4MB 的速度线性增长(网络上每挖出一个块,不管区块有多大小,它仅会增加 80 个字节)。
- 对比一下,如果不使用 SPV,想要存储整个链则将需要数百 GB 。
- Merkle 路径所需的数据大小最大为64log2n字节,其中n是一个区块中的交易总数。
如比特币白皮书第 8 章节所述:
“… [ SPV 客户端]只需要保留最长的工作量证明链条的区块头的拷贝,它可以不断向网络发起询问,直到它确信自己拥有最长的链条,并能够通过merkle的分支通向它被加上时间戳并纳入区块的那次交易。……”
白皮书在第 7章节中:
“……一个不含交易信息的区块头(Block header)大小仅有80字节。如果我们设定区块生成的速率为每10分钟一个,那么每一年产生的数据位4.2MB。(80 bytes * 6 * 24 * 365 = 4.2MB)。”
方法
一直以来,有很多对 SPV 和点对点交易的误解。过去人们习惯让交易发出方将交易广播到所有的比特币网络节点,随后交易的接收方需要以某种方式过滤网络中的全部交易,来查找到与自己相关的特定交易(这本身就是一项极其困难的任务)。最后,即使交易的发出方将交易发给了交易接收方和其它网络节点,按照惯例,无论交易类型、金额或情况如何,接收方也都必须至少等待交易确认6次。
因此,更好的方法是让交易通过SPV 客户端直接进行点对点地交涉,然后交易通过网络节点在比特币账本上进行结算。这与使用支票相似,交易可以更快速地完成:客户将签署的支票(交易)交给商家,然后商家将支票存入银行或兑现(在链上结算交易)。当/如果商家认为当前交易的风险是可以接受的,他们就会直接交付商品或服务。
世上从来都没有绝对安全的东西,欺诈的风险永远会存在(尽管它会随着时间的递推移呈指数下降)。如果交易的商品只是一杯咖啡,那么出售咖啡的商家面临的风险肯定比出售汽车的商家面临的风险要小,因此他们的交易处理方式就会不同。如果卖一杯咖啡,商家可以使用上述的 SPV 流程,只要交易确认有效他们就认可这笔支付,随后再将交易提交到网络(如果使用MAPI,甚至只需提交给受信任的矿工)。由于这种模式,他们可以在几秒内就收到欺诈企图通知和证据,因此他们不会想自己维护整个账本,甚至不希望保留用于检查的 UTXO 设置,因为他们面临的欺诈风险与维护整个账本所需的成本并不匹配。 SPV 就像没有密码的非接触式即时支付一样,此外它的安全性也很高,因为商户可以快速收到欺诈企图的反馈。同样,商户也不想让他们的客户等待6个确认,这毫无必要,因为他们已经通过SPV确认自己收到了一笔可能有效的交易,并且交易在没有双花警报的情况下被网络接受了,这种情况下,他们是有信心能够承担一杯咖啡的风险的。
Merkle树、Merkle根、Merkle路径和Merkle证明
“Merkle 树”是计算机科学中用于验证数据的结构 – 有关更多信息,请参阅维基百科定义。
比特币区块中的“Merkle根”是在区块头中的一个哈希值,它是由这个区块中所有交易的哈希值计算得出的。
SPV 中的 “Merkle路径”指的是用户从自己的交易哈希,来一步步计算出这笔交易所在区块的 Merkle 根的数值所需的数据信息。 Merkle 路径是 Merkle 证明的一部分。
SPV 中的“ Merkle 证明”是用于证明某笔特定交易存在于特定的一个区块中(用户无需检查区块中的所有交易)。它包括“Merkle根”和“Merkle路径”。
- 要创建Merkle证明,用户(或他们的钱包)只需要交易的Merkle路径以及给定区块的区块头(80 字节)。
- 为了验证merkle证明,用户(或他们的钱包)只需要区块头组成的链(而不是整个区块本身)。也就是说,他们无需检查该区块中的全部交易,只需要确定自己拥有的所有区块的区块头副本是准确的,并使用他们自己的区块头链,连同他们想要验证的交易(或其哈希值/交易id),以及它的 Merkle 证明(有时也称为入块证明),就能够验证这笔交易是否被纳入进了一个特定的区块。
Craig Wright博士在2019 年 3 月写了一篇题为 Merkle Trees and SPV 的文章澄清了一些过去人们对 SPV 和交易验证的误解。文章中包含如下图片,显示了交易哈希值如何与区块头中的 Merkle 根相关联:
SPV 钱包
SPV 钱包是一种轻量级钱包,它使用 SPV 的机制来构建比特币交易及进行支付。
为了花费某个 UTXO,SPV 钱包的用户将把以下信息传递给收款方:
- transaction0 – 以此 UTXO 作为输出的交易
- transaction0的默克尔路径
- 包含源自 Merkle 路径的 Merkle 根的区块头(或其标识符,例如区块高度)
- transaction1 – 花费此 UTXO 的交易
用户将以如下方式验证信息的有效性:从transaction0的默克尔路径计算默克尔根。然后用户将其与区块头中指定的 Merkle 根进行比较。 如果它们相同,则用户接受链上的transaction0的内容。
离线支付
请注意如果用户在本地储存了transaction0,那么他就能够离线对transaction1进行签名,因为transaction1中的任何签名都需要来自transaction0的scriptPubKey(锁定脚本)。