主页 > imtoken官网下载教程 > 以太坊分析:默克尔树、世界状态、交易等

以太坊分析:默克尔树、世界状态、交易等

imtoken官网下载教程 2023-02-11 07:27:54

默克尔树

在以太坊的主要数据对象之前,先给大家简单介绍一下什么是默克尔树,使其起到属性特征数据库的作用

假设世界状态和交易由自定义 Merkle-Patricia 树维护。编程

在 Merkle 树中,叶子节点保存块数据的哈希值,而非叶子节点保存其子节点的哈希值。数组

以太坊联盟和以太坊的关系_以太坊究竟是什么_以太坊经典和以太坊

-Merkle树网络示意图(包括节点和节点之间的关系)

Merkle 树指向的数据的任何变化都会引起节点哈希值的变化。 因为每个父节点中保存的哈希值依赖于子节点中包含的数据,所以子节点中数据的变化会引起父节点哈希的变化。 而这样的影响是一个连锁反应,从叶节点到根节点。 因此,叶节点指向的数据发生变化,就会引起根节点存储的哈希发生变化。从以上结构特征,我们可以推导出两个重要的属性:分布式

在判断两棵Merkle树指向的数据是否完全相同时,我们不需要比较每个叶子节点,只需要比较根节点存储的hash即可。学习

在确定某条数据是否被树指向时,我们可以使用 Merkle 证明技术。 无需在此详细介绍该技术,只要知道这是一种验证数据是否存在于 Merkle 树中的简单而有效的方法。区块链

第一个属性重要的是,我们可以只用根节点的哈希值来标记某一时刻整棵树指向的数据。 这意味着只需要保存根节点的哈希值就可以标记区块(无需存储区块链中的所有数据),数据不可篡改。 温泉

至此,我们已经明确了根节点哈希在默克尔树中的作用。 下面介绍一下Ethereum.design中的主要对象

世界状况

世界状态是地址(账户)到账户状态的映射。 虽然世界状态没有存储在区块链上,但在黄皮书的描述中,世界状态也是由一棵树保存的(这棵树也叫状态数据库或状态树)。 世界状态可以看作是一个全局状态,随着交易的执行而不断更新。 以太坊就像一台去中心化的计算机,世界的状态就是这台计算机的硬盘。log

以太坊中的所有账户信息都反映在世界状态中,并由世界状态树保存。 如果你想知道一个账户的余额,或者智能合约的当前状态,你需要查询世界状态树来获取账户的具体状态信息。 我还将在下面简要描述这些信息是如何存储的。

以太坊联盟和以太坊的关系_以太坊究竟是什么_以太坊经典和以太坊

-世界状态树和账户存储-

帐户状态

以太坊中有两种类型的账户:外部拥有账户(EOA)和合约账户。 我们用来互相收发以太币和部署智能合约的账户就是EOA账户以太坊究竟是什么,部署智能合约时自动生成的账户就是合约账户。 每个智能合约都有其独特的以太坊账户。

账户状态反映了以太坊账户的各种信息。 例如,它存储当前账户的以太币余额信息,当前账户发送的交易数量……每个账户都有一个账户状态。

以下是您的帐户状态中包含的内容:

随机数

该地址未来发送的交易数量(如果当前是EOA账户)或者该账户产生的合约创建操作(暂且不管合约创建操作是什么)。

平衡

该账户拥有的以太币数量(以 Wei 为单位)。

存储根

account store树的根节点的hash(后面是account store)。

代码哈希

对于合约账户,这是存储 EVM 代码哈希的账户。 对于 EOA 帐户,将此留空。

帐户状态中不应忽视的一个细节是所有对象(包括上述对象)都是可变的(codeHash 除外)。 例如,当一个账户向另一个账户发送以太币时,除了增加 nonce 外,该账户的余额也会相应发生变化。

codeHash 的不变性使得一旦部署有漏洞的智能合约就无法修复和更新。 相应地,只能部署一个新合约(易受攻击的版本将始终存在于区块链上)。 这就是为什么有必要使用 Truffle 进行智能合约开发和部署,并在使用 Solidity 编程时遵循最佳实践。

帐户存储树是一种保存与帐户关联的数据的结构。 此项仅适用于合约账户,在EOA中,storageRoot留空,codeHash为空字符串的哈希值。 所有智能合约数据以 32 字节映射的形式存储在账户存储树中。 账户状态树如何维护合约数据这里不再赘述。 如果读者对其内部实现感兴趣,强烈推荐阅读本文。 账户状态中的storageRoot字段负责维护账户存储树根节点哈希。

以太坊联盟和以太坊的关系_以太坊究竟是什么_以太坊经典和以太坊

-账户状态和账户存储树-

贸易

事务推进从当前状态到下一个状态的转换。 以太坊中存在三种类型的交易:

在 EOA 之间转移价值的交易(例如,改变发送者和接收者的余额大小)。

发送消息以调用合约的交易(例如,通过发送消息调用来触发 setter 方法以在合约中设置值)。

用于部署合约(从而建立合约账户)的交易。

(从技术上看,前两笔交易是一样的……都是通过消息调用改变账户状态的交易,只是一个是EOA账户,一个是合约账户。这里,交易分为三种,方便读者理解。)

一个事务由以下部分组成:

随机数

该账户发出的交易号数(校对注:可以大致理解为“这是该账户的第一笔交易”)。

汽油价格

在执行此交易、执行计算时每单位天然气支付的费用(以 Wei 为单位)。

气体限制

执行此交易时可以使用的最大气体量。

