《区块链原理与技术》学习笔记(五) ——以太坊的交易、共识机制和数据结构

《区块链原理与技术》学习笔记 第五部分

5. 以太坊交易

以太坊中,交易承载了账户转账和合约创建、调用合约等功能。

5.1 交易内容

交易中的数据大体分为基本的交易、交易的执行参数、交易的签名三个部分。

基本交易内容

  • From:交易发送者的地址,实际上由签名中的<r,s,v>计算得到。
  • To:交易接收者的地址。创建合约时设置为0x0000,调用合约时是合约的地址。
  • Value:交易的金额。1Ether = 10^18 Wei。

交易的执行参数

  • Input Data:交易附带数据,传递创建合约的代码/构造函数、调用合约的函数和参数。
  • Nonce:交易发送者的Nonce。
  • MaxFeePerGas:发送者为交易愿意付出的最大price
  • MaxPriorityFeePerGas:给矿工付出的最大小费
  • gasLimit: 交易允许消费的最大gas,解决智能合约不能停机的问题。

交易的签名

  • hash:由以上字段生成的哈希值
  • r,s,v:由发送者的私钥对交易的哈希做数字签名而成,用于确认转账的合法性。

5.2 交易费用

以太坊中交易的的手续费由Gas机制计算,主要包括以下概念:

  • Gas:计算资源消耗的基础单位
  • GasLimit:允许消耗的最大Gas值
  • GasUsed:执行后消耗的Gas值
  • GasPrice:每个Gas的以太币价格

其中交易的Gas由基础的交易Gas加上EVM运行时消耗的Gas值累加得到。当GasUsed超过GasLimit,交易执行失败。
交易的GasUsed*GasPrice就是用户为交易支付的手续费。

5.3 交易的周期

在这里插入图片描述

1.发起

  • 用户输入from,to,value,data,gasPrice等
  • 用户确认发送至以太坊节点
  • 以太坊钱包软件为用户补充gasLimit,nonce,使用私钥得到r,s,v,最后将交易序列化后发送到网络。

2.广播

  • 节点收到/发起交易后,对交易进行验证
  • 节点验证为合法交易,将交易加入节点的交易池中
  • 节点根据P2P网络广播的策略向相邻节点继续广播交易

3.打包与执行

  • 全节点将交易打包,并将交易按顺序执行
  • 所有需要打包的交易执行后,将交易、状态、收据的信息打包到区块中。
  • 记账节点获得合法区块后,广播到相邻节点

4.验证与执行

  • 没有获得记账权的节点在收到广播的区块后,对区块进行合法性验证,并进行交易的执行。

5.4 交易的执行类型

根据to值的不同,交易的执行分为以下3种:

1.创建合约交易
to为空的交易,交易根据from和nonce值生成合约地址,并执行data中的智能合约代码。EVM会将代码存储到合约地址中。

2.调用合约交易
to为合约账户的交易。EVM获取to地址中的代码,并执行data中的代码。
本质上来说。对合约的调用就是对合约状态的修改。

3.普通转账交易
to为人控制的账户(外部账户),交易直接将以太币从from转到to

6. 以太坊的共识机制

6.1 解决以太坊分叉:Ghost协议

叔块
指不在主链但被主链记录的满足难度的区块。矿工在打包区块时,可以自主选择合法的0-2个叔块。
以太坊中规定,7代以内的有共同祖先的都可以认为是叔父块。

叔父块的接纳和奖励规则

  • 对于主链上的区块,每个区块最多接纳2个叔父块,每接纳一个叔父块,主链区块奖励增加1/32。
  • 接纳的叔父块应该是主链上祖先的直接子块,且不能重复接纳叔父块。
  • 被接纳的叔父块,获得出块奖励为1-(接纳块高度-叔父块高度)/8
  • 叔父块中的交易不需要执行。

在这里插入图片描述

叔父块可以尽量收缩和统一整个区块链的主链,同时维护矿工的积极性。

6.2 新的共识机制:PoS

权益证明(Proof-of-Stake):持有币的数量和占有币数的时间来决定你获得本次记账权利的概率。持有越多,获得记账概率越大。

相比PoW缩短了达成共识时间,节省能源,但是容易分叉和中心化。

7. 以太坊挖矿难度调整

挖矿难度的公式为:

H

=

0

,

D

(

H

)

=

0

D

(

H

)

=

m

a

x

(

D

0

,

P

(

H

)

H

d

+

x

×

ζ

2

)

+

ϵ

H=0,D(H)=0 \ D(H)=max(D_0,P(H)_{H_d}+x × zeta_2)+epsilon

H=0,D(H)=0D(H)=max(D0,P(H)Hd+x×ζ2)+ϵ
其中

P

(

H

)

H

d

P(H)_{H_d}

P(H)Hd是父区块的难度,

x

×

ζ

2

x×zeta_2

