ethereum 黄皮书理解

目录

1. 总览

2. 数据结构

3. 区块形成过程

4. 交易执行

5. 执行模型

6. Gas 返还

参考:


1. 总览


以太坊是基于交易的状态机,基于区块,交易在区块中顺序执行,所有节点的大量冗余计算保证了可信性

2. 数据结构


账户状态 accountState: nonce  balance  storageRoot  codeHash

    nonce: 当前账户发出的交易数量,后面的交易中的nonce跟账户保持一致,合约账户创建后,nonce为1

    storageRoot: EOA为空值,没有存储

                          COA有值,合约所有存储变量及值的键值对,作为叶子节点,最后生成MPT的根root

    codeHash:     EOA为空字串的哈希值

                          COA合约账户关联代码的哈希值

    storage Trie的叶子节点:

    F(address,storage position, blockNumber)   --->   strorage Data

世界状态 World State:就是所有账户状态

    状态树 State Trie,根root写入到区块头中

    keccak256(address)  --> RLP(accountState)

    state Trie的数据存储在各个节点的数据库LevelDB中,即 state DB

    state root  --->   RLP(state trie)

交易 Transaction: nonce  gasPrice  gasLimit  to value  data  v r s

    交易树 Transaction Trie,根root写入到区块头中

    RLP(transactionIndex)  --->  RLP(transaction)

收据 Receipt: madState  gasUsed logBloom logs

    收据树 Receipt Trie, 根root写入到区块头中

    RLP(transactionIndex)  ---> RLP(transaction Receipt)

区块 Block:blockHeader  transactionList   ommerHeaderList

区块头 BlockHeader: parentHash   ommersHash benefitiary  stateRoot  transactionRoot   receiptRoot  logBloom difficulty  number gasLimit gasUsed timeStamp extraData  mixHash nonce

3. 区块形成过程


矿工节点:

ommer验证 ---> 从交易中选取交易并顺序执行  --->  奖励发放  --->  生成区块  ---> pow验证状态

非矿工节点:

ommer验证 --->  顺序执行区块中包含的交易   --->   奖励发放  --->  验证区块   --->  pow验证

如果在计算pow的过程中收到另一个区块,并验证ok,前面打包到自己区块,正在计算pow的交易要回退状态,会退到父区块状态(state DB),甚至有可能要切换分支,回到与接收的区块所在分支的分叉点的世界状态,并再计算到新分支的末尾节点

4. 交易执行


交易字段有  tx: nonce  gasprice gaslimit  to value data

交易分类: tx.to 有效  tx.data 为空  ===》 EOA之间的普通转账

                   tx.to 为空  tx.data 不为空 ==》合约创建

                   tx.to 有效  tx.data 不为空 ==》 消息调用

交易执行顺序:

                   1. 有效性检查

                           ECRecover(hash(tx), v, r, s)  == sender.address

                           tx.nonce == sender.nonce

                           tx.gas0 <= tx.gasLimit        

                           sender.balance >= tx.gas0 * tx.gasPrice

                           block.gasUsed + tx.gas0 <= block.gasLimit

                    2. 不可更改状态修改

                            sender.nonce += 1

                            sender.balance -= tx.gas0 * tx.gasPrice

                    3.  根据交易类型分类执行

                          转        账: sender.balance -= tx.value

                                             tx.to.balance += tx.value

                          合约创建: 将tx.data作为EVM字节码在EVM中执行

                          消息调用: 将tx.data作为ABI 编码在EVM中执行

                     4.  处理结束

                          返还gas 删除自毁账户和空账户

5. 执行模型


   EOA账户发起交易,以太坊内部转换成message,触发 EVM Computation执行

   首先1个交易的执行是在一个区块内部的,所以外部执行环境也就是区块的状态:

       Execution Context: coin_base  timeStamp blockNumber  difficulty gas_limit          

   其次1个交易:

        Transaction Context: gasPrice  origin

   最后1个交易转成message 传入 EVM Computation

        Message: gas value  to  sender  data  code  depth  create_address code_address  storage_address should_transfer_value   

    EVM Computaion 基于账户代码,存储变量开始执行tx.data中指定的函数,如果再EVM 字节码中有 create/call/callcode/delegateCall/staticCall中的1个,会生成child message,

   按照交易分类:

         合约创建:

                 1. 计算合约地址

                     newAddress = B(96...255)(keccak256(RLP(sender, sender.nonce)))

                  2. 转成message

 Message: gas   value    to    sender data    code  create_address code_address  storage_address

             tx.gas  tx.data tx.to tx.from  NULL  tx.data   newAddress      newAddress    newAddress

                    3. 交由EVM Computation执行

                    4. 保存输出(runtime bytecode) hash值即codeHash 保存到账户状态中

                        合约代码是世界状态的一部分,用全局独立的MPT来维护所有账户的关联代码,账户地址作为key,但是访问受限

                         只能通过EVM的create写入

                         只能通过EVM的codesize codecopy extcodesize  exitcodecopy call callcode delegatecall staticcall 间接操作访问

            消息调用:

                    1. 从tx.to的地址上取出account_code   account_code   = state.account_db.get_code(tx.to)

                     2. 转成message

Message: gas   value    to    sender data    code  create_address code_address  storage_address

              tx.gas  tx.value  tx.to  tx.from  tx.data  account_code  none    tx.to                   tx.to   

6. Gas 返还


       SSTORE将非0值存储槽修改为0值,返还15000,操作本身消耗5000,计入计数器Ar

       Selfdestruct 指令删除返还24000,操作本身消耗5000,计入计数器Ar

       实际消耗的gas为Ga,交易执行完剩余gas为Gr

        返还gas G = Gr + min(Ga/2, Ar)     

参考:

https://ethereum.stackexchange.com/questions/268/ethereum-block-architecture

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值