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

标签:区块链架构
发布时间:2018年12月27日 价值:20000.00 / 共识:31

一、Block类

  1. type Block struct {
  2. /******header*******/
  3. header *Header
  4. /******header*******/
  5. /******body*********/
  6. uncles []*Header
  7. transactions Transactions
  8. /******body*********/
  9. // caches
  10. hash atomic.Value
  11. size atomic.Value
  12. // Td is used by package core to store the total difficulty
  13. // of the chain up to and including the block.
  14. td *big.Int
  15. // These fields are used by package eth to track
  16. // inter-peer block relay.
  17. ReceivedAt time.Time
  18. ReceivedFrom interface{}
  19. }

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

Header里有哪些内容呢?

  1. type Header struct {
  2. ParentHash common.Hash `json:"parentHash" gencodec:"required"`
  3. UncleHash common.Hash `json:"sha3Uncles" gencodec:"required"`
  4. Coinbase common.Address `json:"miner" gencodec:"required"`
  5. Root common.Hash `json:"stateRoot" gencodec:"required"`
  6. TxHash common.Hash `json:"transactionsRoot" gencodec:"required"`
  7. ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"`
  8. Bloom Bloom `json:"logsBloom" gencodec:"required"`
  9. Difficulty *big.Int `json:"difficulty" gencodec:"required"`
  10. Number *big.Int `json:"number" gencodec:"required"`
  11. GasLimit uint64 `json:"gasLimit" gencodec:"required"`
  12. GasUsed uint64 `json:"gasUsed" gencodec:"required"`
  13. Time *big.Int `json:"timestamp" gencodec:"required"`
  14. Extra []byte `json:"extraData" gencodec:"required"`
  15. MixDigest common.Hash `json:"mixHash" gencodec:"required"`
  16. Nonce BlockNonce `json:"nonce" gencodec:"required"`
  17. }

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结构体来处理整个块链。

  • 分享 收藏
0 条评论
  • 这篇文章暂无评论,赶紧评论一下吧~