Introduction to Blockchain Blocks
In blockchain technology, blocks serve as containers for valuable information - the fundamental building blocks of any cryptocurrency. Each block contains technical details such as:
- Version number
- Timestamp of creation
- Hash value of the previous block (parent hash)
In Ethereum's architecture, the Block represents one of the core data structures with these key characteristics:
- All account activities are stored as Transactions, listed within each Block
- Transaction execution results are recorded via Receipt objects containing Log entries
- Compressed and encrypted Receipt lists are stored within completed Blocks
- Blocks form a singly-linked list through ParentHash pointers, managed by the BlockChain structure
- The Block structure divides cleanly into Header and Body components
Core Block Structure Analysis
The Ethereum Block consists of several critical components:
type Block struct {
header *Header
uncles []*Header // Block headers
transactions Transactions
hash atomic.Value // Cached hash
size atomic.Value
td *big.Int // Total difficulty
ReceivedAt time.Time
ReceivedFrom interface{} // Block body
}Storage Note: Ethereum separates block headers and bodies for storage efficiency, reflected in the structure's division.
Header Structure Breakdown
The Header contains metadata that defines block properties:
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"`
}Body Structure Components
The Body contains transactional data:
type Body struct {
Transactions []*Transaction
Uncles []*Header
}Header Components: Detailed Examination
The Header serves as the Block's core with these critical elements:
- ParentHash: Pointer to the parent block (genesis blocks excepted)
- UncleHash: RLP hash of the uncles Header array
- Coinbase: Author/miner address receiving transaction fees
- Root: State Trie root hash (MPT structure of all accounts)
- TxHash: Transactions Trie root hash
- ReceiptHash: Receipts Trie root hash
- Bloom: Filter for efficient Log searches
- Difficulty: Block mining difficulty (calculated by consensus)
- Number: Sequential block number (parent +1)
- GasLimit: Theoretical gas consumption cap
- GasUsed: Actual gas consumed by transactions
- Time: Scheduled creation timestamp
- Nonce: 64-bit hash for mining operations
Understanding the Block Body
The Body contains transactional data and special elements:
- Transactions: List of all included transactions
Uncles: Special Header array preventing centralization
- Designed to counteract mining power concentration
- Preserves Ethereum's decentralized nature ๐ Learn more about Ethereum's consensus mechanism
Key Insight: The td (totalDifficulty) represents cumulative blockchain difficulty from genesis to current block.
Block Identification System
Each Block's unique identifier is its RLP hash value:
func (b *Block) Hash() common.Hash {
if hash := b.hash.Load(); hash != nil {
return hash.(common.Hash)
}
v := b.header.Hash()
b.hash.Store(v)
return v
}The hash calculation process:
func (h *Header) Hash() common.Hash {
return rlpHash(h)
}
func rlpHash(x interface{}) (h common.Hash) {
hw := sha3.NewKeccak256()
rlp.Encode(hw, x)
hw.Sum(h[:0])
return h
}Block Creation Process
New blocks are created through:
func NewBlock(header *Header, txs []*Transaction, uncles []*Header, receipts []*Receipt) *Block {
b := &Block{header: CopyHeader(header), td: new(big.Int)}
// Transaction processing
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)
}
// Receipt processing
if len(receipts) == 0 {
b.header.ReceiptHash = EmptyRootHash
} else {
b.header.ReceiptHash = DeriveSha(Receipts(receipts))
b.header.Bloom = CreateBloom(receipts)
}
// Uncle blocks processing
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
}Frequently Asked Questions
Why does Ethereum separate block headers and bodies?
Separation allows more efficient storage and transmission. Light clients can operate with just headers while full nodes process complete blocks.
What purpose do uncle blocks serve?
Uncles prevent mining centralization by rewarding stale blocks, maintaining network decentralization ๐ Explore Ethereum mining mechanics.
How is block difficulty determined?
The consensus algorithm calculates difficulty based on parent block time and difficulty, adjusting mining requirements accordingly.
What's the relationship between GasLimit and GasUsed?
GasLimit sets the theoretical maximum gas per block, while GasUsed shows actual consumption. The network adjusts limits based on usage patterns.
Why does each block contain three trie roots?
The stateRoot, txRoot, and receiptRoot provide Merkle proofs for efficient verification of accounts, transactions, and receipts respectively.
How often does Ethereum produce new blocks?
Ethereum targets a new block approximately every 12-15 seconds, with timestamps adjusted dynamically based on network conditions.