Skip to main content

Try it Live

Run Hardfork examples in the interactive playground

    The Merge

    Active Since: Merge (September 15, 2022) Aliases: “paris” (consensus layer name)

    Consensus Change

    Before Merge (Proof of Work):
    • Miners compete to solve computational puzzles
    • Block rewards: 2 ETH + transaction fees
    • DIFFICULTY opcode returns mining difficulty
    After Merge (Proof of Stake):
    • Validators stake 32 ETH to propose blocks
    • Block rewards: Transaction tips only (base fee burned)
    • DIFFICULTY opcode returns beacon chain randomness (PREVRANDAO)

    Changes Introduced

    PREVRANDAO Opcode

    Opcode: 0x44 (replaces DIFFICULTY) Before Merge:
    • Returns current block’s mining difficulty
    • Used for difficulty-based calculations
    After Merge:
    • Returns beacon chain randomness (PREVRANDAO)
    • Mix hash from beacon chain for randomness
    • Breaking change: Contracts using DIFFICULTY for mining calculations will break

    Block Production

    Before Merge:
    • Miners propose blocks via PoW
    • Block time: ~13 seconds (variable)
    • Uncle blocks possible
    After Merge:
    • Validators propose blocks via PoS
    • Block time: 12 seconds (fixed)
    • No uncle blocks

    Economics

    Before Merge:
    • Block reward: 2 ETH per block
    • Transaction fees to miners
    • Issuance: ~4.3% annual
    After Merge:
    • Block reward: 0 ETH (only tips)
    • Base fee burned (EIP-1559)
    • Issuance: ~0.5% annual (90% reduction)

    Usage Patterns

    Consensus Detection

    Determine consensus mechanism:
    import { Hardfork } from 'tevm'
    
    function getConsensusInfo(fork: BrandedHardfork) {
      if (fork.isPostMerge()) {
        return {
          consensus: "Proof of Stake",
          blockProducer: "validator",
          blockReward: "0 ETH (tips only)",
          difficultyOpcode: "PREVRANDAO",
          blockTime: "12s (fixed)"
        }
      }
    
      return {
        consensus: "Proof of Work",
        blockProducer: "miner",
        blockReward: "2 ETH + fees",
        difficultyOpcode: "DIFFICULTY",
        blockTime: "~13s (variable)"
      }
    }
    

    Mining Configuration

    Validate mining configuration:
    import { Hardfork } from 'tevm'
    
    function validateMiningConfig(fork: BrandedHardfork, config: MiningConfig) {
      if (fork.isPostMerge() && config.mining) {
        throw new Error(
          "Mining not supported after Merge. " +
          "Ethereum uses Proof of Stake consensus."
        )
      }
    }
    

    Opcode Handling

    Handle DIFFICULTY/PREVRANDAO opcode:
    import { Hardfork } from 'tevm'
    
    function handleDifficultyOpcode(fork: BrandedHardfork, value: bigint) {
      if (fork.isPostMerge()) {
        console.log("PREVRANDAO (beacon randomness):", value)
      } else {
        console.log("DIFFICULTY (mining difficulty):", value)
      }
    }
    

    Block Validation

    Validate block structure:
    import { Hardfork } from 'tevm'
    
    function validateBlock(fork: BrandedHardfork, block: Block) {
      if (fork.isPostMerge()) {
        // PoS validation
        if (block.difficulty !== 0n) {
          throw new Error("PoS blocks must have difficulty = 0")
        }
        if (block.nonce !== 0n) {
          throw new Error("PoS blocks must have nonce = 0")
        }
        if (!block.mixHash) {
          throw new Error("PoS blocks require mixHash (PREVRANDAO)")
        }
      } else {
        // PoW validation
        if (block.difficulty === 0n) {
          throw new Error("PoW blocks must have non-zero difficulty")
        }
      }
    }
    

    Network Configuration

    Check consensus mechanism:
    import { Hardfork } from 'tevm'
    
    function getNetworkType(fork: BrandedHardfork): string {
      return fork.isPostMerge() ? "mainnet-pos" : "mainnet-pow"
    }
    

    EIP References

    Primary:
    • EIP-3675 - Upgrade consensus to Proof of Stake
    • EIP-4399 - Supplant DIFFICULTY opcode with PREVRANDAO

    Impact

    For Validators:
    • Must stake 32 ETH to participate
    • Earn tips + MEV (no base fee)
    • Can be slashed for misbehavior
    For Developers:
    • DIFFICULTY opcode behavior changed
    • Contracts using DIFFICULTY for mining logic will break
    • Block time now consistent (12s)
    • No more uncle blocks
    For Network:
    • 90% reduction in ETH issuance
    • Consistent 12-second block times
    • Finality from Casper FFG (2 epochs = ~13 minutes)
    • 99.95% energy reduction
    For Economics:
    • Deflationary when base fee > issuance
    • More predictable issuance schedule
    • Staking yield replaces mining rewards

    Breaking Changes

    DIFFICULTY Opcode

    Contracts using block.difficulty must update:
    // Before Merge (PoW)
    uint256 randomSeed = block.difficulty;  // Mining difficulty
    
    // After Merge (PoS)
    uint256 randomSeed = block.prevrandao;  // Beacon randomness
    // Note: block.difficulty still works but returns prevrandao
    

    Mining

    All mining-related functionality removed:
    • No block rewards for miners
    • No mining difficulty adjustments
    • No uncle blocks
    • Mining software incompatible with PoS

    See Also

    • hasEIP1559 - Check EIP-1559 base fee availability (London)
    • hasEIP4844 - Check blob transactions availability (Cancun)
    • isAtLeast - General version comparison