区块链-如何利用Merkle树验证交易(Merkle 树和简单支付验证(SPV))

目录:http://www.javashuo.com/article/p-nitsjfvy-ey.html html

Merkle树:http://www.javashuo.com/article/p-tkkrcntc-bb.html中说明了Merkle树的一些原理以及提到如何证实某条交易是否存在于该区块中。数据库

如今详细的说一下Merkle树怎么验证交易,以及Merkle树与SPV应用。网络

咱们知道,交易数据只是被保存在区块体中,中间的hash值并无被保存,他们只是存在于运算过程当中。区块链

如何在Merkle树种验证交易存在在区块种?

只须要获得经过该交易求出的Merkle root的hash值与该区块的Merkle root hash值同样便可证实该交易是存在该区块种的。.net

固然也就是说咱们只要获得全部交易的,并经过Merkle树生成方式走一遍就能够证实了,可是每个区块中的交易数量达到上千个都是很正常的,若是说咱们按照这种方式进行计算,其计算的次数是很是多的,是很是浪费资源的。htm

在比特币中为了证实区块中存在某个特定的交易,,一个节点只须要计算log~2~(N)个32字节的哈希值,造成一条从特定交易到树根的认证路径或者Merkle路径便可。这使得比特币节点可以高效地产生一条10或者12个哈希值(320~384 字节)的路径,来证实了在一个巨量字节大小的区块中上千交易中的某笔交易的存在。blog

如下引自:https://www.tangshuang.net/4117.htmlci

如何得到认证路径或者Merkle路径

咱们只须要得到认证路径或者Merkle路径就能够简单证实出该交易。实际上,merkle的验证路径生成的前提是已经存在一棵完整的merkle树。市面上有不少merkle树的实现包,有的包直接给出来getProof的方法来获取某个叶子节点的验证路径。也就是说这个路径能够经过引用一些包自动获取。资源

SPV(轻钱包,就是SPV(简化支付验证,Simplified Payment Verification))。轻钱包并不保存完整的区块链,而是只保存每个区块的区块头。区块体保存了完整的交易信息,而交易信息须要的存储量大部分都是交易头的千倍以上。因此,若是只保存交易头,就能够极大的减小本地客户端存储的区块链信息。字符串

可是,不能所以让区块链没法工做啊。若是这个时候轻钱包要对某一个交易进行验证,而本地又没有这个交易的信息,那怎么验证呢?这时,区块头里面的merkle root就要起做用了。

那么对于SPV轻钱包而言,怎么知道一个交易是否真实的呢?SPV拿到一个交易信息以后(好比接收到一笔钱),并不能确认这个交易是否合法,所以要对这个交易的输入进行验证。

如何证实交易的真实性?

比特币网络中的交易,只有已经被记录到区块链,而且已经获得6个确认的,才被认为是真实的,只有基于这些真实交易发起的新交易(输入与输出的概念),才是合法的。

咱们询问一个交易是否真实,每每基于如下前提:

  • 咱们在问一个交易是否已被记录到区块链中
  • 并且这个交易所在的区块链是最长的哪一条,没有在分叉链上
  • 当每一个节点接收到一条交易广播时,咱们要查询做为一笔新交易的输入的真实性
  • 矿工对交易进行打包以前,对全部的输入进行真实性验证(在矿工接收到交易信息时就已经验证过了,打包的时候验证2000条交易信息不可能)

可是它只拿到了单个交易的信息,而没有本地的完整区块链数据,所以,SPV要拿着这个交易的信息向网络发起查询请求,这个请求被称为merkle block message。当其余有完整区块链数据的客户端收到这个请求以后,利用传过来的交易信息在本身的区块链数据库中进行查询,并把验证路径返回给请求源,SPV拿到验证路径以后,再作一次merkle校验,确认无误以后,就认为这个交易是可信的。

在客户端收到merkle block message以后,要执行下面的步骤:

  1. 经过上述方法找到包含该交易的区块
  2. 检查该区块是不是整个网络中最长链条里面的
  3. 取出全部交易生成merkle tree,利用getProof方法获得该交易的验证路径
  4. 将该验证路径发送回请求源

SPV获得响应以后,要作以下验证:

  1. 同步区块链,确保是整个网络中最长的一条
  2. 先拿到merkle root去区块链中查找,确保该merkle root hash是在链条中
  3. 利用拿到的验证路径,再进行一次merkle校验,确保验证路径所有合法

为何SPV还要再作一次merkle校验呢?主要是为了确保响应方发送的验证路径的有效性。

确保验证路径的真实性

上面提到了SPV还要作一次merkle校验,这也是“不信任”的表现之一。咱们并不确保响应咱们的节点不会做弊或欺诈,所以,咱们要本身进行校验。可是,有没有可能虽然校验过程顺利,可是实际上校验路径是伪造的呢?

咱们来作一个假设:1)merkle root为真;2)交易为假;3)路径中的hash可真可假。这个假设是否成立?

咱们知道,不一样字符串碰撞到同一个sha256的几率极小,那么double sha256的几率就是它的平方,而merkle root是通过一层一层计算上来的,若是一个区块只有一个(或2个)交易,那么就是double^(2+1) sha256,而若是是4个交易,就有double^(4 + 2 + 1) sha256,更况且一个区块有那么多交易,要通过merkle运算获得一个相同的hash,几乎是不可能的,所以,在merkle验证中用一个伪造的交易hash来获得一个已知来merkle root是不可能的。

若是还想更进一步校验,能够在区块头中存储区块打包的交易的数量,这样就能够知道从交易hash到merkle root须要通过几层的运算。这也是一个检验点。

小结

merkle tree被普遍运用于区块链中,但并非只有区块链使用它来进行校验。好比一些p2p下载,如迅雷,就须要把文件分割为小块文件,每块都有一个hash,每块从不一样的网络节点下载,最后组成一个完整的文件,可是也须要进行hash验证,它也可使用merkle来进行验证。merkle tree也不必定是二叉树,能够是任意树结构。而在以太坊中,merkle验证还不够用,增长了Patricia Tree验证,合起来称为“Merkle Patricia Tree”。