(首先声明部分内容来自网络,加上自己的理解,希望与各位多多交流学习)
Merkle Tree也称作Hash Tree,是存储Hash值得一种树。它的组成分成两类,一类是叶子节点,叶子节点是数据块;另一类是非叶子节点,它们是起串联作用的Hash
对于Merkle Tree的理解,必须了解三样东西:1,.Hash 2.Hash List 3.Merkle Tree
Hash的定义是:把长度任意的数据映射成固定长度数据的函数。这个概念读起来很抽象,但是仔细思考,我们发现它也不是那么难理解。我们可以将其转化成一个包含关系,{a1,a2,...,an}属于A。a1,a2,...,an就相当于一个一个长度固定的数据,而A相当于长度任意的数据的集合。这个转化过程使用Hash运算来实现的,并且转化完成后会返回一个Hash值,用于与公布的Hash值进行比较,如果两个值相等,那么证明数据没有损坏,相反,如果不相等,那么证明数据损坏。(另外,由于Hash值得特性,会导致其反推数据十分的困难,这样保证了一定的安全性,这反面涉及到密码学的东西,我们日后在做详细的说明)
在P2P网络中,我们为了提升下载效率,会从多个机器上面下载数据,在理想状态下我们的下载过程一次可以全部完成,但是可能会存在某些机器存在不稳定的状态,那么它就会导致我们下载过程中的某些部分会存在错误,按照传统的思维方式我们可能要重新对其进行下载了,即使不用重新下载也存在着找不到具体哪一块存在这错误。
就在这个十分焦灼的时刻,我们提出了Hash List的概念,有了这个List表单之后,我们就可以不用下载整个文件了,只需要在对每个数据块的Hash拼接起来,然后对其进行Hash运算,如果失败,根据List表单中的Hash编号,找到确定的数据块,对其进行重新下载就行了,这样大大的提升了我们的下载效率。
从某种程度上面说Hash List就可以看作是一棵默克尔树,首先说明一下其树接口,如下图:
相比较Hash List,这个Merkle Tree更具有灵活性,这个Merkle Tree可以下载完一个分支之后立即进行验证操作,而Hash List只能是在完全下载完成之后进行验证,在验证的效率和便捷性上远远不如Merkle Tree。
下面我们来总结一下Merkle Tree,首先这是个数据结构的树,它具有所有树的一些特点,其次,它的非叶子节点都是一个一个的单元数据Hash,最后它的叶子节点是一个数据块,从上到下利用Hash函数加密得到的。(它跟Hash List最大的不同是,Merkle Tree是利用子哈希的概念,而Hash List就是完全的将所有数据加起来之后进行总和的哈希运算)
首先对底层的数据块(Data Block)进行Hash运算,产生hash块,然后再依次对每个hash块进行串联,一直递归这个过程,直到生成一个唯一的节点,结束Merkle Tree的生成。(画图实在不太方便,这里就用这种语言描述吧)(Merkle Tree的创建复杂度是O(n),树高是log(n)+1)(n表示的是进行的hash运算的次数)
================================
过程其实十分的简单,就是一根节点为标志,自上而下检索。
假设有两个Merkle Tree 为A root和B root,A root下有NodeA1和Node A2两个节点,其两个节点下又有四个类似节点,直到最下面的数据块。
其检索过程是首先A root和B root比较时发现问题(父节点),然后对Node A1和Node B1 以及Node A2 和Node B2(儿子节点)进行比较,然后若发现不同,再依次向下,重复这个过程,直到查找到不同的数据块。
更新删除和插入操作跟树的操作也基本相同,就是注意这里除了叶子节点外,都是比较的Hash值。
对于应用来说,我准备从两方面谈起,一方面是传统应用,另一方面是创新应用
数字签名:数字签名,也称为公钥数字签名,顾名思义,踏实一种类似于写在纸上的物理签名一样的,使用公钥加密技术实现鉴别信息的方法,一个用做签名,一个用作验证。那么有了Merkle Tree我们就可以建造一个拥有多条签名的默克尔签名树,成为一种高效的框架。
P2P网络:P2P:Peer To Peer,即点对点,在我们生活中的种子下载,就是用了这种下载技术,通过Merkle Tree树对每个节点进行Hash运算,讲一个大型的下载分解为一个一个的小规模下载,提升下载速度的同时可以大大提升传输的安全性。
在区块链技术上面的应用,可以说让Merkle Tree焕发了第二春,首先它构成了比特币的基础,因为我们知道,在Bitcoin的一个block中包含prev Hash,Nonce,Timestamp,Merkle Root这四部分,那么如果一个用户想要确认一个交易,那么只需要用Merkle Tree的特性,确定之前的每笔交易的数据,根据Hash运算逐层向上,产生一个最终的值,再让其与公钥进行比较,看看是否一样,一样的话证明交易可以进行,然后产生下一个blcok。
这是在bitcoin上面的应用,那么在现在十分火热的Ethereum上也有很重要的应用,Merkle Proof(默克尔树证明),这里我们引用网上面的一个例子,
#引用
================================
每个以太坊区块头不是包括一个Merkle树,而是为三种对象设计的三棵树:
这使得一个非常先进的轻客户端协议成为了可能,它允许轻客户端轻松地进行并核实以下类型的查询答案:
第一种是由交易树(transaction tree)来处理的;第三和第四种则是由状态树(state tree)负责处理,第二种则由收据树(receipt tree)处理。计算前四个查询任务是相当简单的。服务器简单地找到对象,获取Merkle分支,并通过分支来回复轻客户端。
第五种查询任务同样也是由状态树处理,但它的计算方式会比较复杂。这里,我们需要构建一个Merkle状态转变证明(Merkle state transition proof)。从本质上来讲,这样的证明也就是在说“如果你在根S的状态树上运行交易T,其结果状态树将是根为S',log为L,输出为O” (“输出”作为存在于以太坊的一种概念,因为每一笔交易都是一个函数调用;它在理论上并不是必要的)。
为了推断这个证明,服务器在本地创建了一个假的区块,将状态设为 S,并在请求这笔交易时假装是一个轻客户端。也就是说,如果请求这笔交易的过程,需要客户端确定一个账户的余额,这个轻客户端(由服务器模拟的)会发出一个余额查询请求。如果需要轻客户端在特点某个合约的存储中查询特定的条目,这个轻客户端就会发出这样的请求。也就是说服务器(通过模拟一个轻客户端)正确回应所有自己的请求,但服务器也会跟踪它所有发回的数据。
然后,服务器从上述的这些请求中把数据合并并把数据以一个证明的方式发送给客户端。
然后,客户端会进行相同的步骤,但会将服务器提供的证明作为一个数据库来使用。如果客户端进行步骤的结果和服务器提供的是一样的话,客户端就接受这个证明。
================================
#引用结束