Block header functionality with all consensus-critical fields, validation methods, and EIP-specific calculations.
The BlockHeader class represents an Ethereum block header with all consensus-critical fields.
/**
* Class representing a block header in the Ethereum network
*/
class BlockHeader {
readonly parentHash: Uint8Array;
readonly uncleHash: Uint8Array;
readonly coinbase: Address;
readonly stateRoot: Uint8Array;
readonly transactionsTrie: Uint8Array;
readonly receiptTrie: Uint8Array;
readonly logsBloom: Uint8Array;
readonly difficulty: bigint;
readonly number: bigint;
readonly gasLimit: bigint;
readonly gasUsed: bigint;
readonly timestamp: bigint;
readonly extraData: Uint8Array;
readonly mixHash: Uint8Array;
readonly nonce: Uint8Array;
readonly baseFeePerGas?: bigint;
readonly withdrawalsRoot?: Uint8Array;
readonly blobGasUsed?: bigint;
readonly excessBlobGas?: bigint;
readonly parentBeaconBlockRoot?: Uint8Array;
readonly requestsHash?: Uint8Array;
readonly common: Common;
/**
* EIP-4399: mixHash as prevRandao for PoS networks
* @returns mixHash field interpreted as prevRandao
*/
get prevRandao(): Uint8Array;
/**
* Returns the hash of the block header
* @returns Header hash as Uint8Array
*/
hash(): Uint8Array;
/**
* Returns the RLP serialization of the header
* @returns RLP-encoded header as Uint8Array
*/
serialize(): Uint8Array;
/**
* Checks if this is the genesis block header
* @returns True if this is the genesis header
*/
isGenesis(): boolean;
/**
* Returns raw bytes array representation of the header
* @returns Array of raw field bytes
*/
raw(): BlockHeaderBytes;
/**
* Validates gas limit against parent header
* @param parentBlockHeader - Parent block header for validation
*/
validateGasLimit(parentBlockHeader: BlockHeader): void;
/**
* Calculates the next block's base fee (EIP-1559)
* @returns Next block's base fee per gas
*/
calcNextBaseFee(): bigint;
/**
* Returns the current blob gas price (EIP-4844)
* @returns Blob gas price in wei
*/
getBlobGasPrice(): bigint;
/**
* Calculates blob data fee for a number of blobs (EIP-4844)
* @param numBlobs - Number of blobs
* @returns Total data fee for blobs
*/
calcDataFee(numBlobs: number): bigint;
/**
* Calculates next block's excess blob gas (EIP-4844)
* @param childCommon - Common instance for child block
* @returns Next block's excess blob gas
*/
calcNextExcessBlobGas(childCommon: Common): bigint;
/**
* Calculates next block's blob gas price (EIP-4844)
* @param childCommon - Common instance for child block
* @returns Next block's blob gas price
*/
calcNextBlobGasPrice(childCommon: Common): bigint;
/**
* Calculates canonical difficulty for Ethash PoW
* @param parentBlockHeader - Parent block header
* @returns Canonical difficulty value
*/
ethashCanonicalDifficulty(parentBlockHeader: BlockHeader): bigint;
/**
* Returns JSON representation of the header
* @returns Header as JSON object
*/
toJSON(): JSONHeader;
/**
* Returns compact error string representation
* @returns Error string
*/
errorStr(): string;
}Tree-shakeable factory methods for creating BlockHeader instances from various data sources.
/**
* Creates a block header from header data dictionary
* @param headerData - Header data object
* @param opts - Block options
* @returns BlockHeader instance
*/
function createBlockHeader(headerData?: HeaderData, opts?: BlockOptions): BlockHeader;
/**
* Creates a block header from raw bytes array
* @param values - Header bytes array
* @param opts - Block options
* @returns BlockHeader instance
*/
function createBlockHeaderFromBytesArray(
values: BlockHeaderBytes,
opts?: BlockOptions
): BlockHeader;
/**
* Creates a block header from RLP-serialized data
* @param serializedHeaderData - RLP-encoded header data
* @param opts - Block options
* @returns BlockHeader instance
*/
function createBlockHeaderFromRLP(
serializedHeaderData: Uint8Array,
opts?: BlockOptions
): BlockHeader;
/**
* Creates a sealed Clique PoA block header with signature
* @param headerData - Header data object
* @param cliqueSigner - Signer private key (32 bytes)
* @param opts - Block options
* @returns Sealed BlockHeader instance
*/
function createSealedCliqueBlockHeader(
headerData?: HeaderData,
cliqueSigner: Uint8Array,
opts?: BlockOptions
): BlockHeader;
/**
* Creates a block header from JSON-RPC response format
* @param blockParams - JSON-RPC block object
* @param options - Block options
* @returns BlockHeader instance
*/
function createBlockHeaderFromRPC(
blockParams: JSONRPCBlock,
options?: BlockOptions
): BlockHeader;Usage Examples:
import {
createBlockHeader,
createBlockHeaderFromRLP,
createBlockHeaderFromRPC
} from "@ethereumjs/block";
// Create from header data
const header = createBlockHeader({
number: 1n,
gasLimit: 8000000n,
gasUsed: 5000000n,
timestamp: Math.floor(Date.now() / 1000),
baseFeePerGas: 1000000000n, // 1 gwei
});
// Create from RLP data
const rlpData = new Uint8Array([/* RLP bytes */]);
const headerFromRLP = createBlockHeaderFromRLP(rlpData);
// Create from JSON-RPC response
const jsonRpcBlock = {
number: "0x1",
gasLimit: "0x7a1200",
gasUsed: "0x4c4b40",
timestamp: "0x60a7d8c0",
baseFeePerGas: "0x3b9aca00",
// ... other fields
};
const headerFromRPC = createBlockHeaderFromRPC(jsonRpcBlock);
console.log("Header hash:", header.hash());
console.log("Is genesis:", header.isGenesis());
console.log("Block number:", header.number);Methods for handling EIP-1559 base fee calculations and fee market dynamics.
/**
* EIP-1559 fee market calculations
*/
interface FeeMarketOperations {
/**
* Calculates the next block's base fee based on parent block gas usage
* Uses EIP-1559 formula: adjust base fee based on gas usage relative to target
*/
calcNextBaseFee(): bigint;
/**
* Current base fee per gas for this block
* Only available on blocks after EIP-1559 activation
*/
readonly baseFeePerGas?: bigint;
}Usage Examples:
import { createBlockHeader } from "@ethereumjs/block";
// Create header with EIP-1559 fields
const header = createBlockHeader({
number: 12965000n, // Post-London fork
gasLimit: 15000000n,
gasUsed: 10000000n, // 66% of gas limit
baseFeePerGas: 20000000000n, // 20 gwei
});
// Calculate next block's base fee
const nextBaseFee = header.calcNextBaseFee();
console.log("Current base fee:", header.baseFeePerGas);
console.log("Next base fee:", nextBaseFee);
// The base fee will increase since gas used > gas target (50% of limit)
console.log("Fee adjustment:", nextBaseFee > header.baseFeePerGas! ? "increase" : "decrease");Methods for handling EIP-4844 blob gas calculations and blob transaction fees.
/**
* EIP-4844 blob gas operations
*/
interface BlobGasOperations {
/**
* Current blob gas used in this block
*/
readonly blobGasUsed?: bigint;
/**
* Current excess blob gas value
*/
readonly excessBlobGas?: bigint;
/**
* Returns the current blob gas price based on excess blob gas
*/
getBlobGasPrice(): bigint;
/**
* Calculates total data fee for a number of blobs
* @param numBlobs - Number of blobs to calculate fee for
*/
calcDataFee(numBlobs: number): bigint;
/**
* Calculates next block's excess blob gas
* @param childCommon - Common instance for the child block
*/
calcNextExcessBlobGas(childCommon: Common): bigint;
/**
* Calculates next block's blob gas price
* @param childCommon - Common instance for the child block
*/
calcNextBlobGasPrice(childCommon: Common): bigint;
}Usage Examples:
import { createBlockHeader, Common } from "@ethereumjs/block";
// Create header with EIP-4844 fields (post-Cancun fork)
const common = new Common({ chain: 'mainnet', hardfork: 'cancun' });
const header = createBlockHeader({
number: 19426587n, // Post-Cancun fork
blobGasUsed: 262144n, // 2 blobs worth of gas
excessBlobGas: 0n,
}, { common });
// Get current blob gas price
const currentBlobGasPrice = header.getBlobGasPrice();
console.log("Current blob gas price:", currentBlobGasPrice);
// Calculate data fee for different numbers of blobs
const fee1Blob = header.calcDataFee(1);
const fee6Blobs = header.calcDataFee(6); // Max blobs per transaction
console.log("Fee for 1 blob:", fee1Blob);
console.log("Fee for 6 blobs:", fee6Blobs);
// Calculate next block's blob gas values
const nextExcessBlobGas = header.calcNextExcessBlobGas(common);
const nextBlobGasPrice = header.calcNextBlobGasPrice(common);
console.log("Next excess blob gas:", nextExcessBlobGas);
console.log("Next blob gas price:", nextBlobGasPrice);Methods for handling beacon chain withdrawals.
/**
* EIP-4895 withdrawals support
*/
interface WithdrawalsSupport {
/**
* Withdrawals trie root hash
* Present in blocks after EIP-4895 activation (Shanghai fork)
*/
readonly withdrawalsRoot?: Uint8Array;
}Methods for validating block headers against consensus rules.
/**
* Header validation operations
*/
interface HeaderValidation {
/**
* Validates gas limit is within bounds relative to parent
* Ensures gas limit changes don't exceed maximum allowed adjustment
*/
validateGasLimit(parentBlockHeader: BlockHeader): void;
/**
* Calculates canonical difficulty for Ethash PoW consensus
* Uses difficulty adjustment algorithm based on block time and parent difficulty
*/
ethashCanonicalDifficulty(parentBlockHeader: BlockHeader): bigint;
}Usage Examples:
import { createBlockHeader } from "@ethereumjs/block";
const parentHeader = createBlockHeader({
number: 100n,
gasLimit: 8000000n,
timestamp: 1609459200n, // Jan 1, 2021
difficulty: 1000000n,
});
const childHeader = createBlockHeader({
number: 101n,
gasLimit: 8100000n, // Slight increase
timestamp: 1609459215n, // 15 seconds later
difficulty: 1000500n,
});
// Validate gas limit adjustment
try {
childHeader.validateGasLimit(parentHeader);
console.log("Gas limit adjustment is valid");
} catch (error) {
console.error("Invalid gas limit:", error.message);
}
// Calculate canonical difficulty for PoW
const canonicalDifficulty = childHeader.ethashCanonicalDifficulty(parentHeader);
console.log("Expected difficulty:", canonicalDifficulty);
console.log("Actual difficulty:", childHeader.difficulty);Methods for converting headers to various formats.
/**
* Header serialization methods
*/
interface HeaderSerialization {
/** Returns RLP-encoded header as Uint8Array */
serialize(): Uint8Array;
/** Returns raw bytes array representation */
raw(): BlockHeaderBytes;
/** Returns JSON representation */
toJSON(): JSONHeader;
}Usage Examples:
import { createBlockHeader } from "@ethereumjs/block";
const header = createBlockHeader({
number: 1n,
gasLimit: 8000000n,
timestamp: Math.floor(Date.now() / 1000),
});
// Get different serialization formats
const rlpBytes = header.serialize();
const rawBytes = header.raw();
const jsonFormat = header.toJSON();
// Header hash and basic info
const headerHash = header.hash();
const isGenesis = header.isGenesis();
console.log("Header hash:", headerHash);
console.log("RLP size:", rlpBytes.length);
console.log("JSON format:", JSON.stringify(jsonFormat, null, 2));
console.log("Block number:", header.number.toString());
console.log("Gas limit:", header.gasLimit.toString());