主页 > imtoken苹果官网下载 > 以太坊区块-区块

以太坊区块-区块

imtoken苹果官网下载 2023-12-02 05:11:22

以太坊区块-区块

以太坊可以看作是一个数据库,数据库数据的变化是由交易催化的。 为了有效有序地管理事务,必须将一个或多个事务组成一个数据块,然后再提交给数据库。 这个数据块称为块。 一个区块不仅包含多笔交易,还记录了一些额外的数据,以便正确提交给数据库。

下图展示了以太坊区块的数据结构和关系。 在讲解块数据结构时,其他数据必须一并呈现。 只有掌握了区块中的数据来源,才能真正了解区块链数据。

以太坊区块结构

区块分为两部分:区块头(Header)和区块体(Body)。 区块头信息量非常丰富。 它不仅与前一个单元建立连接,还记录了一些交易执行信息和矿工工作信息。 上图中,涉及到一个非常重要的概念Trie。 全称是Merkle compressed prefix tree,需要独立解释。

区块头数据解读

各字段数据如下:

父哈希

是一个哈希值,记录了本区块直接引用的父区块的哈希值。 只有通过这个记录,才能将区块有序地组织起来,形成区块链。 并且可以防止父块的内容被修改,因为块哈希不可避免地会因为数据的修改而改变,所以一个块直接或间接地强化了所有的父块,加密算法保证了历史块不能被修改。

一条区块链

sha3叔叔

是一个哈希值,表示该块引用的多个叔块。 区块体中还包含多个叔块的块头信息,sha3Uncles为叔块集合的RLPHASH哈希值。 在比特币中,只有当一个区块被成功挖出并被其他节点接受时,才能获得奖励。 是所有矿工在争夺记账权和联合奖励。 然而,以太坊略有不同。 无法成为主链一部分的孤立块以太坊技术,如果幸运地被后来的块接受到区块链中,它们将成为叔块。 包含孤立块的块有额外的奖励。 一旦孤儿块成为叔块以太坊技术,该块就可以得到统一的奖励。 通过叔块奖励机制,可以减少以太坊的软分叉,平衡网速慢的矿工利益。

矿工

是一个地址,表示该区块被该账户的矿工挖出,挖矿奖励将发放到该账户。

状态根

是一个哈希值,表示本区块所有交易执行完毕后的以太坊状态快照ID。 因为以太坊被描述为一个状态机系统,所以快照 ID 被称为状态哈希。 又因为状态哈希是由所有账户状态根据Merkle前缀树算法生成的,所以称为状态Merkle树的根值。

交易根

是一个哈希值,表示这个区块中的所有交易都会产生一个默克尔树根节点哈希值。 是加密保证的交易集摘要。 通过这个Root,可以直接验证一笔交易是否包含在这个区块中。

收据根

是一个哈希值,也就是默克尔树根节点的哈希值。 由区块交易执行后产生的交易回执信息集合生成。

原木绽放

它是一个 256 长度的字节数组。 从收据中提取,用于快速定位查找交易收据中的智能合约事件信息。

困难

是一个big.Int值,表示这个区块被挖出的难易程度。

数字

是一个big.Int值,表示这个块的高度。 用于标记区块的序号。 在区块链上,区块的高度必须不断增加。

气体限制

它是一个 uint64 值,表示允许此块消耗的 Gas 燃料量。 这个值是根据父块动态调整的。 调整的目的是调整区块可以包含的交易数量。

使用的气体

是一个uint64值,表示该区块所有交易实际消耗的Gas燃料量。

时间戳

它是一个 uint64 值,表示这个块创建的 UTC 时间戳,以秒为单位。 由于以太坊平均14.5s出块(白皮书研究为12秒),所以区块时间戳可以作为时间戳服务,但不能完全信任。

额外数据

它是一个可变长度的Byte数组,最长为32位。 完全由矿工定制,矿工一般会写一些公开宣传的内容或者作为投票使用。

混合哈希

是一个哈希值。 用于验证块是否被正确挖出。 当区块头数据不包含nonce时,它实际上是一个hash值。

随机数

它是一个长度为8的Byte,实际上是一个uint64值。 用于验证块是否被正确挖出。 mixHash 只能使用正确的 nonce 来进行 PoW 工作量证明。

区块体数据解读

区块体中只有两项数据:交易集合和叔块头集合。 正是交易让以太坊世界发生了变化。

以太坊世界态变化过程

从创世状态开始,每个区块中交易的执行推动了以太坊世界状态的转变。 下一个状态是在前一个状态下进行交易或其他操作,使状态从A状态变为B状态。

交易是状态转换的催化酶。 当一个区块中的所有交易都执行完毕后,以太坊会进入一个新的状态。 在状态转换过程中,会记录一些初始变量和结果数据,分别是交易Merkle哈希值transactionsRoot、交易收据Merkle哈希值receiptRoot、事件Bloom值logsBloom、新状态stateRoot的Merkle哈希值。

其他概念

有3个重要的概念,限于篇幅没有说明,后面会一一说明。

MPT:Merkle compressed prefix tree,Merkle Patricia Tree,是一种改进的数据结构,结合了Merkle树和前缀树的优点。 它是以太坊中用于组织和管理账户数据、生成交易集合哈希的重要数据结构。 回执是为了方便零知识证明、索引和搜索交易,将交易执行过程中的一些特定信息编码成交易回执。 工作量证明,以太坊设计的ETHHASH.key代码

以下是以太坊代码中定义的区块头和区块体结构定义代码,所有核心代码都在core/types/block.go文件中:

//core/types/block.go:70
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        uint64         `json:"timestamp"        gencodec:"required"`
   Extra       []byte         `json:"extraData"        gencodec:"required"`
   MixDigest   common.Hash    `json:"mixHash"`
   Nonce       BlockNonce     `json:"nonce"`
}
type Body struct {
	Transactions []*Transaction
	Uncles       []*Header
}

创建块需要调用函数 NewBlock:

func NewBlock(header *Header, txs []*Transaction, uncles []*Header, receipts []*Receipt) *Block {
   b := &Block{header: CopyHeader(header), td: new(big.Int)}
   // TODO: panic if len(txs) != len(receipts)
   if len(txs) == 0 {
      b.header.TxHash = EmptyRootHash
   } else {
      b.header.TxHash = DeriveSha(Transactions(txs))
      b.transactions = make(Transactions, len(txs))
      copy(b.transactions, txs)
   }
   if len(receipts) == 0 {
      b.header.ReceiptHash = EmptyRootHash
   } else {
      b.header.ReceiptHash = DeriveSha(Receipts(receipts))
      b.header.Bloom = CreateBloom(receipts)
   }
   if len(uncles) == 0 {
      b.header.UncleHash = EmptyUncleHash
   } else {
      b.header.UncleHash = CalcUncleHash(uncles)
      b.uncles = make([]*Header, len(uncles))
      for i := range uncles {
         b.uncles[i] = CopyHeader(uncles[i])
      }
   }
   return b
}