ETH——交易树和收据树

区块链技术 专栏收录该内容
19 篇文章 0 订阅

以太坊中还有另外两棵树:交易树和收据树。

每次发布一个区块的时候,这个区块里所包含的交易会组织成一个交易树,也是一颗Merkle tree。同时以太坊还增加了一个收据树,每个交易执行完之后会形成一个收据记录这个交易的相关信息。交易树与收据树上面的节点是一一对应的。增加这个收据树主要是考虑到了以太坊的智能合约比较复杂,所以通过收据树的结构有利于我们快速查询一些执行的结果。

从数据结构上将,交易树与收据树都是MPT,与比特币中的交易树有所区别,比特币中的交易树就是普通的Merkle tree。

MPT的一点好处是支持查找操作,通过键值从顶向下沿着树进行查找即可。对于状态树来说,查找的键值就是这个账户的地址,对于交易树和收据树的键值为交易在发布的区块中的序号,交易的排列顺序是由发布区块的节点决定的。

三棵树的区别:
交易树和收据树只将当前区块中的交易组织起来,而状态树将所有账户的状态都包含进去,无论这些账户是否与当前区块中交易有关系。
多个区块状态树共享节点,而交易树和收据树是独立的,他们是不共享节点的。

交易树和收据树的用途:

  1. 向轻节点提供Merkle Proof。证明某个交易被打包到某个区块里面了。
  2. 更加复杂的查找操作(例如:查找过去十天当中所有跟某个智能合约有关的交易;过去十天的众筹事件等)

Bloom filter
支持较为高效查找某个元素是否在某个大的集合中。例如某个很大的集合,要知道有没有我要想查找的元素。
最笨:元素遍历,复杂度为线性的,O(n)——轻节点不能用
方法:给一个大的集合,通过计算每个元素的哈希值,出一个紧凑的“摘要”,可以较为便捷的查找是否在集合中。

例:给定一个数据集,其中含义元素a、b、c,通过一个哈希函数H()对每一个元素进行计算,将每一个元素取哈希之后映射到一个初始值全为0的向量中的某一个位置。然后映射到位置的向量的元素由0变为1。所有元素都处理完了,就可以得到一个向量,这就成了这个集合的digest(摘要)了。
在这里插入图片描述

假定想要查询一个元素d是否在集合中,假设H(d)映射到向量中的位置处为0,说明d一定不在集合中;假设H(d)映射到向量中的位置处为1,有可能集合中确实有d,也有可能因为哈希碰撞产生误报。

Bloom filter特点:有可能出现误报,但不会出现漏报。
bloom filter有各种变种,有的不是用一个哈希函数,有的使用一组哈希函数。每个哈希函数独立的把元素映射到向量中的某一个位置,用一组哈希函数的好处是,一般来说,当某一个哈希函数出现碰撞的时候,不会所有的哈希函数都出现哈希碰撞,这样就可以有效解决误报问题。

如何集合中删除元素该怎么操作?
无法操作。也就是说,简单的Bloom filter的局限性是不支持删除操作。如果想要支持删除操作,需要将记录数不能为简单的二进制0和1,需要修改为一个计数器,记录这个位置有多少个元素映射过来,而且还要需要考虑计数器是否会溢出。这样的设计复杂的太多了,与当初设计bloom filter初衷相违背的。所以一般来说,bloom filter不支持删除操作。

以太坊中Bloom filter的作用
每个交易完成后会产生一个收据,收据包含一个Bloom filter记录交易类型、地址等信息。在区块block header中也包含一个总的Bloom filter,其为该区块中所有交易的Bloom filter的一个并集。
所以,查找时候先查找哪一个区块的块头中的Bloom filter中有我需要的类型,如果块头bloom filter里面没有我们想要的话,就可以确定这个区块不是我们想要的。如果块头bloom filter中包含,再查看区块中包含的交易所对应的那些收据树里面的Bloom filter,看看哪个有,也可能都没有,因为有可能是false positive,如果存在,将查看交易直接进行一下确认。
好处是通过Bloom filter这样一个结构,快速大量过滤掉大量无关的区块,从而提高了查找效率。

以太坊的运行过程,可以视为交易驱动的状态机(transaction-driven state machine)。这个状态机的状态就是所有账户的状态,即状态树中包含的那些内容,交易就是每次发布的区块里包含的那些交易,通过执行这些交易会驱动系统从当前状态转移到下一个状态。
BTC我们也可以视为交易驱动的状态机,其状态为UTXO,没有被花掉的那些输出。
以太坊与比特币状态有一个共同特点,状态转移是确定性的。对于给定的当前状态和给定一组交易,可以确定性的转移到下一状态(保证系统一致性)。

问题1:A转账到B,有没有可能收款账户不包含再状态树中?
可能。和比特币系统一样,因为以太坊中账户可以节点自己产生,只有在产生交易时才会被系统知道。
问题2:可否将每个区块中状态树更改为只包含和区块中交易相关的账户状态?(大幅削减状态树大小,且和交易树、收据树保持一致)
不能。首先,这样设计的话,每个区块没有一颗完整的状态树,只有当前区块所包含的交易涉及到的状态。这样会产生一个问题,要查找账户状态很不方便,因为不存在某个区块包含所有状态。
其次,如果要向一个新创建账户转账,因为需要知道收款账户的状态,才能给其添加金额,但由于其是新创建的账户,需要一直找到创世纪块才能知道该账户为新建账户。

具体代码讲解在视频后半段:https://www.bilibili.com/video/BV1Vt411X7JF?p=17

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值