CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-ethereumjs--block

Provides Block serialization and help functions for Ethereum blockchain operations

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

consensus-operations.mddocs/

Consensus Operations

Support for Ethereum consensus mechanisms including Ethash Proof-of-Work and Clique Proof-of-Authority.

Capabilities

Clique Proof-of-Authority Functions

Functions for working with Clique PoA consensus mechanism, including signer validation and epoch transitions.

/**
 * Fixed vanity bytes length in Clique extra data (32 bytes)
 */
const CLIQUE_EXTRA_VANITY: number;

/**
 * Fixed seal bytes length in Clique extra data (65 bytes)
 */
const CLIQUE_EXTRA_SEAL: number;

/**
 * Returns PoA clique signature hash without seal
 * Used for signature verification and signing operations
 * @param header - Block header to get signature hash for
 * @returns Signature hash as Uint8Array
 */
function cliqueSigHash(header: BlockHeader): Uint8Array;

/**
 * Checks if header represents an epoch transition block
 * Epoch transitions occur every N blocks and contain signer list updates
 * @param header - Block header to check
 * @returns True if this is an epoch transition header
 */
function cliqueIsEpochTransition(header: BlockHeader): boolean;

/**
 * Returns extra vanity data from Clique header
 * Vanity data is the first 32 bytes of extra data field
 * @param header - Block header with Clique extra data
 * @returns Vanity data as Uint8Array (32 bytes)
 */
function cliqueExtraVanity(header: BlockHeader): Uint8Array;

/**
 * Returns extra seal data from Clique header
 * Seal data is the last 65 bytes of extra data field containing the signature
 * @param header - Block header with Clique extra data
 * @returns Seal data as Uint8Array (65 bytes)
 */
function cliqueExtraSeal(header: BlockHeader): Uint8Array;

/**
 * Returns the list of signers from an epoch transition header
 * Only valid for epoch transition blocks, throws error otherwise
 * @param header - Epoch transition block header
 * @returns Array of signer addresses
 */
function cliqueEpochTransitionSigners(header: BlockHeader): Address[];

/**
 * Returns the signer address from a Clique block header
 * Recovers the address from the signature in the seal data
 * @param header - Block header with Clique signature
 * @returns Address of the block signer
 */
function cliqueSigner(header: BlockHeader): Address;

/**
 * Verifies signature against a list of authorized signers
 * Checks if the block signer is authorized and signature is valid
 * @param header - Block header with Clique signature
 * @param signerList - Array of authorized signer addresses
 * @returns True if signature is valid and signer is authorized
 */
function cliqueVerifySignature(header: BlockHeader, signerList: Address[]): boolean;

Usage Examples:

import { 
  cliqueSigner, 
  cliqueVerifySignature, 
  cliqueIsEpochTransition,
  cliqueEpochTransitionSigners,
  CLIQUE_EXTRA_VANITY,
  CLIQUE_EXTRA_SEAL 
} from "@ethereumjs/block";

// Working with a Clique PoA block header
const cliqueHeader = createBlockHeaderFromRPC(cliqueBlockData);

// Get the signer of the block
const signerAddress = cliqueSigner(cliqueHeader);
console.log("Block signed by:", signerAddress.toString());

// Verify the signature against authorized signers
const authorizedSigners = [
  Address.fromString("0x1234..."),
  Address.fromString("0x5678..."),
  Address.fromString("0x9abc..."),
];

const isValidSignature = cliqueVerifySignature(cliqueHeader, authorizedSigners);
console.log("Signature valid:", isValidSignature);

// Check if this is an epoch transition
const isEpochTransition = cliqueIsEpochTransition(cliqueHeader);
console.log("Is epoch transition:", isEpochTransition);

if (isEpochTransition) {
  // Get new signer list from epoch transition block
  const newSigners = cliqueEpochTransitionSigners(cliqueHeader);
  console.log("New signer list:", newSigners.map(addr => addr.toString()));
}

