信息安全从业人员^_^
一个未入门de情报学胖子(邮箱:tenghm1986@163.com)
Toggle navigation
信息安全从业人员^_^
主页
About Me
归档
标签
以太坊黄皮书[中文]
2018-10-23 16:35:11
8412
0
0
heming
# 0.参考 [1] [以太坊黄皮书中文版](https://github.com/yuange1024/ethereum_yellowpaper) [2] [yellow paper: Ethereum's formal specification](https://github.com/ethereum/yellowpaper) [3] [markdown数学公式输入](http://blog.lisp4fun.com/2017/11/01/formula) # 1.简介 - 比特币网络通过共识机制、自愿遵守的社会合约,实现了一个**去中心化**的**价值转移系统**且可以在全球范围内自由使用。这样的系统是加密安全、**基于交易状态机**的一种具体应用 - 以太坊是一个尝试达到通用性的技术项目,可以构建任何基于**交易的状态机** ## 1.1 驱动因素 - 最重要目标:为了促成那些本来无法信任对方的个体之间交易,想用一个丰富且清晰的语言去实现一个状态变化的系统,期望协议被自动执行 - 给用户一个保证:个体、系统或者组织之间相互交互,他们都能完全**信任可能的结果**以及**产生结果的过程** ## 1.2 前人工作 - 2013年 Buterin提出核心机制但最重要核心特性:**图灵完备的语言**和实质上具有**无限的**内部交易**数据存储容量**的区块链 - 1992年 Dwork and Naor共识算法Proof of Work,互联网传递价值信号的一种手段 - 竞争币(alt-coins:彩色币、万事达币、瑞波币--联邦系统、清算系统) - Szabo and Miller 智能合约 smart contract # 2. 区块链范式 > - 以太坊整体上可以看成是一个基于交易的状态机:起始于创世区块(Genesis)状态,然后随着交易的执行状态逐步改变一直到最终状态。 - 交易则成为了连接两个状态的有效桥梁。(无效的状态改变可能是减少账户余额,但是没有在其他账户上加上同等额度) > $ \sigma_{t+1}\equiv\Upsilon (\sigma_{t},T)$ $\Upsilon$是状态转换函数,可以执行任意计算 $\sigma$是储存交易中状态 $T$是交易 >区块 >> 每个区块保留若干交易数据和前一个区块的引用,加上一个最终状态的标识符(最终状态不保存在区块中) >挖矿 >>通过一定的努力与其他潜在的区块竞争一系列交易的记账权 $\sigma_{t+1} \equiv \prod(\sigma_{t},B)$ $ B \equiv (...,(T_{0},T_{1}...))$ $\prod(\sigma,B) \equiv \Omega(B,\Upsilon(\Upsilon(\sigma,T_{0}),T_{1})...) $ 其中$B$是一个区块,包含一系列交易和一些其他组成部分 $\prod$是区块级别状态转换函数 $\Omega$是区块定稿状态转换函数 ## 2.1 单位 |倍数|单位| |:--|:--| |10<sup>0</sup>|Wei(伟)| |10<sup>12</sup>|Szabo(萨博)| |10<sup>15</sup>|Finney(芬妮)| |10<sup>18</sup>|Ether(以太)| ## 2.2 如何选择历史 如果从根节点到叶子节点的路径不同(最佳区块),那么就会产生分叉 这就意味着在某一个给定的时间点,系统中会有多个状态共存 目前使用一个简易的GHOST版本达成共识,有时会在某个特定的区块链高度启用新的协议 # 3. 约定 >$\sigma$表示世界状态 $\mathcal{U}$表示机器状态(machine-state) $\Upsilon$表示以太坊状态转换函数 $C$表示总体费用 $KEC$表示Keccak-256哈希函数 $SHA3$PoW哈希算法 $KEC512$表示Keccack-512哈希函数 $T$表示交易,**T<sub>n</sub>**表示交易的nonce次数 $ \square $表示未修改的输入值 $\square ^* $表示中间值 $B_{32}$表示32字节 $N_{256}$表示所有比2<sup>256</sup>小的正整数 $\ell(x) \equiv x[||x||-1]$表示序列中的最后一个条目 # 4.区块、状态和交易 ## 4.1 世界状态 地址和账户状态的映射,账户状态$\sigma[a]$包含以下四个字段: - nonce:等于账户地址发出的交易数量或者这个账户所创建的合约数量,表示成$\sigma[a]_{n}$ - balance:表示这个账户地址用于多少wei,表示成$\sigma[a]_{b}$ - storageRoot:保存这个账户存储内容的Merkle Patricia树的根节点的256位哈希值(keccak256位到RLP映射),表示成$\sigma[a]_{s}$ - codeHash:EVM代码的哈希值,当代码被创建不可修改,用$b$来表示代码则有KEC(b)=$\sigma[a]_{c}$,如果是空字符串的哈希,即$\sigma[a]_{c}=kec()$,即为"非合约账户" 这些状态没有存储在区块链上,但在映射过程中将映射维护在一个Merkle Patricia树上,这个树需要后端数据库去维护,称为状态数据库 >定义世界状态函数$L_{s} \equiv \{ p(a):\sigma[a] \neq \phi \}$ $p(a) \equiv (KEC(a),RLP((\sigma[a]_{n},\sigma[a]_{b},\sigma[a]_{s},\sigma[a]_{c})))$ >>空账户 empty $EMPTY(\sigma,a) \equiv \sigma[a]_{c}=KEC(()) \bigwedge\sigma[a]_{n}=0\bigwedge\sigma[a]_{b}=0$ Dead 账户 $DEAD(\sigma,a) \equiv \sigma[a]=\phi \vee EMPTY(\sigma,a)$ ## 4.2 交易 交易(符号,T)是一个单一的加密学签名的指令,交易有两种类型:一种表现为**消息调用**,另一种为通过**代码创建新的账户(称为“合约创建”)** 这两种类型的交易有一些共同字段: - nonce:交易发送者发出的交易数量,表示**T<sub>n</sub>** - gasPrice:每单位gas的价格,表示**T<sub>p</sub>** - gasLimit:执行这个交易的最大gas数量,表示**T<sub>g</sub>** - to:接收者地址,160位的消息调用接收者地址;合约的话,$\phi$表示B<sub>0</sub>的唯一成员,表示成**T<sub>t</sub>** - value:转移到接收者账户的Wei的数量,表示成**T<sub>v</sub>** - v,r,s:与交易签名相符的若干数值,用于确定交易的发送者(v:金额,r:接收,s:发送)分别表示成**T<sub>w</sub>,T<sub>r</sub>,T<sub>s</sub>** - init:一个不限制大小的字节数组,用来指定账户初始化程序的EVM代码,用**T<sub>i</sub>表示**(**合约创建**) - data:一个不限制大小的字节数组,用来指定消息调用的输入数据,由**T<sub>d</sub>**表示(一个**消息调用**交易包括的) >if $T_{t} = \phi$ $L_{T}(T) \equiv (T_{n},T_{p},T_{g},T_{t},T_{v},T_{i},T_{w},T_{r},T_{s})$ otherwise $L_{T}(T) \equiv (T_{n},T_{p},T_{g},T_{t},T_{v},T_{d},T_{w},T_{r},T_{s})$ --- **NOTE** T<sub>i</sub> T<sub>d</sub>不限制字节长度 T<sub>t</sub> 普通账户:20字节的地址哈希值;合约时将等于$\phi$ --- ## 4.3 区块 区块组成: - 信息片段集合--区块头(block header) - 组成区块的交易T - 其他一些区块头U(叔区块,ommers) >一个区块B可以表示成: $B \equiv (B_{H},B_{T},B_{U})$ 区块头包含的信息如下: - parentHash - 父区块头的Keccak256哈希,用**H<sub>p</sub>**表示 - ommersHash - 当前区块的ommers列表的Keccak256哈希,用**H<sub>o</sub>**表示 - beneficiary - 成功挖到这个区块所得到的所有交易费的160位接收地址,用**H<sub>c</sub>**表示 - stateRoot - 所有交易被执行且区块定稿后的状态树(state trie)的根节点的Keccak256哈希,用**H<sub>r</sub>**表示 - transactionsRoot - 当前区块中所包含的所有交易所组成的树结构(transaction trie)根节点Keccak256位哈希.用**H<sub>t</sub>**表示 - receiptsRoot - 当前区块中所有交易的收据所组成的树结构(receipt trie)根节点的Keccak256位哈希.用**H<sub>e</sub>**表示 - logsBloom - 由当前区块中所有交易的收据数据中的可索引信息(产生日志的地址和日志主题)组成的Bloom 过滤器,用**H<sub>b</sub>**表示 - difficulty - 当前区块难度水平的纯量值,它可以根据前一个区块的难度水平和时间戳计算得到,用**H<sub>d</sub>**表示 - number - 当前区块的祖先的数量.创世区块的这个数量为 0.用**H<sub>i</sub>**表示 - gasLimit - 目前每个区块的 gas 开支上限,用**H<sub>l</sub>**表示 - gasUsed - 当前区块的所有交易所用掉的 gas 之和,用**H<sub>g</sub>**表示 - timeStamp - 当前区块初始化时的 Unix 时间戳,用**H<sub>s</sub>** 表示 - extraData - 与当前区块相关的任意字节数据,但必须在32 字节以内,用**H<sub>x</sub>**表示 - mixHash - 一个 256 位的哈希值,用来与 nonce 一起证明当前区块已经承载了足够的计算量,用**H<sub>m</sub>**表示 - nonce - 一个64位的值,用来与 mixHash 一起于证明当前区块已经承载了足够的计算量,用**H<sub>n</sub>**表示 ## 4.3.1 交易收据 每个交易执行过程中的一些特定信息编码为交易数据,以$B_{R}[i]$表示第i个交易的收据,并把收据信息保存在一个以索引为键的树中,树的根节点以$H_{e}$保存在区块头中 R包含四条目的元组: - 当交易发生后累积gas使用量$R_{u}$ - 交易过程中创建的日志集合$R_{l}$ - 这些日志信息所构成的Bloom过滤器$R_{b}$ - 交易的状态码$R_{z}$ (256字节,整数) > $R \equiv (R_{u},R_{l},R_{b},R_{z})$ $R_{z}$,256字节;$R_{u}$,正整数;$R_{b}$256字节的数据哈希 $R_{l}$是一系列日志项$(O_{0},O_{1},...)$ 一个日志项$O \equiv (O_{a},(O_{t0},O_{t1,...},O_{d}))$ 其中: $O_{a}$日志产生着的地址; $O_{t}$一系列32字节的日志主题; $O_{d}$一系列字节数据 ## 4.3.2 整体有效性 当一个区块满足如下条件,认为区块有效: - 内部一致的ommer和交易区块哈希值所组成 - 基于起始状态$\sigma$(由父区块的最终状态继承而来)按顺序执行完成所有的给定交易$B_{T}$后所达到的标识符$H_{r}$的一个新状态 >$H_{r} \equiv TRIE(L_{s}(\prod(\sigma,B)))$ $\prod$称为状态累积函数 $H_{o}\equiv KEC(RLP(L_{H}^*(B_{U})))$ $H_{t} \equiv TRIE( \{\forall i < ||B_{T}||,i \in N,p(i,L_{T}(B_{T}[i]))\})$ $H_{e}\equiv TRIE(\{\forall i < ||B_{R}||,i \in N; p(i,L_{R}(B_{R}[i]))\})$,其中$B_{R}$交易收据 $H_{b} \equiv \vee_{r \in B_{R}}(r_{b})$ $p(k,v) \equiv (RLP(k),RLP(v))$,键值对,经过RLP变换 此外:$TRIE(L_{s}(\sigma)) = P(B_{H})_{H_{r}}$ 其中$P(B_{H})$就是父区块B ## 4.3.3 序列化 $L_{H}$、$L_{B}$、$L_{R}$预备函数,分别对区块头、区块、交易收据进行RLP序列化,用于网络传输或者本地存储 $L_{H}(H) \equiv (H_{p},H_{o},H_{c},H_{r},H_{t},H_{e},H_{b},H_{d},H_{i},H_{l},H_{g},H_{s},H_{x},H_{m},H_{n})$ $L_{B}(B) \equiv (L_{H}(B_{H}),L_{T}(B_{T}),L_{H}(B_{U}))$ ## 4.3.4 区块头验证 **针对$H_{i}$验证:** $H_{i} \equiv P(H)_{H_{i}}+1$ **针对$H_{d}$验证:** 定义一个权威难度值函数$D(H)$ $ D(H) \equiv \begin{cases} D_{0},& if H_{i}=0\\ max(D_{0},P(H)_{H_{d}}+x \times\varsigma_{2} + \epsilon,& otherwise \end{cases} $ $D_{0} \equiv 131072$创世区块难度值 $x=\lfloor \frac {P(H)_{H_{d}}} {2048}\rfloor$ $\varsigma_{2} \equiv max(y- \lfloor \frac {H_{s}-P(H)_{H_{s}}} {9} \rfloor)$ varsigma 出块时间的动态平衡 $ y\equiv \begin{cases} 1,& if||P(H)_{U}||=0 \\ 2,& otherwise \end{cases} $ $\epsilon \equiv \lfloor 2^{\lfloor H_{i}^{'} \div 100000\rfloor -2}\rfloor$ epsilon会每个10w个区块难度逐渐上升 $H_{i}^{'} \equiv max(H_{i}-3000000,0)$ **针对 $H_{l}$验证:** $H_{l} < P(H)_{H_{l}} + \lfloor \frac {P(H)_{H_{l}}}{1024}\rfloor$ $\bigwedge$ $H_{l} > P(H)_{H_{l}} - \lfloor \frac {P(H)_{H_{l}}}{1024}\rfloor$ $\bigwedge$ $H_{l} \geq5000 $ **针对$H_{g}$验证:** $H_{g} \leq H_{l}$ **针对 $H_{s}$ 验证:** $H_{s} > P(H)_{H_{s}}$ 如果最近的两个区块间隔较短,则会导致难度值增加,大概率会延长下个区块的出块时间 **针对nonce $H_{n}$验证:** $n \leq \frac {2^{256}}{H_{d}}$ **针对$H_{x}$验证:** $||H_{x}|| \leq 32 $ # 5.GAS及其支付 任何操作都需要操作费用的原因: - 避免网络滥用 - 避免因为图灵完整性带来的不可避免问题 gasPrice可以由交易者随意指定,矿工会公告他们执行交易的最低gas价格 # 6.交易执行 交易执行是以太坊协议中最复杂的部分。 $\Upsilon$--状态转换函数 交易执行前先通过初始的基础有效性测试: - 交易是RLP格式数据,没有多余后缀 - 交易的签名时有效的 - 交易的nonce是有效的(等于发送者账户当前的nonce,交易次数) - gas上限不小于交易所使用的gas go($gaslimit \geq go$) - 发送者账户的balance应该不少于实际费用$v_{0}$($balance \geq v_{0}$) $\sigma ^{'}=\Upsilon(\sigma,T)$ **约定:** - $\Upsilon ^{g}$交易执行所消耗的gas - $\Upsilon ^{l}$交易过程中累积产生的日志项 - $\Upsilon ^{z}$交易结果的状态码 ## 6.1 子状态 交易过程中会累积产生一些特定的信息,我们称之为子状态,用A来表示: $A \equiv (A_{s},A_{l},A_{t},A_{r})$ $A_{s}$:在交易完成后删除账户 $A_{l}$:一系列的日志,允许以太坊的外部观察者简单跟踪合约调用 $A_{t}$:交易所接触过的账户集合 $A_{r}$:应该返还的金额 空的子状态$A^{0} \equiv(\phi,(),\phi,0)$,没有自毁、没有日志、没有接触过账户、返还金额为0 ## 6.2 执行 固有的gas消耗$go$ $ go \equiv \sum_{i\in T_{i},T_{d}} \begin{cases} G_{txdatazero},& i=0 \\ G_{txdatanonzero},& otherwise \end{cases} $+$\begin{cases}G_{txcreate}, & T_{t} = \phi\\0,& otherwise \end{cases}+G_{transaction}$ 等式上面一行为合约消耗gas(合约创建),下面一行为正常交易(消息调用) $T_{i}$ :EVM初始化代码的字节序列 $T_{d}$ :交易附带的关联数据的字节序列 合约创建 增加$G_{txcreate}$ 预支付的费用: $v_{0} \equiv T_{g}T_{p} + T_{v}$(可参考章节4.2) **检查有效性:** $S(T) \neq \phi$交易发起者的账户不为空 $\sigma[S(T)] \neq \phi$ 账户状态不为空(可参考章节4.1) $T_{n} = \sigma[S(T)]_{n}$ $go \leq T_{g}$ $v_{o} \leq \sigma[S(T)]_{b}$ $T_{g} \leq B_{Hl} - \ell(B_{R})_{u}$$(B_{Hl}$区块头总的gasLimit,${B_{R}}_{u}$区块中累积消耗gas,可参考章节4.3.1) **检查点状态$\sigma_{0}$**: $$\sigma_{0} \equiv \sigma $$ *except:* $$\sigma_{0}[S(T)]_{b} \equiv \sigma[S(T)]_{b}-T_{g}T_{p}$$ $$\sigma_{0}[S(T)]_{n} \equiv \sigma[S(T)]_{n}+1$$ **临时状态$\sigma_{p}$:** >约定: >>$\sigma_{p}$为临时状态 $g^{'}$为剩余gas $A$:子状态 $z$:状态码 $ (\sigma_{p},g^{'},A,z) \equiv \begin{cases} \bigwedge_{4}(\sigma_{0},S(T),T_{o},g,T_{p},T_{v},T_{i},0,T),&if&T_{t} = \phi\\ \Theta_{4}(\sigma_{0},S(T),T_{o},T_{t},g,T_{p},T_{v},T_{d},0,T) & otherwise \end{cases} $ $T_{0}$:交易的原始发起人,当一个消息的调用或合约创建不是由交易所触发,而是由EVM代码所触发时,原始发起人可能与发送者不同 $g$:$g \equiv T_{g} -go$ 等式第一行为合约创建,第二行为正常交易 $A_{r}^{'} \equiv A_{r} + \sum_{i \in A_{s}R_{selfdestruct}}$ 返还gas=剩余gas+基于返还计数的补贴(**看代码注意**): $g^{*} \equiv g^{'} +min\{\lfloor \frac {T_{g}-g^{'}}{2}\rfloor,A_{r}^{'}\}$ **基于临时状态$\sigma_{p}$定义预备最终状态$\sigma^{'}$:** $$\sigma^{*} \equiv \sigma_{p}$$ except: $$\sigma^{*}[S(T)]_{b} = \sigma_{p}[S(T)]_{b} + g^{*}T_{p}$$(返还未用完的gas,必须是+) $$\sigma^{*}[m]_{b} \equiv \sigma_{p}[m]_{b}+(T_{g}-g^{*})T_{p}$$ $$m \equiv B_{H_{c}}$$(head coinbase信息) $$$$ **最终状态\sigma^{'}:** 删除了所有出现在自毁列表中的账户或被接触过的空账户之后,即可达到最终状态 $\sigma^{'} \equiv \sigma^{*},except:$ $\forall i \in A_{s}:\sigma^{'}[i] = \phi$(交易完成后删除的账户) $\forall i \in A_{t}:\sigma^{'}[i] = \phi,if DEAD(\sigma^{*},i)$(接触账户) **定义$\Upsilon$相关信息:** $\Upsilon^{g}(\sigma,T)\equiv T_{g}-g^{*}$:交易中总共使用的gas $\Upsilon^{l}(\sigma,T) \equiv A_{l}$:交易中创建的日志 $\Upsilon^{z}(\sigma,T) \equiv z$:交易的状态码 # 7.合约创建 合约创建需要固有参数: - 发送者($s$) - 原始交易人($o$) - 可用的 gas($g$) - gas 价格($p$) - endowment($v$,即初始捐款) - 任意长度的字节数组(即EVM初始化代码)$\mathbf{i}$ - 消息调用/合约创建的当前栈深度($e$) - 以及对状态进行修改的许可($w$) 我们定义创建函数为函数 $\Lambda$,它将使用上述参数,和状态 $\boldsymbol{\sigma}$ 一起来计算出一个新的元组。就像第6 节所介绍的那样,这个新的元组包含新的状态、剩余的 gas、交易子状态以及一个错误消息 $(\boldsymbol{\sigma}', g', A, \mathbf{o})$: \begin{equation} (\boldsymbol{\sigma}', g', A, z, \mathbf{o}) \equiv \Lambda(\boldsymbol{\sigma}, s, o, g, p, v, \mathbf{i}, e, w) \end{equation} 新账户的地址是一个哈希值的最右边 160 位,这个哈希值是由一个仅包含发送者地址和其账户 nonce 的结构进行RLP编码之后再进行 Keccak 哈希计算所得到的。我们可以定义由此得来的新帐户的地址 $a$: \begin{equation} a \equiv \mathcal{B}_{96..255}\Big(\mathtt{\tiny KEC}\Big(\mathtt{\tiny RLP}\big(\;(s, \boldsymbol{\sigma}[s]_{\mathrm{n}} - 1)\;\big)\Big)\Big) \end{equation} 其中 $\mathtt{\tiny KEC}$ 是 Keccak 256 哈希函数,$\mathtt{\tiny RLP}$ 是 RLP 编码函数,$\mathcal{B}_{a..b}(X)$ 表示取二进制数据 $X$ 的位数范围 $[a, b]$ 的值,$\boldsymbol{\sigma}[x]$ 则是地址 $x$ 的状态,或者 $\varnothing$ 表示什么都不存在。注意,我们使用的是一个比发送者 nonce 要小的值(减了 1);因为我们认定我们已经在这个调用之前对发送者的 nonce 加了 1,因此所用的值是发送者在该交易或 VM 操作开始时的 nonce。 # 8.消息调用 执行消息调用时需要多个参数: - 发送者(s) - 交易发起人(o) - 接收者(r) - 执行代码的账户(c,通常与接收 者相同) - 可用的 gas(g) - 转账金额(v) - gas 价格(p) - 函数调用的输入数据(一个任意长度的字节数组 d) - 消息调用/合约创建的当前栈深度(e) - 对状态修改的许可(w) - 消息调用一个额外的元素--由字节数组 o 表示的输出数据 $ \begin{equation} (\boldsymbol{\sigma}', g', A, z, \mathbf{o}) \equiv \Theta(\boldsymbol{\sigma}, s, o, r, c, g, p, v, \tilde{v}, \mathbf{d}, e, w) \end{equation} $ # 9.执行模型(EVM) 通过一系列的字节代码指令和一个环境数据的元组去更改系统状态,通过一个正规的虚拟状态机来实现的,EVM,准图灵机(准--通过参数gas来限制) ## 9.1 基础 - EVM基于栈的架构,其中字(word)的大小是256位,其内存模型是简单基于字寻址的字节数组。 - 栈的最大深度1024 - 程序指令保存在ROM - EVM存在异常执行的情况,包括堆栈溢出和非法指令。如果发生像out-of-gas这样的异常,EVM不会使状态保持原样,而是立即停止执行,并告知执行代理,由代理来独立处理这些异常 ## 9.2 费用概述 三种情况消耗gas - 计算操作费用 - 执行一个低级别的消息调用或者合约创建可能需要扣除gas(CREATE,call,callcode) - 内存使用的增加也会消耗一定的gas ## 9.3 执行环境 - I<sub>a</sub> 拥有正在执行的代码的账户地址 - I<sub>o</sub> 触发这次执行的初始交易的发送者地址 - I<sub>p</sub> 触发这次执行的初始交易的 gas 价格 - I<sub>d</sub> 这次执行的输入数据字节数组;如果执行代理是一个交易,这就是交易数据 - I<sub>s</sub> 触发这次执行的账户地址;如果执行代理是一个交易,则为交易发送者地址 - I<sub>v</sub> 作为这次执行的一部分传到当前账户的转账金额,以 Wei 为单位;如果执行代理是一个交易, 这就是交易的转账金额 - I<sub>b</sub> 所要执行的机器代码字节数组 - I<sub>H</sub> 当前区块的区块头 - I<sub>e</sub> 当前消息调用或合约创建的深度(也就是当前已经被执行的 CALL 或 CREATE 的数量) - I<sub>w</sub> 修改状态的许可 执行模型定义了函数 $\Xi$,它可以用来计算结果状态 $\boldsymbol{\sigma}'$,剩余的 gas $g'$,累积的子状态 $A$ 和结果输出 $\mathbf{o}$。根据当前的上下文,我们可以把它定义为: $ \begin{equation} (\boldsymbol{\sigma}', g', A, \mathbf{o}) \equiv \Xi(\boldsymbol{\sigma}, g, I) \end{equation} $ 这个累积的子状态 A 是由自毁集合 s、日志集l、接触过的账户 t 和返还金额 r 所组成的元组 $A \equiv (s,l,t,r)$ ## 9.4 执行概述 可行的实现方案中,都应该对完整的系统状态$\sigma$和机器状态$u$一起进行迭代建模 ### 9.4.1 机器状态 机器状态$u$是由一个元组(g,pc,m,i,s)所定义: - 可用的gas g - 程序计数器pc - 内存的内容m - 内存中激活的自述(从0开始的连续计数)i - 栈的内容s ### 9.4.2 异常停止 - gas不足 - 无效的指令 - 栈中的条目不足 - 指令JUMP/JUMPI的目标无效 - 新栈的大小超过1024 - 在一个静态调用中去尝试修改状态 # 10.区块树到区块链 - 权威的区块链是在整个的区块树中从根节点到叶子节点的路径 - 计算量大的(路径长,区块hash计算依据包含计算量) # 11.区块定稿 区块定稿的过程包含4个步骤: - 验证ommer - 验证交易 - 发放奖励 - 校验(或在挖矿中,计算有效的)状态和区块的nonce ## 11.1 Ommer验证 - 验证ommer头也就是验证每个ommer头即是有效的区块头 - 它必须是当前区块N代以内的ommer,$N \leq 6$ - 一个区块最多有两个ommer头 <center> ![ommer验证](https://leanote.com/api/file/getImage?fileId=5bcecca8ab6441232f0042b9) </center> ## 11.2 交易验证 <center> ![交易验证](https://leanote.com/api/file/getImage?fileId=5bcecdafab6441213d003a8e) </center> ## 11.3 奖励发放 <center> ![奖励发放](https://leanote.com/api/file/getImage?fileId=5bcece0fab6441213d003aba) </center> ## 11.4 状态和nonce验证 <center> ![状态与nonce验证1](https://leanote.com/api/file/getImage?fileId=5bcece97ab6441213d003af6) </center> <center> ![状态与nonce验证2](https://leanote.com/api/file/getImage?fileId=5bcece97ab6441213d003af7) </center> ## 11.5 挖矿工作量证明 - 通过密码学安全的nonce来证明为了获得一些象征性的值n,已经付出了一定量的计算 - 工作量证明不仅是在未来使区块链权威的获得保障的安全信任方法,同时也是一个利益分配机制 工作量证明函数有两个重要的目标: - 尽可能的被更多人去接受(对特别定制的硬件的需求或由这种硬件所提供的回报,应该减到最小) - 不允许获得超线性的收益,尤其在有一个很高的初始障碍条件下(资金充裕,获得引起麻烦的挖矿算力,获得超线性的汇报,按他们的意愿改变收益分布) 比特币世界中一个灾难是ASIC(专为挖矿而设计的芯片) 抵抗ASIC设计的两个方向: - 设计一个需要大量的内存和带宽,来使这些内存不能被用于并行地计算nonce(选择第一个,ETHash) - 让计算变得有通用目的(针对定制的硬件) <center> ![工作量证明](https://leanote.com/api/file/getImage?fileId=5bced2a7ab6441213d003c76) </center> ### 11.5.1 Ethash <center> ![ethash](https://leanote.com/api/file/getImage?fileId=5bced6e6ab6441213d003eae) </center> # 12.实践合约 特别有用的合约模式,其中两个: - 数据供给(data feeds) - 随机数(random numbers) ## 12.1 数据供给 允许外部的信息进入以太坊内,以太坊不会保证这个信息的京都和及时性,这是二级合约作者的任务 通常模式是会包含一个以太坊内的合约,当给定一个消息调用时,可以由外部服务提供信息 ## 12.2 随机数 利用在交易时还不可知的数据来生成伪随机数,比如区块的哈希值,区块的时间,区块的beneficiary地址,使用BLOCKHASH操作获得最近256个区块的哈希值作为随机数 # 13.未来方向 - 状态数据库将不再强制要求维护所有之前的trie结构 - 区块链合并(减少作为全节点或挖矿节点客户端需要下载的区块数量) - 区块链压缩:一定数量的区块中没有进行任何发送/接收交易的状态树节点可以丢弃,以此来降低以太币的泄露(Ether-leakage)并减小状态数据库的增长 ## 13.1可扩展性 - 概括性的状态转换函数,切分和并行化交易将难以适应分而治之的策略 - 低价值的交易可以忽略 - 一些形式的层次结构或许可以实现并行化的交易组合和区块构建比如通过合并小的轻量的链到主区块;增量式地组合或粘连(通过工作量证明)小的交易来构建主区块 # 14.结论 去中心化的安全的社会化操作系统
上一篇:
以太坊白皮书[中文]
下一篇:
专利相关
0
赞
8412 人读过
新浪微博
微信
腾讯微博
QQ空间
人人网
Please enable JavaScript to view the
comments powered by Disqus.
comments powered by
Disqus
文档导航