BITC:Turboproof 证明系统初探_ITC

编者按:本文来自以太坊爱好者,作者:GuillaumeBallet,翻译&校对:TrumanW&阿剑,Odaily星球日报经授权转载。以太坊的状态数据正不受限制地快速增长,长此以往,将只有少数大型公司才能负担运行节点的成本。应Alexey的要求,本文描述了我对turboproof证明系统的理解,该技术未来有可能会应用在多种轻客户端上。以太坊区块链的状态数据使用十六叉帕特里夏树来存储的。数据存储有两个层次:地址树是从地址到账户数据的映射。智能合约的数据也存储在一棵数据树中,该树就是由从32字节内存地址到32字节的值的映射构成的。这些默克尔树存储对。请注意,键的基本单位是半字节,而不是一个字节。这些默克尔树具有3种类型的节点:叶子节点:这些是对,它们始终是默克尔树的终端节点。分支节点:内部节点,并且此节点及其所有子节点共享相同的前缀。每个分支节点有17个条目。前16个条目对应于子节点的键后缀的第一个半字节。如果存在,则第17个条目是与键前缀关联的值。扩展节点:“捷径节点”,让所有子节点共享一个公共前缀。有了扩展节点,就不会建出很多只有一个叶子的分支节点了。举个例子,以下的树有一组叶子节点,分支节点以及扩展节点:

-图1.一个Trie编码以下键值对:,,和。在此示例中,键和值已缩短为2个字节,以提高可读性。标签为0到15的行表示分支节点,延伸出来的箭头所指的半字节是其子节点的前缀。第17个条目未使用,因此未显示。的那一行是扩展节点,这意味着其子节点必须以这两个半字节为前缀。终端节点是叶子,左边的两个具有前缀,右边的两个不需要前缀,因为根据指向它的路径就能得到完整的键。-在实际应用中,这个模型是以太坊很多效率问题的根源,但是它也被证明有很强的韧性。序列化值

一些用例需要在用户之间传递元组。例如,为了节省空间,轻型客户端仅存储各默克尔树的根。因此,为了与状态进行交互,用户需要告诉轻客户端自己的状态是什么样的,以便轻客户端可以执行操作并计算新的状态根。为压缩数据,该建构必须能够将多个账户的状态变化打包成单个证明。在前面的示例的基础上,这是树中同时存在和的证明:

-图2.证明图1中的树包含和。除了这两个值以外的子树所存储的值都用原值相应哈希值替代。。-只要在该证明中提供的哈希值就是原值的哈希值,那么根据图2中的信息计算出的树根哈希值将与图1中的树根哈希值一致。问题是如何序列化数据:给定一个哈希表列表和对列表,人们如何找出树的结构?例如,仅给出以下输入:和的对表示子树的哈希值。人们可能重建出下面这棵树:

-图3.因为缺少结构信息而建出的错误数据树-也可能建出下面这样的数据树:

-图4.另一棵因为缺乏结构信息而产生的错误数据树-因此,我们需要编码结构信息的方法。Turboproof

AlexeyAkhunov的提案仍在制定中,而我这篇独立的文章也想略尽绵薄,为定义整个概念做点工作。这里介绍的解决方案与我和SinaMahmoodi合作的rust实现相对应。Turboproof分为三个部分:叶子节点的清单哈希值的列表,与树的原始分支一一对应“结构信息”,即仅使用提供的哈希和叶子如何重建树的指令列表。为能重建出正确的数据树,最后一部分被编码为供堆栈器执行的一系列指令:LEAF表示应从证明的叶子序列中弹出一个叶子节点;BRANCH规定需要创建一个新的分支节点,并且之前构造的节点应存储为新分支节点的第i个子节点。然后将新节点存储在堆栈中;ADD规定,应将堆栈顶部的节点设置为堆栈上位于其下方的分支节点的第i个子节点;EXTENSION规定应将堆栈顶部的节点设置为扩展节点的子节点,整个子树的前缀由半字节ext的序列表示;HASH是表示子树哈希值的节点。一些例子

假设整个状态由以下4个对组成:

这些键值对所组成的数据树表示如下:

-图5.初始数据树-证明

我们的证明将是针对两个键0xcafecafe和0xcafedeca的。不需要用到的两个叶子节点将被转化为哈希值。然后将证明序列化为:节点以深度优先的顺序序列化:

-图6.证明的节点部分-哈希也按深度优先顺序进行序列化。只有一个哈希值,代表0xd*子树用于重建树的指令集:

用户现在可以证明他们知道树的当前状态。他们可以将证明发送给中继器或任何想要确保用户知道他们自己状态的人。重建树

一开始,节点和哈希列表被接受,接着堆栈被初始化为空。

-图7.重建树过程的初始状态-让我们跟随这个程序。1.LEAF

-图8.第一个叶子节点被推入堆栈-2.LEAF

-图9.两个叶子节点都在堆栈中-3.BRANCH(14)

-图10.将序列中的节点设为分支节点,然后弹出堆栈顶部的节点,将后者设置为前者的第14个子节点。如此组成的子树随后立即被推入栈顶。-4.ADD(13)

-图11.弹出堆栈顶部的两个元素,并添加第二个元素作为第一个元素的第13个子元素。结果被推回堆栈。-5.EXTENSION()

-图12.将序列中的节点设为扩展节点,扩展节点的前缀为“0xafe”,然后栈顶的元素成为该扩展节点的子节点。完成操作后,整个子树被推回堆栈。-6.BRANCH(13)

-图13.将序列中的节点设为分支节点,并让栈顶的元素成为其第13个子节点。结果再次被压入堆栈。-7.HASH

-图14.哈希从证明的哈希列表中提取并推入堆栈的顶部。-8.ADD(14)

-图15.栈顶的哈希值被添加为树的第14个子节点。-该程序至此终止,并且堆栈的顶部存有树的最终版本。该树与图6中的树具有相同的根哈希,并且很简单就能验证两个键均存在。Turboproof的意义

以太坊状态数据正在增长。在撰写本文时,状态数据已增长到约占20GB。对于手机来说,这个量级已经太大了。想让所有人都能访问网络,就必须保证不那么强大的设备也能访问网络。有了这样的证明方式,用户就可以只存储他们感兴趣的数据,并在他们想与区块链进行交互时证明所有权。这就是所谓的轻客户端。想深一步,人们可以构想用这种“无状态”的方式来维护主链,用户只需保存链上状态中跟自己有关的部分,并在需要时发布这些信息。这将有助于阻止状态所需空间的持续增长,并使所有人都能使用以太坊。为了使证明尺寸较小并能快速处理,仍需要做一些工作,好在让它们变得更加普及也会有助于我们的工作。致谢仰赖于AlexeyAkhunov和SinaMahmoodi的投入和反馈,这篇文章才得以写就。

郑重声明: 本文版权归原作者所有, 转载文章仅为传播更多信息之目的, 如作者信息标记有误, 请第一时间联系我们修改或删除, 多谢。

区块博客

[0:15ms0-4:342ms