Skip to main content

Wrapping up

At this point, you’ve walked through the foundational mental models behind the OP Stack, from how Layer 2s inherit security through state commitments and data availability, to how modular rollups restructure traditional blockchain responsibilities into flexible, interoperable components.

You’ve seen how data flows from Ethereum to L2 and back again. You’ve looked at what happens when that flow is disrupted, by reorgs, fault proofs, or message mismatches. You’ve broken down what each component in the system does and why it matters.

More importantly, you’ve built the kind of context that lets you ask better questions when things go wrong.

From here, you can start exploring the design docs, dive into the repositories, or contribute to the system’s governance. What you build next depends on your specialization (governance, interop, etc.), but this foundation will carry you through all of it.

You’re ready! Let’s keep going.

🧠 Knowledge Check

Q1: What are the components of an output root posted by OP Stack to Ethereum?

Solution

An output root is a hash derived from:

  • The L2 state root
  • The storage root of the withdrawal contract
  • The latest L1 block hash
  • A version number

Together, these components commit to the entire L2 state and make withdrawal verification and fault proofs possible.

Q2: Why are reorgs a risk for deposits from L1 to L2?

Solution

Because deposits depend on L1 logs being final. If the L1 block containing a deposit gets reorged out, the deposit event might disappear.

The OP Stack mitigates this by delaying deposit inclusion on L2 — waiting a few Ethereum blocks before treating the deposit as canonical.

Q3: What is the formal interface of the derivation and execution process?

Solution
  • Derivation: derive(S_prev, DA) → { payload | null }
  • Execution: execute(S_prev, payload) → S_next

Together, these form the state transition function of the rollup.

Q4: How does the OP Stack ensure that any invalid state transition can be challenged?

Solution

By using fault proofs, which re-execute transitions using:

  • The previous and next state roots
  • The DA layer
  • The same derivation and execution logic

If the computed state doesn't match the posted commitment, the transition is invalid. The MIPS VM and PreImageOracle are used to execute disputes deterministically on L1.

Q5: What is the role of the op-node and op-geth in the modular stack?

Solution
  • op-node: Consensus client. It handles derivation, sequencing, and communication with the engine API.
  • op-geth: Execution client. It runs the EVM, processes deposit transactions, and executes payloads.

Together, they form the rollup’s version of consensus and execution.

Q6: What happens if a sequencer fails to include a deposit within 12 hours?

Solution

The sequencer’s L2 chain becomes non-canonical. Forced inclusion mechanisms kick in, ensuring that the deposit is eventually included regardless of sequencer behavior.

This ensures censorship resistance and enforces the order of L1-originating messages.

Q7: What’s the difference between a precompile and a predeploy?

Solution
  • Precompiles: Native code at fixed addresses (e.g. P256VERIFY). Requires a protocol upgrade to change.
  • Predeploys: EVM bytecode at fixed addresses (e.g. L1Block, GasPriceOracle). Can be proxies, easier to upgrade, and used like normal contracts.

Q8: What does the L2 COINBASE opcode return on the OP Stack?

Solution

It returns the sequencer’s fee wallet address, not a miner or validator address. This remains constant across blocks, unlike Ethereum where it changes per block.

Q9: Why is address aliasing used in OP Stack?

Solution

To prevent L1 contracts from impersonating L2 contracts due to address collisions.

When an L1 contract sends a message to L2, its address is modified by adding a constant offset (+0x1111...1111) so that it doesn't conflict with existing L2 contract addresses.

Q10: What is the purpose of L2ToL1MessagePasser?

Solution

It records all L2-initiated withdrawals. This storage root is used as part of the output root commitment, and is checked during withdrawal proofs on L1 to ensure the withdrawal was indeed initiated.

🧠 What Would Happen If...

These questions are meant to stretch your mental model, to help you reason about edge cases, adversarial scenarios, and design tradeoffs in the OP Stack.

Q11: What would happen if the sequencer includes a deposit out of order?

Solution

That block would be invalid.

Deposits must be included in the exact order they were emitted on L1. If a sequencer includes them out of order, it breaks the determinism of state derivation. Honest nodes would reject the block, and a fault proof could challenge it. Canonicality is enforced by the protocol.

Q12: What happens if an L1 contract tries to call an L2 contract that checks for a specific msg.sender?

Solution

If the L2 contract is expecting the original L1 address, the check will fail.

Due to address aliasing, msg.sender appears as L1_address + ALIAS_OFFSET. Developers must either:

  • Account for aliasing in their checks, or
  • Use predeploys like L2CrossDomainMessenger that abstract away aliasing details.

Q13: What happens if data posted in a blob becomes unavailable after the fact?

Solution

Anyone trying to verify the associated state transition, e.g., in a fault proof, would fail to reconstruct the transition.

This breaks the assumption of verifiability. DA is part of the trust model. Without it, the system becomes non-provable and no longer secure. This is why Ethereum DA is often preferred: it ensures full reconstructibility.

Q14: What if a user starts a withdrawal on L2, but the sequencer censors it and never posts the output root?

Solution

The system has permissionless output proposals and fault proofs (or will, on most OP Chains). Eventually, someone else, not the sequencer, can post the correct output root to L1.

The dispute game can then be used to resolve state. This protects users from sequencer censorship, assuming a working fault-proof system and availability of L2 data.

Q15: What if two rollups post the same contract to the same address on L2, but with different bytecode?

Solution

This is totally possible, because rollups are separate chains. Even if both use the same address (e.g. via CREATE2), the bytecode may differ.

That’s why trust in a contract must be scoped to its specific chain context.