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

  • 5. 以太坊交易
    • 5.1 交易内容
    • 5.2 交易费用
    • 5.3 交易的周期
    • 5.4 交易的执行类型
  • 6. 以太坊的共识机制
    • 6.1 解决以太坊分叉:Ghost协议
    • 6.2 新的共识机制:PoS
  • 7. 以太坊挖矿难度调整
    • 7.1 自适应难度调整
    • 7.2 难度炸弹
  • 8. 数据结构与存储
    • 8.1 区块和叔块
    • 8.2 默克尔前缀树(Merkle Patricia Trie)
    • 8.3 布隆过滤器(Bloom Filter)

5. 以太坊交易

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

5.1 交易内容

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

基本交易内容

  • From:交易发送者的地址,实际上由签名中的计算得到。
  • 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)=max( D 0,P(H ) Hd +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_2x×ζ2 用于自适应调节出块难度, ϵ\epsilonϵ表示设定的难度炸弹

基础部分有下界,最小值为 D0= 131072D_0=131072D0=131072

7.1 自适应难度调整

x= ⌊P ( H ) H d 2048⌋, ζ 2=max ( y − ⌊H s−P(H ) Hs 9⌋, − 99 )x= \left\lfloor \frac{P(H)_{H_d}}{2048} \right\rfloor, \ \zeta_2=max \left( y-\left\lfloor \frac{H_s-P(H)_{H_s}}{9} \right\rfloor, -99 \right) x=2048P(H)Hd,ζ2=max(y9HsP(H)Hs,99)
x为调整的单位, ζ2 \zeta_2ζ2 为调整的系数
如果父区块中包含uncle,y为2,否则为1
Hs H_sHs是本区块的时间戳, P ( H ) H s P(H)_{H_s}P(H)Hs是父区块的时间戳,并规定 Hs> P ( H ) H s H_s > P(H)_{H_s}Hs>P(H)Hs

7.2 难度炸弹

ϵ= ⌊ 2 ⌊ Hi′/ 100 , 000 ⌋ − 2⌋, H i ′=max( H i−30,000,000)\epsilon = \left\lfloor 2^{\lfloor H’_i / 100,000 \rfloor -2} \right\rfloor, \ 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)

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

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