手记

以太坊 区块链的数据结构

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.gotype 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.gotype 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.gotype 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.gotype 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
}



作者:古则
链接:https://www.jianshu.com/p/487c448009e5


0人推荐
随时随地看视频
慕课网APP