// Examine extra data structure
console.log("Vanity length:", CLIQUE_EXTRA_VANITY); // 32
console.log("Seal length:", CLIQUE_EXTRA_SEAL); // 65
console.log("Total extra data length:", cliqueHeader.extraData.length);

Clique Block Creation

Functions for creating sealed Clique blocks with proper signatures.

/**
 * Creates a sealed Clique PoA block with signature
 * @param blockData - Block data object
 * @param cliqueSigner - Signer private key (32 bytes)
 * @param opts - Block options
 * @returns Sealed Block instance with Clique signature
 */
function createSealedCliqueBlock(
  blockData?: BlockData,
  cliqueSigner: Uint8Array,
  opts?: BlockOptions
): Block;

/**
 * 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 with Clique signature
 */
function createSealedCliqueBlockHeader(
  headerData?: HeaderData,
  cliqueSigner: Uint8Array,
  opts?: BlockOptions
): BlockHeader;

Usage Examples:

import { createSealedCliqueBlock, createSealedCliqueBlockHeader } from "@ethereumjs/block";

// Private key for signing (32 bytes)
const signerPrivateKey = new Uint8Array([
  // ... 32 bytes of private key
]);

// Create sealed Clique block
const sealedBlock = createSealedCliqueBlock({
  header: {
    number: 100n,
    gasLimit: 8000000n,
    timestamp: Math.floor(Date.now() / 1000),
    extraData: new Uint8Array(32 + 65), // Vanity + seal space
  },
  transactions: [],
}, signerPrivateKey);

// Create sealed Clique header only
const sealedHeader = createSealedCliqueBlockHeader({
  number: 100n,
  gasLimit: 8000000n,
  timestamp: Math.floor(Date.now() / 1000),
  extraData: new Uint8Array(32 + 65), // Vanity + seal space
}, signerPrivateKey);

// Verify the sealed block
const signerAddress = cliqueSigner(sealedBlock.header);
console.log("Block sealed by:", signerAddress.toString());

// The signature should be valid
const isValid = cliqueVerifySignature(sealedBlock.header, [signerAddress]);
console.log("Signature valid:", isValid);

Ethash Proof-of-Work Functions

Functions for working with Ethash PoW consensus mechanism and difficulty calculations.

/**
 * Calculates canonical difficulty for Ethash PoW consensus
 * Uses the difficulty adjustment algorithm based on block time and parent difficulty
 * Includes difficulty bomb adjustments for specific hard forks
 * @param block - Current block
 * @param parentBlock - Parent block for difficulty calculation
 * @returns Canonical difficulty value for the block
 */
function ethashCanonicalDifficulty(block: Block, parentBlock: Block): bigint;

Usage Examples:

import { ethashCanonicalDifficulty, createBlock } from "@ethereumjs/block";

// Create parent block (PoW era)
const parentBlock = createBlock({
  header: {
    number: 1000000n,
    difficulty: 17179869184n, // ~17 billion
    timestamp: 1609459200n, // Jan 1, 2021
  },
});

// Create child block
const childBlock = createBlock({
  header: {
    number: 1000001n,
    timestamp: 1609459215n, // 15 seconds later (target is ~13-15s)
  },
});

// Calculate what the difficulty should be
const canonicalDifficulty = ethashCanonicalDifficulty(childBlock, parentBlock);
console.log("Parent difficulty:", parentBlock.header.difficulty);
console.log("Canonical difficulty:", canonicalDifficulty);

// The difficulty should be similar since block time is close to target
const difficultyChange = canonicalDifficulty - parentBlock.header.difficulty;
console.log("Difficulty change:", difficultyChange);
console.log("Percentage change:", Number(difficultyChange * 100n / parentBlock.header.difficulty));

Difficulty Calculations

The difficulty adjustment algorithm varies by consensus mechanism and network upgrade.

/**
 * Difficulty calculation interface
 */
