以太坊 区块链的数据结构

1.整体结构

BlockChain结构体被用来管理整个区块单向链表,在一个Ethereum客户端软件(比如钱包)中,只会有一个BlockChain对象存在。同Block/Header的关系类似,BlockChain还有一个成员变量类型是HeaderChain, 用来管理所有Header组成的单向链表。当然,HeaderChain在全局范围内也仅有一个对象,并被BlockChain持有(准确说是HeaderChain只会被BlockChain和LightChain持有,LightChain类似于BlockChain,但默认只处理Headers,不过依然可以下载bodies和receipts)。它们的UML关系图如下所示:


image.png

BlockChain 同HeaderChain有诸多类似之处。

  • 比如二者都有相同的ChainConfig对象,有相同的Database接口行为变量以提供[k,v]数据的读取和写入
  • BlockChain 有成员genesisBlock和currentBlock,分别对应创世块和当前块,而HeaderChain则有genesisHeader和currentHeader;
  • BlockChain 有bodyCache,blockCache 等成员用以缓存高频调用对象,而HeaderChain则有headerCache, tdCache, numberCache等缓存成员变量。
  • BlockChain 相对于HeaderChain主要增多了Processor和Validator两个接口行为变量,前者用以执行所有交易对象,后者可以验证诸如Body等数据成员的有效性

共识机制

blockchain及headerchain都有engine成员, 是Ethereum系统里共识算法的一个主要行为接口,它基于符合某种共识算法规范的算法库,提供如下接口

//consensus/consensus.go
type Engine interface {
    // Author retrieves the Ethereum address of the account that minted the given
    // block, which may be different from the header's coinbase if a consensus
    // engine is based on signatures.
    Author(header *types.Header) (common.Address, error)

    // VerifyHeader checks whether a header conforms to the consensus rules of a
    // given engine. Verifying the seal may be done optionally here, or explicitly
    // via the VerifySeal method.
    VerifyHeader(chain ChainReader, header *types.Header, seal bool) error

    // VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers
    // concurrently. The method returns a quit channel to abort the operations and
    // a results channel to retrieve the async verifications (the order is that of
    // the input slice).
    VerifyHeaders(chain ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error)

    // VerifyUncles verifies that the given block's uncles conform to the consensus
    // rules of a given engine.
    VerifyUncles(chain ChainReader, block *types.Block) error

    // VerifySeal checks whether the crypto seal on a header is valid according to
    // the consensus rules of the given engine.
    VerifySeal(chain ChainReader, header *types.Header) error

    // Prepare initializes the consensus fields of a block header according to the
    // rules of a particular engine. The changes are executed inline.
    Prepare(chain ChainReader, header *types.Header) error

    // Finalize runs any post-transaction state modifications (e.g. block rewards)
    // and assembles the final block.
    // Note: The block header and state database might be updated to reflect any
    // consensus rules that happen at finalization (e.g. block rewards).
    Finalize(chain ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction,
        uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error)

    // Seal generates a new block for the given input block with the local miner's
    // seal place on top.
    Seal(chain ChainReader, block *types.Block, stop <-chan struct{}) (*types.Block, error)

    // CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty
    // that a new block should have.
    CalcDifficulty(chain ChainReader, time uint64, parent *types.Header) *big.Int

    // APIs returns the RPC APIs this consensus engine provides.
    APIs(chain ChainReader) []rpc.API
}

等一系列涉及到数据合法性的关键函数。不仅仅BlockChain和HeaderChain结构体,在Ethereum系统里,所有跟验证区块对象相关的操作都会调用Engine行为接口来完成

目前存在两种共识算法规范,

  • 一种是基于POW(proof-of-work),叫Ethash (consensus/ethash/)
  • 另一种基于POW(proof-of-authority),叫Clique(consensus/clique)

数据结构

  • BlockChain
