区块链中SPV与Merkle
SPV简单支付验证
Simplified Payment Verification (SPV)(简易支付验证)
由于区块链的分布式存储特性,让每一个人都去运行一个完整的节点不太现实,数据量太大。在中本聪发布的 比特币白皮书 中,针对这个问题提出了一个解决方案:SPV 简单支付验证节点,SPV强调的是验证支付,不是验证交易。这两个概念是不同的。验证支付,比较简单,只需要判断用于支付的那笔交易是否被验证过,以及得到网络多少次确认(即有多少个区块叠加)。而交易验证则复杂的多,需要验证账户余额是否足够支出、是否存在双重支付、交易脚本是否通过等问题,一般这个操作是由全节点的矿工来完成。为了满足这个需求 所以在SPV节点上,不保存全部区块链数据,不下载区块全部交易,只保存区块头数据。请看下图
如果是只保存区块头数据,那数据量就会小的多。那如何验证呢。
Merkle Tree
Merkle Tree,也叫哈希树,是由Ralph Merkle于1979年提出申请的专利。它是一种用做快速归纳和校验大规模数据完整性的树形数据结构。
再上图中区块头中存储一个名为Merkel根的字段,它是由区块体中每两个交易数据的Hash产生一个上层Hash值,直至剩余一个称之为根Hash.如果仅有奇数个交易需要归纳,那最后的交易就会被复制一份以构成偶数个叶子节点,这种偶数个叶子节点的树也被称为平衡树。
当SPV需要去验证一比交易的输入是否有效时(是否已打入到区块链中),由于SPV本地没有存储每个区块的详细交易数据,需要去网络上找到全节点验证。假如需要验证上图中第6个交易,SPV会将第6个交易的Hash值发送给全节点,全节点会在本地找到这笔详细交易和所在的区块。将认证路径反馈给SPV节点。
所谓的认证路径就是 SPV节点拿自己已知的的值与全节点返回的值 计算出Merkle根值,在自己本地节点 查找是否有包含该值的区块 确认这笔交易的输入当前是否有效。
计算过程:
5 + 6 计算出56
56 + 78 计算出5678
1234 + 5678 计算出 12345678(根节点)
根据最终计算出来的值,SPV 会在本地寻找 与之对应的值是否存在。如果存在就能定位到值所在的区块距离最新的区块的高度是多少。也就是本次交易的输入确认过几次。
Java 实现Merkle
已实现 Merkle tree树的组成,获取认证路径,重新计算Root根值。
代码地址 https://github.com/544845389/Merkle_Tree_Demo
效果: