术语表 /节点与软件
简化支付验证
又称 SPV。
- 简化支付验证是什么?
- 简化支付验证仅凭区块头和默克尔分支,即可确认某笔交易位于一个有真实工作量证明支撑的区块中。
中本聪在2008年白皮书的第8节中描述了这一方法,将其作为无需运行服务器即可使用比特币的方式。它成本低廉,因为一个区块头只有80字节:在约960,000个区块时,整条区块头链大约为77 MB,而同在2026年8月,区块本身约为759 GB。它能让您获得矿工已承诺纳入您这笔付款的证明,但完全无法说明这笔付款是否合法。
运作方式
简化支付验证凭两项证据回答一个问题。
第一项是区块头链。每个区块头恰好为80字节,包含前一个区块头的哈希、区块内交易的默克尔根、时间戳,以及矿工必须达到的难度目标。客户端只下载区块头,检查每个区块头是否与前一个相连、每个哈希是否确实低于其声明的目标,最终得到一条可以用电力成本来衡量的链。伪造它并不是靠说得像真的就行,而是要重新完成挖矿。
第二项是默克尔分支。区块中的交易两两合并哈希,直到只剩一个根,因此要证明某笔特定交易在某个区块中,只需提供通向该根的路径上的少量兄弟哈希。其数量是对数级的:包含4,096笔交易的区块需要12个哈希,即384字节,区块大小翻倍只会多出一个哈希。您的客户端沿着分支逐级计算哈希,将结果与它已信任的区块头中的默克尔根比较,结果要么是该交易在这个区块中,要么不在。
把两者结合起来,就是简化支付验证所提出的主张:这笔交易已被某个区块承诺,此后其上又累积了可衡量的工作量。
接下来是它的缺口,因为这正是有用的部分。被纳入不等于有效。该方法无法告诉您所花费的比特币是否存在,签名是否有效,区块是否给了矿工正确的补贴,也无法告诉您同一笔比特币是否在另一条分支上被花费。它也无法证明某件事不存在:服务器只要省略一笔付款,就不会留下任何证据。中本聪直接把这一限制写进了白皮书,指出只要诚实节点控制着网络,这一技术就是可靠的,而频繁收款的企业仍会希望运行自己的节点。
购买比特币时为何重要
手机钱包里的绿色对勾通常根本不是验证。
多数人在首次通过交易所购买后安装的钱包,从不构建区块头链。它们向某家公司的服务器询问您有多少余额,显示答案,并标注为已确认。这比白皮书所述的方法提供的保障更弱,而白皮书所述的方法本身又弱于运行节点。对于日常的小额余额,这条信任链没有问题,假装并非如此对谁都没有帮助。当金额大到会让您受损时,它就不再可以接受了。
实际的问题是:您在信任谁,要信任多久。本站的交易所评测列出了各平台在放行提币前的要求,而每一个确认数都是该交易所自己节点的报告。币到账后,向您显示它们的钱包又是在根据别人的节点报告。双方都不太可能说谎,但都可能出错、离线,或提供被喂给它们的链,而且发生这种情况时,双方都不会告知您。
还有隐私方面的问题。2014年针对布隆过滤器客户端的研究发现,本意是隐藏钱包关注哪些地址的过滤器,却把其中大部分地址暴露了出去。这正是 Bitcoin Core 在2019年11月发布的0.19.0版本中默认关闭该功能的原因,也是较新的轻钱包改为下载紧凑过滤器而不是上传请求的原因。
2018年9月简化支付验证本会漏掉什么
CVE-2018-17144是比特币历史上说明被纳入与有效之间差别的最清晰例子。
Bitcoin Core 0.14.0中加入的一项优化跳过了一项曾被认为多余的检查,结果受影响的版本会部分处理一个包含重复花费同一输入的交易的区块。以一种方式处理,会使节点崩溃;以另一种方式处理,则会让矿工凭空创造比特币。该漏洞于2018年9月17日被报告,并在次日于 Bitcoin Core 0.16.3中修复。没有人在主网上利用过它。
设想有人利用了它。矿工产出一个会膨胀供应量的区块,其区块头带有完全真实的工作量证明,默克尔树也完全正确。已更新的全节点解析该区块,发现重复的输入,拒绝该区块,并断开发送它的对等节点。而做简化支付验证的客户端检查区块头,检查分支,并把其中的付款报告为已确认,因为它能获得的每一项证据都是有效的。它无法获得被花费的输入,所以这个问题根本不会出现。
这就是全部的取舍。简化支付验证的规则取决于谁在挖矿,节点则不然。
简化支付验证 vs Neutrino
简化支付验证和 Neutrino 都能让钱包在没有完整区块链的情况下工作,但过滤的方向相反。BIP37 下的传统方式会把您的关注点发给某个对等节点:您上传一个过滤器,对等节点替您搜索,并大致得知您拥有哪些地址。Neutrino 是 BIP157 和 BIP158 的实现,多数移动端闪电网络钱包都在使用它,由节点为每个区块向所有人发布一个紧凑过滤器;您的钱包下载过滤器,在本地私下检测,只请求匹配的区块。此后进行的验证是同样的默克尔和区块头运算。不同之处在于,另一端没有任何人得知您在查找什么。