interface DifficultyCalculation {
  /**
   * Calculates canonical difficulty using Ethash algorithm
   * Factors include:
   * - Parent difficulty
   * - Block time vs target time
   * - Difficulty bomb adjustments
   * - Uncle count (pre-Byzantium)
   */
  ethashCanonicalDifficulty(block: Block, parentBlock: Block): bigint;

  /**
   * Header-level difficulty calculation
   * Available as method on BlockHeader class
   */
  ethashCanonicalDifficulty(parentBlockHeader: BlockHeader): bigint;
}

Usage Examples:

import { createBlockHeader } from "@ethereumjs/block";

// Example of difficulty calculation with different block times
const parentHeader = createBlockHeader({
  number: 5000000n,
  difficulty: 1000000000000000n, // 1 petahash
  timestamp: 1609459200n,
});

// Fast block (10 seconds) - difficulty should increase
const fastChildHeader = createBlockHeader({
  number: 5000001n,
  timestamp: 1609459210n, // 10 seconds later
});

// Slow block (30 seconds) - difficulty should decrease  
const slowChildHeader = createBlockHeader({
  number: 5000001n,
  timestamp: 1609459230n, // 30 seconds later
});

const fastDifficulty = fastChildHeader.ethashCanonicalDifficulty(parentHeader);
const slowDifficulty = slowChildHeader.ethashCanonicalDifficulty(parentHeader);

console.log("Parent difficulty:", parentHeader.difficulty);
console.log("Fast block difficulty:", fastDifficulty);
console.log("Slow block difficulty:", slowDifficulty);

// Fast blocks get higher difficulty, slow blocks get lower difficulty
console.log("Fast block increase:", fastDifficulty > parentHeader.difficulty);
console.log("Slow block decrease:", slowDifficulty < parentHeader.difficulty);

Consensus Network Configuration

Different networks use different consensus mechanisms and require appropriate configuration.

/**
 * Network-specific consensus configuration
 */
interface ConsensusConfiguration {
  /**
   * Ethash PoW networks: mainnet, ropsten (historical)
   * Use ethashCanonicalDifficulty for difficulty calculations
   */
  ethash: {
    networks: string[];
    methods: ["ethashCanonicalDifficulty"];
  };

  /**
   * Clique PoA networks: goerli, rinkeby (historical)
   * Use clique* functions for signer validation
   */
  clique: {
    networks: string[];
    methods: [
      "cliqueSigner",
      "cliqueVerifySignature", 
      "cliqueIsEpochTransition",
      "cliqueEpochTransitionSigners"
    ];
  };

  /**
   * Proof-of-Stake networks: mainnet (post-merge), sepolia
   * No consensus-specific functions needed at block level
   */
  pos: {
    networks: string[];
    methods: [];
  };
}

Usage Examples:

import { Common } from "@ethereumjs/common";
import { createBlock, cliqueSigner } from "@ethereumjs/block";

// Configure for different networks
const mainnetCommon = new Common({ chain: 'mainnet', hardfork: 'london' }); // PoW era
const goerliCommon = new Common({ chain: 'goerli' }); // Clique PoA
const sepoliaCommon = new Common({ chain: 'sepolia' }); // PoS

// Create blocks for different networks
const mainnetBlock = createBlock(blockData, { common: mainnetCommon });
const goerliBlock = createBlock(blockData, { common: goerliCommon });
const sepoliaBlock = createBlock(blockData, { common: sepoliaCommon });

// Use appropriate consensus functions
if (goerliCommon.consensusType() === 'poa') {
  const signer = cliqueSigner(goerliBlock.header);
  console.log("Goerli block signer:", signer.toString());
}

if (mainnetCommon.consensusType() === 'pow') {
  // Would use ethashCanonicalDifficulty for PoW validation
  console.log("Mainnet PoW block difficulty:", mainnetBlock.header.difficulty);
}

console.log("Sepolia consensus:", sepoliaCommon.consensusType()); // 'pos'

docs

block-operations.md

consensus-operations.md

header-operations.md

index.md

utility-functions.md

tile.json