美文网首页
以太坊源码解读 Block类及其储存

以太坊源码解读 Block类及其储存

作者: Li_MAX | 来源:发表于2018-12-15 13:59 被阅读19次

一、Block类

type Block struct {
        /******header*******/
    header       *Header
        /******header*******/
 
        /******body*********/
    uncles       []*Header
    transactions Transactions
        /******body*********/
 
    // caches
    hash atomic.Value
    size atomic.Value
 
    // Td is used by package core to store the total difficulty
    // of the chain up to and including the block.
    td *big.Int
 
    // These fields are used by package eth to track
    // inter-peer block relay.
    ReceivedAt   time.Time
    ReceivedFrom interface{}
}

block类实际上就只有两个部分,header和body。其他的如hash、size、td等都是在接受和验证区块后产生的内容,实际上向全网公布的时候block就只有header和body(uncles和transactions)。

Header里有哪些内容呢?

type Header struct {
   ParentHash  common.Hash    `json:"parentHash"       gencodec:"required"`
   UncleHash   common.Hash    `json:"sha3Uncles"       gencodec:"required"`
   Coinbase    common.Address `json:"miner"            gencodec:"required"`
   Root        common.Hash    `json:"stateRoot"        gencodec:"required"`
   TxHash      common.Hash    `json:"transactionsRoot" gencodec:"required"`
   ReceiptHash common.Hash    `json:"receiptsRoot"     gencodec:"required"`
   Bloom       Bloom          `json:"logsBloom"        gencodec:"required"`
   Difficulty  *big.Int       `json:"difficulty"       gencodec:"required"`
   Number      *big.Int       `json:"number"           gencodec:"required"`
   GasLimit    uint64         `json:"gasLimit"         gencodec:"required"`
   GasUsed     uint64         `json:"gasUsed"          gencodec:"required"`
   Time        *big.Int       `json:"timestamp"        gencodec:"required"`
   Extra       []byte         `json:"extraData"        gencodec:"required"`
   MixDigest   common.Hash    `json:"mixHash"          gencodec:"required"`
   Nonce       BlockNonce     `json:"nonce"            gencodec:"required"`
}

1)ParentHash:前一个区块的hash
2)UncleHash:叔区块hash,如果有多个叔区块就加到一起
3)Coinbase:矿工账户
4)Root:StateDB中的“state Trie”的根节点的RLP哈希值。
5)TxHash:“tx Trie”的根节点的RLP哈希值。
6)ReceiptHash: "Receipt Trie”的根节点的RLP哈希值。
7)Bloom:Bloom过滤器(Filter),用来快速判断一个参数Log对象是否存在于一组已知的Log集合中。
8)Difficulty:难度值
9)Number:区块号
10)GasLimit:区块内所有Gas消耗的理论上限。该数值在区块创建时设置,与父区块的GasUsed有关。
11)GasUsed:区块内所有Transaction执行时所实际消耗的Gas总和。
12)Time:时间戳
13)Extra:额外信息
14)Nonce:pow产生的数值,也可以用于验证矿工的工作

二、Root、TxHash、ReceiptHash

在比特币中,区块body中的交易通过merkle tree的形式组织,然后将merkle root存在block header中。

image

而在以太坊中不是merkle-tree,而是Merkle-PatricaTrie(MPT)结构,而且存在三棵树:state Trie、tx Trie、Receipt Trie。

首先,在StateDB中,每个账户以stateObject对象表示,所有账户对象可以逐个插入一个Merkle-PatricaTrie(MPT)结构里,形成“state Trie”。其次,Block的transactions中所有的tx对象,被逐个插入一个MPT结构,形成“tx Trie”。最后,所有Transaction执行完后会生成一个Receipt数组,这个数组中的所有Receipt被逐个插入一个MPT结构中,形成"Receipt Trie"。

image

上图中表示的意思是,首先一个区块的几个重要部分分开储存在leveldb中,header、body、receipts以RLP编码的形式储存在数据库中,key都是用num+key构成的。另外,我们可以通过‘h’+num+hash+'t'查询区块链的总难度td;‘H’+hash可以查询到blocknumber;在知道num的情况下可以查询‘h’+num+‘n’对应的区块链上的hash(即不在规范链上的区块可能也有该num,但是无法通过这个key查询到);在仅仅知道hash的情况下,通过‘l’+hash来查询区块hash+区块号+交易编码的编码值,这样的值仅仅储存规范链上的区块,所以我们可以快速的查看某hash对应的区块是否在规范链上。

key value
'h' + num +hash header的RLP编码值
'b' + num +hash body的RLP编码值
'r' + num +hash receipt的RLP编码值
'h' + num + hash + 't' 截止该区块的总难度值
'h' + num + 'n' 区块号对应的规范链上的区块的hash(规范链 )
'H' + hash Header对应的block number(规范链)
'l' + hash 【区块hash、区块号num、交易编号】的编码值,是交易查询入口(规范链)

这些信息都在强烈的暗示,num(Number)和hash是Block最为重要的两个属性:num用来确定Block在整个区块链中所处的位置,hash用来辨识惟一的Block/Header对象。

通过以上的设计,Block结构体的所有重要成员,都被存储进了底层数据库。当所有Block对象的信息都已经写进数据库后,我们就可以使用BlockChain结构体来处理整个块链。

相关文章

网友评论

      本文标题:以太坊源码解读 Block类及其储存

      本文链接:https://www.haomeiwen.com/subject/onbthqtx.html