Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

以太坊黄皮书公式解析(下) #55

Open
DavidCai1111 opened this issue Jan 13, 2022 · 0 comments
Open

以太坊黄皮书公式解析(下) #55

DavidCai1111 opened this issue Jan 13, 2022 · 0 comments
Labels

Comments

@DavidCai1111
Copy link
Owner

前言与版本

笔者最近在结合以太坊黄皮书以太坊源码,结合自己的理解解析下黄皮书内的公式,与大家共同学习进步,若大家在阅读以太坊黄皮书时,对公式产生理解上的困惑,可以参阅本文一起看。文章基于当前(2022/1/10)的黄皮书,版本号为 BERLIN VERSION fabef25 ,若有不准确之处,欢迎指出。由于该黄皮书内除附录外有 183 个公式,为了让文章篇幅不过长,该解析会由三部分组成一个系列,每个系列解析约 60 个公式,本文为下篇。

公式解析

(130)

  • 此处 Ξ 为 EVM 指令执行函数。
  • σ 为执行前世界状态。
  • σ' 为执行后世界状态。
  • g 为执行前 Gas 剩余。
  • g' 为计算后 Gas 剩余。
  • I 所包含的字段参阅公式 (91) - (99)。
  • A 为执行后子状态。
  • o 为执行输出内容(output)。

公式 (130) 给出了 EVM 指令执行函数的输入输出定义。

(144)

  • u 为机器状态(machine state),包含:
    • ug: 剩余可用 Gas 。
    • upc:当前执行程序计数器。
    • um:内存的内容。
    • ui:内存中激活的字节数。
    • us:栈的内容。

公式 (144) 定义了当前待执行指令 w ,即为待执行指令集位于索引 upc 中的指令,或者为 STOP 。

(145) (146)

  • Z 为异常检查函数。

公式 (146) 定义了指令 W 函数,当 w 的指令在 CREATE, CREATE2, SSTORE, SELFDESTRUCT 之一,在 LOG0 - LOG4 之一,或是 CALL 且对应栈索引上的数据不为空时。
公式 (145) 定义异常状态的可能情况:Gas 费不足、非法指令(指令 w 的 δw 未定义,详细后文会阐述)、栈中参数不足、JUMP\JUMPI 的目的地非法、新的栈大小超过 1024、企图在 static 调用中修改状态。

(150)

公式 (150) 定义了正常停止函数 H 。当指令会 RETURN 或 REVERT 时,会返回一个特殊函数 HRETURN 。若是 STOP 或 SELFDESTRUCT,则返回空序列,或者则返回空集合(表示返回不正常)。

(131) - (143)

公式 (140) 定义了 o 为正常停止函数 H 对当前机器状态和入参 I 的输出。
公式 (141) 定义了 · 操作会将其之后的项放入集合中。
公式 (142) (143) 表示机器状态的更新会伴随 Gas 的消耗。
公式 (139) 定义了指令执行函数 X ,它会被递归调用(公式中第 4 种情况),除非检测到异常(通过异常检查函数 Z 检查)、操作为 REVERT 或正常停止(通过正常停止函数 H 检查)。
公式 (133) - (138) 定义了机器状态 u 的初始状态。
公式 (131) - (132) 表示 Ξ EVM 执行函数的具体逻辑为对入参进行 X 函数(即公式(139))的调用。

(149)

公式 (149) 定义了 N 函数,接受当前指令索引以及指令,返回下一个有效指令在代码中的位置。会区分给定的指定入参是否为 PUSH1, PUSH2 。

(147) (148)

公式 (147) 的 D 函数返回正在运行的代码所给定的有效跳转地址集合。如果位置越界,则返回空集合。如果指令为 JUMPDSET ,则会递归调用 N 函数保存到一个位置集合,否则直接调用 N 函数返回下一个位置。

(151) - (154)

公式 (151) - (154) 描述了指令的栈执行模型,栈变化大小由入栈指令个数减去出栈指令个数(公式(152))。公式 (153) 表示栈是低位索引(lower-indexed)的,即栈顶索引为 0 。公式 (154) 则表示在指令从索引 0 开始往栈内推入后,会从栈顶开始一条条执行指令,索引也会逐渐变小。

