美文网首页
以太坊源码解读 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