价值

v, r, s

交易加密签名中使用的值,可用于识别交易的发送方。

数据(仅用于价值传输和向智能合约发送消息)

消息调用附带的输入数据(比如你要执行智能合约中的setter方法,数据区要包含setter方法的标识和你要设置的参数值)。

init(仅用于合约创建)

用于初始化合约的 EVM 代码。

暂时不要想着消化这些概念……你必须对以太坊的内部机制有更深入的了解,才能真正理解和使用data area和init area等概念。

信不信由你,区块中的所有交易也存储在 Merkle 树中。 而这棵树的根节点的hash值就是由区块头保存的! 我们来分析一下以太坊的区块结构。

堵塞

一个区块分为区块头和区块体两部分。

区块头是以太坊区块链的一部分。 它保存了前一个区块(也称为父区块)的哈希值以太坊究竟是什么,通过区块头链接形成密码学背书的链。

区块体包含记录在该区块中的一系列交易,以及叔块(ommer)区块头的列表。 如果你想了解更多关于叔块的知识,我推荐阅读这篇文章。

以太坊联盟和以太坊的关系_以太坊究竟是什么_以太坊经典和以太坊

-以太坊区块抽象示意图-

下面介绍一下区块头包括哪些部分。

父哈希

前一个区块的区块头哈希。 每个区块都包含之前区块的哈希值,一直追溯到链上的创世区块。 这也是维护数据不被篡改的结构设计(任何对前一个区块的篡改都会影响后续所有区块的哈希值)。

哈希表

叔块头和部分块体的哈希值。

受益人

通过挖掘该区块获得收入的以太坊账户。

状态根

世界状态树根节点的哈希值(在所有交易执行后)。

交易根

交易树根节点的哈希值。 这棵树包含了区块体的所有交易。

收据根

每当执行交易时,以太坊都会生成与结果对应的交易收据。 这是交易收据树根节点的哈希值。

原木绽放

Bloom filter 用于判断某条日志是否已经被某个区块中的事务生成(如果你对这方面感兴趣,可以参考Stack Overflow上的这个答案)。 这避免了将日志信息存储在块中(节省了大量空间)。

困难

该区块的难度值。 这是衡量当前区块挖掘难度的指标(这里不介绍这个概念的细节和计算)。

数字

前导块的总数。 这表示区块链的高度(即区块链上有多少块)。 创世块的编号为0。

气体限制

每笔交易都需要消耗gas。 gas limit 表示该区块记录的所有交易可以使用的gas总量。 这是一种限制区块内交易数量的方法。

使用的气体

区块中每笔交易实际消耗的gas总量。

时间戳

区块创建时的 Unix 时间戳。 请记住,由于以太坊网络的去中心化特性,我们不能相信这个值,尤其是在编写涉及与时间相关的业务逻辑的智能合约时。

额外数据

可以输入任何内容的可变长度字节数组。 当矿工构建区块时,他们可以在这个区域添加任何东西。

混合哈希

用于验证一个区块是否真正被记录在链上的哈希值(如果你想真正理解这个概念,推荐阅读这篇文章 Ethash 工作量证明函数)。

随机数

同mixHash,用于验证区块是否真实记录在链上的值。

哎呀……说起来嘴巴都酸了……建议大家别着急,慢慢来! 但我想再次强调,阅读这篇文章的目的不应该是记住每一个名词及其作用(你可以在谷歌上找到这些)。 我写这篇文章的初衷是想通俗易懂(至少比黄皮书简单)来介绍以太坊对象的方方面面,帮助新手理解那些专业术语的含义。 只需将本文视为“以愚蠢的方式学习以太坊对象”!

综上所述

让我们简单回顾一下我们学到了什么! 总的来说,以太坊有四种前缀树:

世界状态树包括从地址到账户状态的映射。 世界状态树根节点的哈希值由区块保存(在stateRoot字段中),表示区块创建时的当前状态。 全网只有一棵世界状态树。

账户存储树存储与某个智能合约相关的数据信息。 帐户存储树根节点的哈希值(在 storageRoot 字段中)由帐户状态保存。 每个帐户都有一个帐户存储树。

交易树包含一个区块中的所有交易信息。 交易树根节点的哈希由区块头保存(在 transactionsRoot 字段中)。 每个区块都有一个交易树。

交易回执树包含一个区块中所有交易的回执信息。 还有,区块头(在receiptsRoot区)保存了交易回执树根节点的hash值; 每个区块都有对应的交易收据树。

我们今天讨论的对象是:

世界的状态:分布式计算机以太坊的硬盘。 它是从地址到帐户状态的映射。

账户状态:存储每个以太坊账户的状态信息。 账户状态还保存了账户状态树的storageRoot,里面包含了账户的存储数据。

事务:标记系统中的状态转换。 它可以是资金转移、消息调用或合约部署。

块:包含与前一个块(parentHash)的连接,并保存在执行时将在系统中生成新状态的事务。 区块中还保存了stateRoot、transactionRoot、receiptsRoot、世界状态树的根节点hash、交易树和对应的交易收据树。

我想用一张图来表示文章中提到的各种概念信息。

以太坊联盟和以太坊的关系_以太坊究竟是什么_以太坊经典和以太坊

-区块、交易、账户状态对象和以太坊的默克尔树-

根据个人经验,直接从黄皮书上学习以太坊并不方便,需要很大的耐心。 如前所述,本文的主要目标是用区块链初学者可以理解的语言描述以太坊的主要对象。 衷心希望本文能为您的学习之路指点迷津!