深入探索以太坊世界状态,Part-1
以太坊是由多个组成部分构成的。这篇文章旨在解构以太坊,使你能更深入理解它的数据存储层。我们将介绍区块链中“状态”的概念,并探究帕特里夏前缀树(Patricia Trie)数据结构的理论依据,利用 Google 的 leveldb 数据库来阐释以太坊中前缀树的应用。
什么是区块链“状态”?
比特币的“状态”是通过网络中全局的未使用交易输出(UTXO)来刻画的。比特币网络中价值的传递通过交易来进行,更准确地说,一个比特币用户能使用一个或多个 UTXO 来创建一笔交易,所消耗的 UTXO 将作为交易的输入。
对 UTXO 更详尽的介绍不在本文的讨论范围内,然而在接下来的数个段落中,我们将不断提及这一概念,来指出比特币和以太坊之间基础实现上的差异。
接下来的两个比特币例子将指出比特币 UTXO 模型和以太坊世界状态概念之间的不同之处。
首先,比特币的 UTXO 不能被拆分消耗。如果一个比特币用户想要花费 0.5 个比特币(他手上只有一个价值 1 比特币的 UTXO),他必须显式地将赋予 0.5 个比特币转账地址(转给自己)作为找零。如果他们没有设置自我找零,那么 0.5 个比特币就会作为矿工打包交易的奖励转给矿工。
第二点,在一个最底层的角度来说,比特币并不保存用户的账户余额。在比特币中,用户仅仅在某一给定时间点掌握着一到多个 UTXO 的私钥。尽管数字钱包设计得好像比特币区块链能自动保存和管理用户的余额等等,但实际上不是这样的。
用户的账户余额在比特币网络中是一种抽象的概念,事实上一个用户的余额是他所控制的每一个 UTXO (用户保管着对应的私钥)价值的和。用户所使用的私钥能对每一个 UTXO 进行签名和消费。
UTXO 系统在比特币网络中运行良好,某种程度上要归功于数字钱包能完成绝大多数与交易相关的工作,包括但不限于以下几点:
a) 操作 UTXO
b) 保存私钥
c) 设置交易费用
d) 提供找零地址
e) 统计 UTXO (显示可用余额、转帐中的数额以及总余额)
有趣的是,一个非确定性钱包(如上图中的比特币核心钱包)的备份仅仅提供 UTXO 的快照(在该时间点)。只要用户执行了任何交易(发送或接收),他们所生成的原始备份就过期了。
总结来说,我们知道:
比特币区块链不保存账户余额
比特币钱包保存 UTXO 的私钥
当被包含在某一条交易中时,整个 UTXO 就被使用掉了(在有些找零场景中,原来 UTXO 中的价值会被新的 UTXO 承载)
和上述比特币网络不同,以太坊世界状态已经能管理账户余额以及更多信息了。以太坊中的状态并不是一种抽象的概念,它是以太坊的基础层协议。正如黄皮书 [1] 中所提及的,以太坊是一个基于交易的“状态”机。基于所有交易的状态机概念就这样被构建出来。
让我们从头开始捋一捋,和其他区块链一样,以太坊区块链是由创世区块开始的。从这个起点开始(创世状态在 0 区块高度),诸如交易、合约以及挖矿的活动会持续不断地改变以太坊区块链的状态。在以太坊中,账户余额(存储在状态树中)随每一次交易进行所发生的改变就是这样一个例子。
值得留意的是,像账户余额这样的数据并不直接保存在以太坊区块链的区块中。区块中只保存交易树、状态树和收据树的根节点哈希值。其存储结构如下图所示。
从上图中可以注意到,存储树(所有智能合约数据存储的位置)的根节点哈希实际上指向了状态树,从而间接指向了区块链。接下来我们将深入探讨这一部分更细节的内容。
以太坊中存在两种截然不同的数据类型:永久数据和暂存数据。交易就是永久数据的一个例子。一旦一个交易被确认,它就将永久地被记录在交易树结构中,并且无法篡改。而某一个特定以太坊账户的余额则是暂存数据的例子。账户地址的余额存储在状态树中,并且每当接收到和该账户有关的交易时,该余额都会改变。将挖矿确认后的交易这样的永久数据和账户余额这样的暂存数据分开管理是有意义的。以太坊使用前缀树这种数据结构(上图所示结构)来管理数据,那么接下来我们介绍一下什么是前缀树。
前缀树
前缀树是众所周知用于存储有序字符串的一种数据结构。以太坊特别采用了一种被称为“检索用文字数字编码的信息的实用算法”(Practical algorithm to retrieve information coded in alphanumeric,缩写为 PATRICIA,下文音译“帕特里夏树”)树。帕特里夏树的主要优势在于它简缩的存储。接下来我们对比标准(传统)前缀树和帕特里夏前缀树之间工作原理的不同。
– \0 表示空指针-
在前缀树中添加单词的规则
我们跟随着所加入单词的搜索路径来看。如果我们(在搜索过程中)遇到了一个空指针,就构建一个新节点;当成功将单词加入到前缀树中后,我们再创建一个空指针(终止符)。
当需要加入一个被其他长单词所包含的短单词时,我们就直接把所有的字母放进去并加入一个空指针(终止符)。
从前缀树中删除单词的规则
我们从前缀树中搜索一个表示字符串(我们所要删除的单词)的叶子(分支末端节点)。紧接着删除从叶子末端节点开始直到根节点的所有节点。除非我们遇到了一个有超过一个子节点的节点,否则删完为止。
前缀树中搜索单词的规则
我们依次检索所搜索字符串中的各个字母,直到得到一条完整的路径才停止搜索(在正确的顺序下)。如果在检索完字符串(检索目标)中的所有字母之前就遇到了空指针,那就可以说该字符串并不在该前缀树中。另一方面,如果我们随着检索到达了一个叶子节点(分支末端节点),那么该路径就代表着目标字符串,可以认为目标字符串在前缀树之中。
帕特里夏树
向帕特里夏树添加单词的规则
帕特里夏树将所有的常用字符集合为一个分支。
所有非常用字符都会成为路径上的一个新分支。当要向帕特里夏树添加一个新单词时,我们依次加入所有的字母,然后加入空指针(终止符)。
从帕特里夏树中删除单词的规则
从帕特里夏树中删除单词的规则整体上和传统前缀树一样,不同之处在于删除节点(从叶子节点到根节点)时,我们必须保证所有的父节点都至少有两个子节点。单个子节点只包含字符和一个空指针是允许的(如上图所示,每一个单词末尾都是这种情况)。同样允许一个节点只包含一个空指针(这种情况发生在短单词包含于长单词内)。上图中就体现了“wood”和“wooden”在同一个前缀树中的情形。
值得留意的是,当要从一个前缀树种删除时,路径上不能保留任何只有一个子节点的父节点。如果在删除过程中发生了这种情况,我们需要把合适的字符重新连接起来以解决该问题。这种例子在下图中呈现(从前缀树种删除单词 “word” )。
-从前缀树中删除 “word” 之前-
-删除并重组前缀树之后-
帕特里夏树中的单词搜索规则
在 Patricia 前缀树中搜索单词和标准前缀树一致。
标准前缀树和帕特里夏树之间的相似性
假设 “m” 是我们要添加的字符串的长度, “N” 是可用字母表的大小,将该字符串加入到前缀树的时间复杂度 “O” 为 O(mN)
假设 “m” 是我们要删除的字符串的长度, “N” 是可用字母表的大小,在前缀树中删除该字符串的时间复杂度 “O” 为 O(mN)
假设 “m” 是我们要搜索的字符串的长度,在前缀树中搜索该字符串的时间复杂度 “O” 为 O(m)
标准前缀树和 Patricia 前缀树之间的主要区别
使用帕特里夏树最大的优势在于存储方面。
使用标准前缀树来存储总长度为“M”的字符串的空间复杂度为 O(MN) ,其中 “N” 为可用字母表的大小。
使用帕特里夏树来存储总长度为“M”的字符串的空间复杂度为 O(nN+M) ,其中 “n” 是前缀树中存储字符串的数量,“N” 为可用字母表的大小。
直观来看能发现,两种树的深度显著不同(如上述两图所示)。帕特里夏树的深度更小(更浅),这归因于帕特里夏树将常用的字符组合的能力(并把空指针和叶子节点连接)更强。
以太坊前缀树的深入探究
让我们更深入地探究一下状态、存储以及交易前缀树。
状态前缀树 —— 独一无二
以太坊中有且只有一个全局状态前缀树。
这个全局状态树在不断地更新着。
这个状态前缀树包含了以太坊网络中每一个账户的一组键值对。
这个 “键” 是一个 160 位的标识符(以太坊账户的地址)。
全局状态前缀树中的 “值” 是通过编码以太坊账户中的如下细节来得到的(使用递归长度前缀编码 (RLP) 的方法):
nonce 值
余额
存储前缀树根节点哈希
代码哈希
状态前缀树的根节点(在给定时间点整个状态树的哈希值)是用来确保状态前缀树安全的唯一标志符,状态前缀树的根节点是由整个内部状态树的全部数据来通过密码学手段得到的。
-状态前缀树(用 leveldb 实现的默克尔帕特里夏树(缩写 MPT))和一个以太坊区块之间的关系-
-给定区块中存储的“stateRoot”,这是用 Keccak 256 位哈希算法计算状态前缀树根节点得到的。“stateRoot”:‘0x8c77785e3e9171715dd34117b047dffe44575c32ede59bde39fbf5dc074f2976’-
存储前缀树 —— 智能合约数据的存储
存储前缀树是智能合约数据存储的位置。每一个以太坊账户都有自己的存储前缀树。在全局状态前缀树中保存着存储前缀树根节点的 256 位哈希 storageRoot 值(正如我们刚刚讨论的那样)。
交易前缀树 —— 一个区块一个树
每一个以太坊区块都有着自己的独立的交易前缀树。一个区块往往包括多笔交易,而交易的顺序当然由打包交易的矿工来决定。在交易前缀树中找到一笔交易的路径是通过(RLP 编码方法)检索交易在区块中的索引来得到的。已经被挖矿验证过的区块将永远不会再更新,所以区块中的交易顺序也将固定下来。这就意味着一旦你从区块的交易前缀树中定位到了某一笔交易,你日后就可以通过相同的路径找回它。
原文链接: https://medium.com/cybermiles/diving-into-ethereums-world-state-c893102030ed
作者: Timothy McCallum
翻译&校对: 安仔 Clint & Elisa
稿源:以太坊爱好者(https://ethfans.org/posts/diving-into-ethereums-world-state-part-1)
文章标签: UTXO 以太坊 前缀树 帕特里夏树
深入探索以太坊世界状态,Part-1相关推荐
- 深入探索以太坊世界状态,Part-2
以太坊前缀树的实际示例 以太坊的各个主流客户端使用两种不同的数据库软件来存储前缀树,其中用 Rust 写成的 Parity 客户端使用 RocksDB ,而以太坊的 Go .C++ 以及 Python ...
- 以太坊无状态客户端初探
自从看到了这篇文章,我便一直很想深入了解以太坊的无状态客户端.当然,经过 15 个月的摸索,我对以太坊中的状态.软件.网络的认知都发生了很大的变化,比如说,我现在认为要引入无状态客户端,则硬分叉在所难 ...
- 跟随一笔交易来看以太坊c++客户端源码执行流程 / 源码分析
本文初步分析了一个交易在以太坊内部的处理流程,涉及到交易的接收,检查,执行,同步,区块的构建以及挖矿,结合前面一篇基于黄皮书的理解总结,对以太坊有了更多的认识.因为主要的工作在c++层面,所以这里以c ...
- 细品以太坊的“四棵树”——Merkle Patricia Trie
目录 1. 基础算法 1.1 Merkle Tree 1.2 Trie 1.3 Patricia Trie 2. Merkle Patricia Trie 2.1 节点类型 2.2 Key 定义 2. ...
- 以太坊EVM源码注释之State
以太坊EVM源码注释之State Ethereum State EVM在给定的状态下使用提供的上下文(Context)运行合约,计算有效的状态转换(智能合约代码执行的结果)来更新以太坊状态(Ether ...
- 区块链/以太坊/读书笔记/精通以太坊思维导图
第一章-第三章 学习笔记 思维导图 附:文本结构 精通以太坊-基础1-3章概念基于区块链技术打造的平台智能合约以太坊计算基础框架上执行的程序DApp狭义基于智能合约开发的用户界面至少包含一个智能合约广 ...
- 以太坊创始人V 神:普通人看见现在,天才看见未来
一个时代的天才一定是最懂那个时代的人,而后才能成为点亮时代的光. 作者 | 晋兆雨.Carol 责编 | 徐威龙 普通人看见现在,天才看见未来 25 年前,在俄罗斯一个不起眼的家庭里,一位小小少年来 ...
- 《精通以太坊》预言机
[本文摘自<精通以太坊>一书第11章预言机部分] 在本章中,我们将讨论预言机(oracle),它是可以为以太坊智能合约提供外部数据源的系统. "oracle"一词来自希 ...
- 以太坊原理分析(一)以太坊工作(交易)原理
简介 不管你们知不知道以太坊(Ethereum blockchain)是什么,但是你们大概都听说过以太坊.最近在新闻里出现过很多次,包括一些专业杂志的封面,但是如果你们对以太坊到底是什么没有一个基本的 ...
最新文章
- [architecture]-armv8-aarch64种的SIMD/FP指令介绍
- 自定义PopupWindow弹出后背景灰色状态
- SGU traffic light
- 搜索引擎如何评估外贸网站内容?
- Linux 系统中随机数在 KVM 中的应用
- python试卷生成_小学初中高中试卷自动生成
- Indigo Untyped Channel
- pdf editor android,MaxiPDF PDF editor builder
- 信息系统项目管理师——历年论文题目2012年-2020年
- C语言学习:一个函数可以有几个返回值?
- 牛牛的宝可梦Go(dp+floyd)
- 工作日常记录:整数有符号数除以无符号数的那些事
- Flash builder 4无法调试问题
- whm面板降mysql_WHMCS与Cpanel/WHM面板整合方法-Cpanel/WHM管理使用教程 | 麦田一棵葱...
- 面试加分项,10道海量数据处理,你会几道?
- anaconda打不开解决办法
- javascript 比较两个json数据是否相等
- Guía de Inversión Minera en Argentina阿根廷矿业投资指引
- [原]VC极域电子教室相关功能的实现dll(差不多是“外挂”)
- [oeasy]python0110 屏幕点阵字体_3x5_5x7_雅达利字库
热门文章
- no applicable action for [springProperty] logback异常
- 参加SCRUM中文网CSM认证班的一些感想
- 【敏捷CSM认证】产品负责人(Product Owner)
- Office Online Server搭建(全网最详细)
- vue router中hash模式和history模式的区别
- 特步突围数字化转型--让特步同比增长24.8%的全渠道中台
- js 年月日时间转换
- c++ 内容检索小程序
- Xcode清除缓存、清理多余证书教程(傻瓜版)​
- AMD Mantle与Media SDK的异同