//core/blockchain.go
type BlockChain struct {
    chainConfig *params.ChainConfig // Chain & network configuration
    cacheConfig *CacheConfig        // Cache configuration for pruning

    db     ethdb.Database // Low level persistent database to store final content in
    triegc *prque.Prque   // Priority queue mapping block numbers to tries to gc
    gcproc time.Duration  // Accumulates canonical block processing for trie dumping

    hc            *HeaderChain
    rmLogsFeed    event.Feed
    chainFeed     event.Feed
    chainSideFeed event.Feed
    chainHeadFeed event.Feed
    logsFeed      event.Feed
    scope         event.SubscriptionScope
    genesisBlock  *types.Block

    mu      sync.RWMutex // global mutex for locking chain operations
    chainmu sync.RWMutex // blockchain insertion lock
    procmu  sync.RWMutex // block processor lock

    checkpoint       int          // checkpoint counts towards the new checkpoint
    currentBlock     atomic.Value // Current head of the block chain
    currentFastBlock atomic.Value // Current head of the fast-sync chain (may be above the block chain!)

    stateCache   state.Database // State database to reuse between imports (contains state cache)
    bodyCache    *lru.Cache     // Cache for the most recent block bodies
    bodyRLPCache *lru.Cache     // Cache for the most recent block bodies in RLP encoded format
    blockCache   *lru.Cache     // Cache for the most recent entire blocks
    futureBlocks *lru.Cache     // future blocks are blocks added for later processing

    quit    chan struct{} // blockchain quit channel
    running int32         // running must be called atomically
    // procInterrupt must be atomically called
    procInterrupt int32          // interrupt signaler for block processing
    wg            sync.WaitGroup // chain processing wait group for shutting down
        //共识机制
    engine    consensus.Engine
    processor Processor // block processor interface
    validator Validator // block and state validator interface
    vmConfig  vm.Config

    badBlocks *lru.Cache // Bad block cache
}
  • HeaderChain
//core/headerchain.go
type HeaderChain struct {
    config *params.ChainConfig

    chainDb       ethdb.Database
    genesisHeader *types.Header

    currentHeader     atomic.Value // Current head of the header chain (may be above the block chain!)
    currentHeaderHash common.Hash  // Hash of the current head of the header chain (prevent recomputing all the time)

    headerCache *lru.Cache // Cache for the most recent block headers
    tdCache     *lru.Cache // Cache for the most recent block total difficulties
    numberCache *lru.Cache // Cache for the most recent block numbers

    procInterrupt func() bool

    rand   *mrand.Rand
        //共识机制
    engine consensus.Engine
}
  • Block
//core/types/block.go
// Block represents an entire block in the Ethereum blockchain.
type Block struct {
    header       *Header
    uncles       []*Header
    transactions Transactions

    // 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{}
}

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"`
}

type Body struct {
    Transactions []*Transaction
    Uncles       []*Header
}

  • Transaction
//core/types/transaction.go
type Transaction struct {
    data txdata
    // caches
    hash atomic.Value
    size atomic.Value
    from atomic.Value
}

type txdata struct {
    AccountNonce uint64          `json:"nonce"    gencodec:"required"`
    Price        *big.Int        `json:"gasPrice" gencodec:"required"`
    GasLimit     uint64          `json:"gas"      gencodec:"required"`
    Recipient    *common.Address `json:"to"       rlp:"nil"` // nil means contract creation
    Amount       *big.Int        `json:"value"    gencodec:"required"`
    Payload      []byte          `json:"input"    gencodec:"required"`

    // Signature values
    V *big.Int `json:"v" gencodec:"required"`
    R *big.Int `json:"r" gencodec:"required"`
    S *big.Int `json:"s" gencodec:"required"`

    // This is only used when marshaling to JSON.
    Hash *common.Hash `json:"hash" rlp:"-"`
}

type txdataMarshaling struct {
    AccountNonce hexutil.Uint64
    Price        *hexutil.Big
    GasLimit     hexutil.Uint64
    Amount       *hexutil.Big
    Payload      hexutil.Bytes
    V            *hexutil.Big
    R            *hexutil.Big
    S            *hexutil.Big
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,980评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,422评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,130评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,553评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,408评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,326评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,720评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,373评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,678评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,722评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,486评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,335评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,738评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,283评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,692评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,893评论 2 335

推荐阅读更多精彩内容