x×ζ2 用于自适应调节出块难度,

ϵ

epsilon

ϵ表示设定的难度炸弹

基础部分有下界,最小值为

D

0

=

131072

D_0=131072

D0=131072

7.1 自适应难度调整

x

=

P

(

H

)

H

d

2048

,

 

ζ

2

=

m

a

x

(

y

H

s

P

(

H

)

H

s

9

,

99

)

x= leftlfloor frac{P(H)_{H_d}}{2048} rightrfloor, zeta_2=max left( y-leftlfloor frac{H_s-P(H)_{H_s}}{9} rightrfloor, -99 right)

x=2048P(H)Hd, ζ2=max(y9HsP(H)Hs,99)
x为调整的单位,

ζ

2

zeta_2

ζ2 为调整的系数
如果父区块中包含uncle,y为2,否则为1

H

s

H_s

Hs是本区块的时间戳,

P

(

H

)

H

s

P(H)_{H_s}

P(H)Hs是父区块的时间戳,并规定

H

s

>

P

(

H

)

H

s

H_s > P(H)_{H_s}

Hs>P(H)Hs

7.2 难度炸弹

ϵ

=

2

H

i

/

100

,

000

2

,

 

H

i

=

m

a

x

(

H

i

30

,

000

,

000

)

epsilon = leftlfloor 2^{lfloor H'_i / 100,000 rfloor -2} rightrfloor, H'_i=max(H_i-30,000,000)

ϵ=2Hi/100,0002, Hi=max(Hi30,000,000)

ϵ

epsilon

ϵ 是2的指数函数。每100000块扩大一倍

设置难度炸弹是为了降低迁移到PoS协议时发生fork的风险,引导矿工有意愿迁移到PoS。

8. 数据结构与存储

8.1 区块和叔块

以太坊区块的区块头包括:

  • 记录以太坊状态的状态根
  • 交易列表、收据列表、父块和叔块的哈希值
  • 区块号、难度、矿工地址、时间戳、Nonce值
  • gas上限、交易gas之和、工作量证明摘要
  • 可变长度字段

以太坊区块体的内容:

  • 由交易组成的TX列表
  • 有交易执行信息组成的收据列表
  • 用于改进以太坊共识过程的叔块列表

在这里插入图片描述

世界状态
以太坊中所有账户的状态的汇总,也就是区块头的状态根,通过一个特殊的树状哈希数据结构实现。

收据
对应交易的数据结构,代表交易执行的一些中间状态写入交易的执行结果等信息。
收据的内容包括:

  • 以太坊的智能合约向EVM输出的执行日志
  • 智能合约执行的Gas
  • 单个交易执行完毕后以太坊的状态根
  • 如果交易创建合约,收据中写入新建合约的地址

8.2 默克尔前缀树(Merkle Patricia Trie)

由于以太坊潜在的账户数量巨大,单使用Merkle Tree无法存储数据,且修改成本高,因此以太坊使用了十六叉压缩前缀树,作为地址到账户的索引,然后利用Merkle Tree将每一层节点合并计算节点的哈希值,最后得到根哈希值。

压缩前缀树
普通的字典树(Trie)为每一个字母作为树的节点,这样导致树的高度太高,浪费存储空间;压缩前缀树(Patricia Trie)将共同的前缀部分组成一个子树,逐级向下划分,提高了查找效率。

在这里插入图片描述

MPT
在MPT中,“单词”对应账户的哈希值,“指针”对应哈希指针。叶子节点记录(前缀+账户哈希值)的哈希值,父节点的哈希值为(前缀+子分支)的哈希值。

以下图为例:
H1=H(“”+账户1的哈希值),H3=H(d+账户3的哈希值)
H5=H(bc+H1+H2+“”+“”+…+“”)
H6=H(b+H4+…+“”+H3+“+”“)
H_root=H(”“+…+”“+H5+…+”“+H6+”")

在这里插入图片描述

状态树
以太坊的状态树记录各个账号的状态,当状态改变后只会影响对应分支的状态,区块存储对应状态树的状态根。

合约存储树
合约账户存储树也使用了MPT来记录存储地址到存储值的映射,映射表的哈希值叫做存储根(storage root)。
由于合约存储空间中的一个单位刚好为256位,所以可以直接当叶子节点

交易树和收据树
这两棵树通过交易/收据在区块中的序号来构建MPT,收据和交易的信息一一对应。

8.3 布隆过滤器(Bloom Filter)

布隆过滤器可以检索一个值是否在一个集合中,以太坊用来对收据的日志进行索引、查找。
在容忍一定错误率的情况下,它的效率很高。

原理:用多个哈希函数将键值映射到一个位图中。对于一个键值,若在同样的哈希函数映射下,没有在位图中出现标记位,则键值一定不在集合中。

在这里插入图片描述

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇

)">
下一篇>>