(155) (156)

公式 (155) 表示,随着不同计算的执行,ug 会被相应的消耗。公式 (156) 则表示,upc 会根据是否是 JUMP/JUMPI 来判断,或者是调用公式 (149) 定义的 N 函数。

(157) - (160)

公式 (157) - (160) 则表示,假定在执行中,机器状态内的,内存(m, i),子状态(A)和世界状态(σ)不会改变。

(161) - (162)

  • Bt 为链上的总难度。
  • Bd 为当前区块难度。

公式 (162) 定义了 B' 为当前区块的父区块。公式 (161) 则表达了链上的总难度是累计的。

(165)

公式 (165) 定义了如何判断两个区块是否是兄妹(sibling):即两个区块的父区块相同,两个区块自身是不同区块,相互不为叔块。

(164)

公式 (164) 定义了如果判断两个区块是否是亲属(kin):如果 n 代之内是兄妹(sibling),则为亲属。

(163)

  • V 为区块头验证函数,参阅公式 (52) 。

公式 (163) 表示,当前区块最多可以引用两个叔块,叔块都验证有效,且叔块都与当前区块在 6 代以内。

(164)

公式 (164) 表示,区块头中记录的总累计 Gas 使用量,必须为区块中最后一个区块执行后的累计 Gas 使用量相同。

(165) - (171)

  • Rblock 为当前挖出一个区块所能获得的奖励。

公式 (171) 定义了当初挖出这个叔块的矿工的收益,从公式可以看出,该叔块离当前区块越亲,则奖励越高,并且会把奖励加入到账户状态中(公式(170)),前提是收益账户不是空账户(公式(169))。公式 (168) 定义了挖出当前区块的矿工收益,除了固定的挖出区块所得收益之外,也与其引用的叔块的数量相关。公式 (167) 则将上述这些行为,统一定义为区块奖励函数 Ω 。

(172)

公式 (172) 定义了不同以太坊版本中,挖出区块的固定收益。

(173)

  • LS 为世界状态函数,具体定义参阅公式 (10) 。

公式 (173) 定义了函数 Γ ,映射区块 B 至它的初始世界状态。若区块 B 没有父区块(即它就是创世区块),那么为创世状态。否则就是它的初始世界状态就是其父区块的 storageRoot 。

(182)

公式 (182) 定义了区块状态转换函数 Π ,定义是从最新的世界状态,再加上接收过 Ω 函数奖励后的区块的状态。

(174) - (177)

公式 (174) - (177) 定义了区块状态转换函数 Φ :首先更新当前区块的 storageRoot 为父区块的世界加上区块中所有交易对状态的改变(公式(177));将矿工挖矿算出的最终结果记录在区块的 mixHash 中(公式(176));更新区块的 nonce (公式(175)),且最大值由区块的 difficulty 限定。

(179)

  • Υg 为区块交易 Gas 花销状态计算函数。

公式 (179) 表达了区块的 Gas 花销,会随着一个个交易的处理而累积。

(180)

  • Υl 为区块交易日志状态计算函数。

公式 (180) 表达了区块的日志,会随着一个个交易的处理而累积。

(181)

  • Υz 为区块交易状态码计算函数。

公式 (181) 表达了区块的状态码,会随着一个个交易的处理而更新。

(178)

  • Υ 为区块交易整体状态计算函数。

公式 (178) 是公式 (179) - (181) 定义了 σ[n] 为基于区块内的第 N 个交易后所产生的状态。表示区块状态会从区块的初始状态开始,通过一个个交易来累积更新状态。

(183)

公式 (183) 描述了工作量证明函数 PoW ,接受三个参数,第一个为不包含 nonce 和 mixHash 的新区块头状态,第二个参数为当前区块头 nonce,第三个参数为当前 DAG (用来计算 mixHash 的大型数据集合),输出 mixHash 和 nonce 。nonce 的最大值由区块的 difficulty 限定。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant