This directory contains the complete working implementation that accompanies the Create L2 Rollup tutorial. It provides automated deployment of an OP Stack L2 rollup testnet using official published Docker images.
This implementation deploys a fully functional OP Stack L2 rollup testnet, including:
- L1 Smart Contracts deployed on Sepolia testnet (via op-deployer)
- Execution Client (op-geth) processing transactions
- Consensus Client (op-node) managing rollup consensus
- Batcher (op-batcher) publishing transaction data to L1
- Proposer (op-proposer) submitting state root proposals
- Challenger (op-challenger) monitoring for disputes
| Dependency | Version | Install Command | Purpose |
|---|---|---|---|
| Docker | ^24 | Follow Docker installation guide | Container runtime for OP Stack services |
| Docker Compose | latest | Usually included with Docker Desktop | Multi-container orchestration |
| jq | latest | brew install jq (macOS) / apt install jq (Ubuntu) | JSON processing for deployment data |
| git | latest | Usually pre-installed | Cloning repositories for prestate generation |
For the best experience with correct tool versions, we recommend installing mise:
# Install mise (manages all tool versions automatically) curl https://mise.jdx.dev/install.sh | bash # Install all required tools with correct versions cd docs/create-l2-rollup-example mise installWhy mise? It automatically handles tool installation and version management, preventing compatibility issues.
- Sepolia RPC URL: Get from Infura, Alchemy, or another provider
- Sepolia ETH: At least 2-3 ETH for contract deployment and operations
- Public IP: For P2P networking (use
curl ifconfig.meto find your public IP)
-
Navigate to this code directory:
cd docs/create-l2-rollup-example -
Configure environment variables:
cp .example.env .env # Edit .env with your actual values (L1_RPC_URL, PRIVATE_KEY, L2_CHAIN_ID) -
Download op-deployer:
make init # Download op-deployer -
Deploy and start everything:
make setup # Deploy contracts and configure all services make up # Start all services
-
Verify deployment:
make status # Check service health make test-l1 # Verify L1 connectivity make test-l2 # Verify L2 functionality # Or manually check: docker-compose ps docker-compose logs -f op-node
Copy .example.env to .env and configure the following variables:
# L1 Configuration (Sepolia testnet) # Option 1: Public endpoint (no API key required) L1_RPC_URL="https://ethereum-sepolia-rpc.publicnode.com" L1_BEACON_URL="https://ethereum-sepolia-beacon-api.publicnode.com" # Option 2: Private endpoint (requires API key) # L1_RPC_URL="https://eth-sepolia.g.alchemy.com/v2/YOUR_API_KEY" # L1_BEACON_URL="https://ethereum-sepolia-beacon-api.publicnode.com" # Private key for deployment and operations # IMPORTANT: Never commit this to version control PRIVATE_KEY="YOUR_PRIVATE_KEY_WITHOUT_0x_PREFIX" # Optional: Public IP for P2P networking (defaults to 127.0.0.1 for local testing) P2P_ADVERTISE_IP="127.0.0.1" # Optional: Custom L2 Chain ID (default: 16584) L2_CHAIN_ID="16584"The .env file will be automatically loaded by Docker Compose.
For detailed manual setup instructions, see the Create L2 Rollup tutorial. The tutorial provides step-by-step guidance for setting up each component individually if you prefer not to use the automated approach.
create-l2-rollup-example/ ├── .example.env # Environment variables template ├── docker-compose.yml # Service orchestration ├── Makefile # Automation commands ├── scripts/ │ ├── setup-rollup.sh # Automated deployment script │ └── download-op-deployer.sh # op-deployer downloader └── README.md # This file Generated directories (created during deployment):
deployer/ # op-deployer configuration and outputs ├── .deployer/ # Deployment artifacts (genesis.json, rollup.json, etc.) ├── addresses/ # Generated wallet addresses └── .env # Environment variables batcher/ # op-batcher configuration └── .env # Environment variables proposer/ # op-proposer configuration └── .env # Environment variables challenger/ # op-challenger configuration ├── .env # Challenger-specific environment variables └── data/ # Challenger data directory sequencer/ # op-sequencer configuration ├── .env # op-sequencer environment variables ├── genesis.json # op-geth genesis file ├── jwt.txt # JWT secret for auth RPC ├── rollup.json # op-node rollup configuration └── op-geth-data/ # op-geth data directory | Service | Port | Description |
|---|---|---|
| op-geth | 8545 | HTTP RPC endpoint |
| op-geth | 8546 | WebSocket RPC endpoint |
| op-geth | 8551 | Auth RPC for op-node |
| op-node | 8547 | op-node RPC endpoint |
| op-node | 9222 | P2P networking |
# View all service logs make logs # View specific service logs docker-compose logs -f op-node docker-compose logs -f op-geth # Check service health make status # Restart all services make restart # Restart a specific service docker-compose restart op-batcherBy default, this devnet disables P2P networking entirely to avoid validation warnings when running locally. The --p2p.disable flag is set in docker-compose.yml (line 26).
| Environment | P2P Networking | Reason |
|---|---|---|
| Local devnet | Disabled (default) | Prevents P2P warnings when testing solo without peers |
| Private testnet | Disabled | No other nodes to connect with |
| Public testnet | Enabled | Other nodes need to receive blocks and sync |
| Production mainnet | Enabled | Required for network operation |
- Open
docker-compose.yml - Remove
--p2p.disable # For local devnet only... - Add back the P2P configuration flags:
--p2p.listen.ip=0.0.0.0 --p2p.listen.tcp=9222 --p2p.listen.udp=9222 --p2p.advertise.ip=${P2P_ADVERTISE_IP} --p2p.advertise.tcp=9222 --p2p.advertise.udp=9222 --p2p.sequencer.key=${PRIVATE_KEY}
- Ensure your P2P networking environment is properly configured:
- Set
P2P_ADVERTISE_IPin.envto your public IP address (not 127.0.0.1) - Ensure port 9222 (both TCP and UDP) is accessible from the internet
- Configure proper firewall rules to allow P2P traffic
- Consider setting up bootnodes for better peer discovery
- Set
# Example: Quick enable P2P for testing sed -i '' '/--p2p.disable/d' docker-compose.yml # Then add back P2P flags manually in docker-compose.yml docker-compose restart op-node- Port conflicts: Ensure ports 8545-8551 and 9222 are available
- Insufficient ETH: Make sure your deployment wallet has enough Sepolia ETH
- Network timeouts: Check your L1 RPC URL and network connectivity
- Docker issues: Ensure Docker daemon is running and you have sufficient resources
To reset and redeploy:
# Stop all services and clean up make clean # Re-run setup make setup make up- Never commit private keys to version control
- Use hardware security modules (HSMs) for production deployments
- Monitor gas costs on Sepolia testnet
- Backup wallet addresses and deployment artifacts
This code example accompanies the Create L2 Rollup tutorial in the Optimism documentation. It provides a complete, working implementation that demonstrates the concepts covered in the tutorial.
This code is part of the Optimism documentation. For issues or contributions:
- Documentation issues: Report on the main Optimism repository
- Code improvements: Submit pull requests to the Optimism monorepo
- Tutorial feedback: Use the documentation feedback mechanisms
This code is provided as-is for educational and testing purposes. See the Optimism monorepo for licensing information.