轻钱包(SPV)是“Simplified Payment Verification”(简单支付验证)的缩写。中本聪论文简要地提及了这一概念,指出:不运行完全节点也可验证支付,用户只需要保存所有的block header就可以了。用户虽然不能自己验证交易,但如果能够从区块链的某处找到相符的交易,他就可以知道网络已经认可了这笔交易,而且得到了网络的多少个确认。
按照中本聪的原文,有个细节需要注意,SPV指的是“支付验证“,而不是“交易验证”。这两种验证有很大区别。
“交易验证”非常复杂,涉及到验证是否有足够余额可供支出、是否存在双花、脚本能否通过等等,通常由运行完全节点的矿工来完成。
“支付验证”则比较简单,只判断用于“支付”的那笔交易是否已经被验证过,并得到了多少的算力保护(多少确认数)。
考虑这样一种情况,A收到来自B的一个通知,B声称他已经从某某账户中汇款一定数额的钱给了A。去中心方式下,没有任何人能证明B的可靠。接到这一通知,A如何能判断B所说的是真的呢?
在比特币系统中,这一通知是以一个固定格式的“交易”来实现的,该交易中包含B的汇款账户、B的签名、汇给A的金额以及A的地址。
如果A想本人亲自验证这笔交易,首先,A要遍历区块链账本,定位到B的账户上,这样才能查看B所给的账户上是否曾经有足够的金额;接下来,A要遍历后续的所有账本,看B是否已经支出了这个账户上的钱给别人(是否存在双花欺骗);然后还要验证脚本来判断B是否拥有该账户的支配权。这一过程要求A必须得到完整的区块链才行。
但是,如果A只想知道这笔支付是否已经得到了验证(如果验证了就发货),他可以依赖比特币系统来快速验证。即,检查发生此项支付的那笔交易是否已经收录于区块链中,并得到了多少个确认。
原理:block header中有三个关键字段,一是prev_block_hash(前一区块的hash值,确保了区块链所记录的交易次序);二是bits(当前区块的计算难度), 三是merkle_root_hash(借助merkle tree算法,确保收录与区块中所有交易的真实性)。
验证某个交易是否真实存在时,理论上,用户可以通过以下方式进行验证:
0. 从网络上获取并保存最长链的所有block header至本地;
1. 计算该交易的hash值tx_hash;
2. 定位到包含该tx_hash所在的区块,验证block header是否包含在已知的最长链中;
3. 从区块中获取构建merkle tree所需的hash值;
4. 根据这些hash值计算merkle_root_hash;
5. 若计算结果与block header中的merkle_root_hash相等,则交易真实存在。
6. 根据该block header所处的位置,确定该交易已经得到多少个确认。
优点:极大地节省存储空间。减轻终端用户的负担。无论未来的交易量有多大,block header的大小始终不变,只有80字节。按照每小时6个的出块速度,每年产出52560个区块。当只保存block header时,每年新增的存储需求约为4兆字节,100年后累计的存储需求仅为400兆,即使用户使用的是最低端的设备,正常情况下也完全能够负载。