您的位置:首页 > 大数据 > 人工智能

Merkcle Tree

2016-12-01 21:48 253 查看

问题

区块链本质上就是一个分布式的账本,每个区块记录了一定时间内的所有交易,比如比特币是讲每10min内的所有交易合成一个区块,放在总链上,交易成百上千,并且区块分布存储在不同的节点上,我们并不是每次都从某个受信任的源得到整个区块,于是我们面临两个问题:

1 如何确定我得到的区块是否被篡改过?

2 如何快速确定某交易是否存在于区块?

Merkle Tree

SHA

安全散列算法SHA(Secure Hash Algorithm)是美国国家安全局 (NSA) 设计,美国国家标准与技术研究院(NIST) 发布的一系列密码散列函数,包括 SHA-1、SHA-224、SHA-256、SHA-384 和 SHA-512 等变体。主要适用于数字签名标准(DigitalSignature Standard DSS)里面定义的数字签名算法(Digital Signature Algorithm DSA)

快速检测两个文件是否相同常用的办法是计算SHA256值,本质上SHA256就是一个hash值,文件内部的任何更改都会导致SHA256的变化,文件可能很大,但SHA256只有256bit,比较操作可以瞬间完成

hash list



容易想的解决方案是将所有的交易分别计算hash然后串起来再算一次hash,这个hash作为单独的节点,我们只要比较一个top hash 就可以检测节点是否可信,可是依然有问题:

1 如何定位被修改的交易?

2 当文件是分块传输的,当文件没有完全传输完毕,如何得知已经下载的文件块是正确定?

merkle tree

merkel树可以很漂亮的解决以上问题



merkle tree中的指针并不是传统的内存地址,而是一个hash,也就是说,节点的信息即值也是地址

首先,树的叶子是每个区块的hash值 ,比特币用的是双SHA256,即

hashL1 = SHA256(SHA256(L1))


然后每两两交易的hash直接拼接成一个512bit的串,然后再次计算hash,即

hash0 =  SHA256(SHA256(L1+L2))


从底至上,如此往复,直到计算出一个根

在我们讨论merkel树的优点之前,先解决一个问题,图中的树看起来很完美,一个完全二叉树

但是,节点数很难刚好就是2^n个,这里有三种解决方案:

1 每层计算时,首先判断当前层的节点是否是偶数,如果不是,那么讲最后一个节点复制,添加在尾部,凑成偶数

2 类似哈弗曼树,建立一个列表,从表头取两个节点,计算hash 然后压入表尾,直到表空

3 将不足2^n的节点序列直接复制最后一个节点直到正好达到2^n个

从二叉树的性质可以看出,显然以上3中方法虽然添加的节点数目不同,但是树的高度都在数量级,整个数据结构的空间占用也在3N以内

与hashlist同样,merkel树也可以快速做信任检测

树根由所有节点一步步hash生成,那么树根就成了整个树的签名,跟hashlist一样,树种任何一个节点的任何一点改动都会引起根hash的变化,如此一来,我只需要在信任的源获取根hash,就可以快速检测自己的整个区块是否正确

merkle树的优势在于,可以在log2N的时间复杂度下判断一个节点是否正确(交易是否存在),当节点发生变化时定位该节点

节点检测

我手里有L2这个节点,我只需要L1 hash1两个点就能计算出树根hash,再与可信任的根hash比较,就可以确定节点是否正确,这点在hashlist里完全做不到,hashlist需要所有其他节点

修改定位

如果L2节点遭到篡改或失效,我只需要tophash、hash1 、hash0、hashl1、hashl2就可以定位,此处看起来检测了几乎所有节点,实际上,当树非常大的时候,我只需要检测一个分支以及兄弟子树的根,显然,这也只需要Log2N的时间复杂度

总结

merkel树具有安全、迅速、复杂度可控等优势,在区块链中有非常重要的应用,但是也有缺点–功能太少,比如,我想知道此次交易的详细信息呢?merkel树无能为力,以太坊在此基础结合前缀树开发了MPT,增加了很多有意思的新功能,下篇我们将详细讲解MPT
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法 hash blockchain