1. 什么是默克尔树:
为了使的用户能够确信,Poloniex拥有每一个用户的真实并且完整的账户数据,我们尝试构建了默克尔树,运用默克尔树,可以使的我们所有的用户独立而确真的验证他们对应的财产是完整无二的存储于Poloniex平台中,而又不需要泄漏其他任何用户的任何信息。用户无需第三方机构的介入,只需要下载自己所特有记录的id哈希以及默克尔根和证明路径就可以证明他们的财产是由Poloniex 1:1所持有的。
默克尔树 (Merkle Tree) 是 Ralph Merkle 于 1979 年提出并以自己名字命名的一种资料结构。默克尔树是比特币和以太坊等加密货币常用的资料结构。透过默克尔树,多个资料可以合併成一个资料,并且能储存较大规模的资料汇总结果,同时还可以透过密码学的手段证明相应的资料压缩在汇总结果中。透过验证默克尔树树根的资料完整性,可以证明构成默克尔树的所有资料完整性。默克尔树的树叶部分,是由资料集中所有资料的杂凑值所构成。具体而言,树叶构造会连接两个相邻的杂凑对,群组在一起后再次进行杂凑处理并产生母杂凑值。重複进行的群组和杂凑过程,最后产生顶层根杂凑,也就是默克尔树根 (Merkle Root)。默克尔树根的杂凑值包含整棵默克尔树所有资料的杂凑值,篡改或改动任何节点的资料都会导致默克尔树根杂凑值改动而有完全不同的值,因此可以保证默克尔树的资料完整性。
简单来说,默克尔树得名于其发明者拉尔夫默克尔,密码学中是很常用的数据结构,能够用于去实现验证大量数据完整性,而又不透露额外信息。其能够将各种数据形式表现为一种无法反解的哈希值,每个用户可以得到他们自己的用户证明,其中包含默克尔证明中的证明路径以及默克尔根,以及用户哈希,于是用户可以利用默克尔树的属性验证他们个人用户的信息以及财产是否包含在Poloniex的财产信息之中。同时结合零资产证明中的默克尔相关电路约束所构成的储备金证明,用户可以验证Poloniex的交易所财产(也就是所有用户财产数据)是由每一个用户数据计算准确无二计算得到的,这样用户可以知晓自己的财产由Poloniex所持有,且按照1:1的比例保证拥有对应每一个用户的储备金。简单来说,用户通过默克尔树,可以确保自己的所有财产信息准确无二的
2. 默克尔树升级:
我们采用了默克尔树v2.0机制来作为百分百储备金的验证证明。
在此之前我们验证的主要流程为:
1.对所有用户的余额进行匿名快照产生默克尔树,默克尔树包含了交易所所有用户持有资产的加密资料
2.从默克尔树最后一个节点取得默克尔树根,从默克尔树根可以取得快照时的单一杂凑值(合并所有交易的杂凑值)及资产总余额
3.验证Poloniex链上钱包地址的数位签名,证明地址的所有权,并取得可公开核对的资产总余额。
4.最后,透过比对和链上钱包地址中的总余额是否大于默克尔树所显示的资产总树,证明用户资产受100%储备金支撑,展现Poloniex对用户资产的兑付能力。
升级:
我们将原始的默克尔树升级为了稀疏默克尔树,其庞大的树构成以及多空哈希根所具备更强的容错性,此外较大的树,能够容纳更多的用户。我们从原版本的五种币种种类升级为了200种币种种类,此外增加了用户总正资产以及总负债,用于同时哈希的计算。按照此规则构成的稀疏默克尔树能够保证用户每一个节点的独特性,并且能够完全的囊括用户相关的所有财产。关于稀疏默克尔树的详细内容下述。
如何针对单用户进行默克尔证明:
用户可以从交互端,核对uid并下载属于自己的独特的userproof证明文件。用户下载验证端,读入自己的userproof文件就可以进行用户的默克尔证明,验证自己的所有财产信息是确真为我们所拥有的。
用户userproof文件构成:
包含该用户对应稀疏默克尔树中的索引位置,uid加密后的id哈希以及全部币种财产信息,根哈希,和对应该用户的证明路径。利用其中的财产信息和id哈希重新计算叶子结点哈希,结合其中验证路径哈希,就可以计算并比对最终的根,完成默克尔证明。(图解形式)
3. 稀疏默克尔树
相比于之前的版本我们升级了我们的默克尔树版本为稀疏默克尔树的v2.0版本,
图 1
稀疏默克尔树的大小是预先设定好的,并且每个叶子结点保存在稀疏默克尔树的时候,空结点是无需存储的。这也就意味着我们只需要存储已经设置好的用户结点。如图1示
其优势具体包括:
- 强扩展性:随着数据量的增加,传统默克尔树的高度可能会增加,导致验证所需的计算量也增加。稀疏默克尔树可以通过将空的分支合并来减少树的高度,从而在某种程度上提高了验证的效率和可扩展性。
- 可动态更新: 相较于一半的默克尔树如果需要更新数据,就需要重新计算整个树的哈希值。稀疏默克尔树可以更加高效地支持动态数据的插入和删除,只需要更新叶节点和一小部分中间节点的哈希值,而不需要重新构建整个树。
- 快速验证: 稀疏默克尔树的结构使得可以在某些情况下更快速地验证数据的完整性,因为不需要逐层遍历整个树。
- 利用我们上一步计算得到的叶子哈希,并确定我们要添加叶子结点的索引位置,就可以将用户添加到稀疏默克尔树之中。并根据用户的索引位置就可以得到此用户的证明路径,用于验证该用户是否确真的位于树的构成中,保存了您的财产数据)
4. 叶子结点是如何构成的?
什么是hash256计算?
对于任意长度的消息,SHA256都会产生一个256位的哈希值,这一哈希值相当于是个长度为32个字节的数组,通常有一个长度为64的十六进制字符串来表示,其中1个字节=8位,一个十六进制的字符的长度为4位。
例如,对于消息:
经过Hash256,即能得到一个长度为64的16进制值:
3a6fed5fc11392b3ee9f81caf017b48640d7458766a8eb0382899a605b41f2b9
而该哈希值就能够保证单向(未知原始消息无法反向计算得到哈希值)且避免碰撞(不同消息难以出现重复的哈希值)这两大特点,
- 叶子结点的构成
我们首先进行uid的加密计算获得对应每个用户id哈希值:
图 2
利用hashID这一独一无二的标识就可以查询到每个用户独特的财产以及个人信息,且hash256不存在线性时间反算求解的可能,这就意味着不可能有其他人有手段能够暴力计算出用户自己的hashID(除非这个人知晓您的Uid)。
更进一步,用户的叶子结点的哈希值,是通过hashID以及所有币种信息财产承诺加之用户的总资产和总负债计算得到,这就确保了,这一独一无二的hash本身是包含用户的所有账户信息的。
这一计算过程您可以从图示中理解:
图 3
- 为什么hash不会出现重复的情况?
由于每个用户的uid是独一无二的,所以每个用户的hashID也必然是独一无二的,在绝大部分情况中,不同用户之间的所有财产相关的账户信息是很难完全相同的,因此,其哈希值完全相同的概率也是极其小的,再加之hashID所保证的独特性,每个账户的账户ID是不太可能出现相同的情况的。
- 为什么其他用户不能得到您的哈希值?
SHA-256的核心安全属性之一是抗碰撞性(collision resistance),这意味着找到两个不同的输入,它们产生相同的哈希值是非常困难的。从哈希值反推出原始输入,涉及到找到满足哈希值的所有可能输入。这被称为“逆映射”或“逆哈希”,但在目前的计算环境下,由于哈希函数的设计目标是阻止逆向计算,要实现逆向计算SHA-256是非常困难的。因此其他人只有完全掌握您的账户属性以及uid才可能获得您的哈希值。