ETH_16

北大肖臻老师《区块链技术与应用》ETH_16

比特币和以太坊模式不同

比特币:

BTC系统是基于交易的账本,系统中并未显示记录账户有多少钱,只能通过UTXO进行推算。但实际中,使用起来较为别扭。
A转给B钱的时候,需要说明币的来源。实际中只需要存钱说明来源,花钱则不用。此外,账户中的钱在花的时候,必须一次性全部花出去。
转账机制如图所示

以太坊:

以太坊系统则采用了基于账户的模型,与现实中银行账户相似。系统中显示记录每个账户以太币的数量,转账是否合法只需要查看转账者账户中以太币是否足够即可,同时也不需要每次全部转账。同时,这也也天然地防范了双花攻击。
当然,以太坊发这种模式也存在缺点,这种模式存在重放攻击的缺陷。A向B转账,过一段时间,B将A的交易重新发布,从而导致A账户被扣钱两次。
为了抵抗这种重放攻击,引入了nonce(其实应该是number)用来记录交易次数

以太坊系统中存在两类账户:

外部账户:类似于BTC系统中公私钥对。存在账户余额balance和计数器nonce
合约账户:并非通过公私钥对控制。(不能主动发起交易,只能接收到外部账户调用后才能发起交易或调用其他合约账户)其除了balance和nonce之外还有code(代码)、storage(相关状态-存储)

创建合约时,会返回一个地址,知道地址就可以对合约进行调用。

ETH状态树

前言:以太坊中有三棵树,先介绍状态树(和账户余额有关)

数据结构

首先,我们要实现从账户地址到账户状态的映射。在以太坊中,账户地址为160字节,表示为40个16进制数额。状态包含了余额(balance)、交易次数(nonce),合约账户中还包含了code(代码)、存储(stroge)。

思考:直观地来看,其本质上为Key-value键值对,所以直观想法便用哈希表实现。若不考虑哈希碰撞,查询直接为常数级别的查询效率。
但采用哈希表,难以提供Merkle proof(BTC数据结构篇中有对Merkle proof的介绍,还记得是什么吗?)。
那如何组织数据结构呢?
我们能否像BTC中,将哈希表的内容组织为Merkle Tree?

但当新区块发布,哈希表内容会改变,再次将其组织为新的Merkle Tree?如果这样,每当产生新区块(ETH中新区块产生时间为10s左右),都要重新组织Merkle Tree,很明显这是不现实的。
需要注意的是,比特币系统中没有账户概念,交易由区块管理,而区块包含上限为4000个交易左右,所以Merkle Tree不是无限增大的。而ETH中,Merkle Tree来组织账户信息,很明显其会越来越庞大。
实际中,发生变化的仅仅为很少一部分数据,我们每次重新构建Merkle Tree代价很大

那我们不要哈希表了,直接使用Merkle Tree,每次修改只需要修改其中一部分即可,这个可以吗?

实际中,Merkle Tree并未提供一个高效的查找和更新的方案。此外,将所有账户构建为一个大的Merkle Tree,为了保证所有节点的一致性和查找速度,必须进行排序。

那么经过排序,使用Sorted Merkle Tree可以吗?

新增账户,由于其地址随机,插入Merkle Tree时候很大可能在Tree中间,发现其必须进行重构。所以Sorted Merkle Tree插入、删除(实际上可以不删除)的代价太大。

既然哈希表和 Merkle Tree都不可以,那么我们看一下实际中以太坊采取的数据结构:MPT
一个简单的数据结构——trie(字典树、前缀树)

如下为一个通过5个单词组成的trie数据结构(只画出key,未画出value)
如图:在这里插入图片描述

特点:

  1. trie中每个节点的分支数目取决于Key值中每个元素的取值范围(图例中最多26个英文字母分叉+一个结束标志位)。
  2. trie查找效率取决于key的长度。实际应用中(以太坊地址长度为160byte)。
  3. 理论上哈希会出现碰撞,而trie上面不会发生碰撞。
  4. 给定输入,无论如何顺序插入,构造的trie都是一样的。
  5. 更新操作局部性较好

缺点:

  1. trie的存储浪费。很多节点只存储一个key,但其“儿子”只有一个,过于浪费。因此,为了解决这一问题,我们引入Patricia tree/trie
Patricia trie

Patricia trie就是进行了路径压缩的trie。如上图例子,进行路径压缩后如下图所示:
在这里插入图片描述

需要注意的是,如果新插入单词,原本压缩的路径可能需要扩展开来。那么,需要考虑什么情况下路径压缩效果较好?树中插入的键值分布较为稀疏的情况下,可见路径压缩效果较好。
在以太坊系统中,160位的地址存在2^160 种,该数实际上已经非常大了,和账户数目相比,可以认为地址这一键值非常稀疏。
因此,我们可以在以太坊账户管理种使用Patricia tree这一数据结构!但实际上,在以太坊种使用的并非简单的PT(Patricia tree),而是MPT(Merkle Patricia tree)

MPT(Modified Patricia tree)
以太坊中针对MPT(Merkle Patricia tree)进行了修改,我们称其为MPT(Modified Patricia tree)

下图为以太坊中使用的MPT结构示意图。右上角表示四个账户(为直观,显示较少)和其状态(只显示账户余额)
在这里插入图片描述
每次发布新区块,状态树中部分节点状态会改变。但改变并非在原地修改,而是新建一些分支,保留原本状态。如下图中,仅仅有新发生改变的节点才需要修改,其他未修改节点直接指向前一个区块中的对应节点。
在这里插入图片描述

所以,系统中全节点并非维护一棵MPT,而是每次发布新区块都要新建MPT。只不过大部分节点共享。

为什么要保存原本状态?为何不直接修改?

为了便于回滚。如下1中产生分叉,而后上面节点胜出,变为2中状态。那么,下面节点中状态的修改便需要进行回滚。因此,需要维护这些历史记录。
在这里插入图片描述

通过代码看以太坊中的数据结构
block header 中的数据结构

在这里插入图片描述

区块结构

在这里插入图片描述

区块在网上真正发布时的信息

在这里插入图片描述

这块实在没听懂(太难了,哭了),看的别人的笔记!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值