Spinning up the proposer
After you have spun up your sequencer, you need to attach a proposer to post your L2 state roots data back onto L1 so we can prove withdrawal validity. The proposer is a critical component that enables trustless L2-to-L1 messaging and creates the authoritative view of L2 state from L1's perspective.
This guide assumes you already have a functioning sequencer and the necessary L1 contracts deployed using op-deployer
. If you haven't set up your sequencer yet, please refer to the sequencer guide first.
To see configuration info for the proposer, check out the configuration page.
Understanding the proposer's role
The proposer (op-proposer
) serves as a crucial bridge between your L2 chain and L1. Its primary responsibilities include:
- State commitment: Proposing L2 state roots to L1 at regular intervals
- Withdrawal enablement: Providing the necessary commitments for users to prove and finalize withdrawals
The proposer creates dispute games via the DisputeGameFactory
contract.
Prerequisites
Before setting up your proposer, ensure you have:
Running infrastructure:
- An operational sequencer node
- Access to a L1 RPC endpoint
Network information:
- Your L2 chain ID and network configuration
- L1 network details (chain ID, RPC endpoints)
Software installation
Build from source
Clone and build op-proposer
# If you don't already have the optimism repository from the sequencer setup
git clone https://github.com/ethereum-optimism/optimism.git
cd optimism
# Checkout the latest release tag
git checkout op-proposer/v1.10.0
# Build op-proposer
cd op-proposer
just
# Binary will be available at ./bin/op-proposer
This uses op-proposer/v1.10.0
which is compatible with op-node/v1.13.3 and op-geth/v1.101511.0 from spinning up the sequencer guide.
Always check the release notes (opens in a new tab) for compatibility.
Verify installation
Run this command to verify the installation.
./bin/op-proposer --version
Configuration setup
1. Organize your workspace
at the same level as your sequencer from the [sequencer tutorial](link-to-the sequencer tutorial):
# Create proposer directory at the same level as your sequencer
mkdir proposer-node
cd proposer-node
# Create scripts directory
mkdir scripts
2. Extract DisputeGameFactory address
Extract the DisputeGameFactory
contract address from your op-deployer output:
# Navigate to proposer directory
cd proposer-node
# Copy the state.json from .deployer directory created while using op-deployer
# Update the path if your .deployer directory is located elsewhere
cp ../.deployer/state.json .
# Extract the DisputeGameFactory address
GAME_FACTORY_ADDRESS=$(cat state.json | jq -r '.opChainDeployments[0].disputeGameFactoryProxyAddress')
echo "DisputeGameFactory Address: $GAME_FACTORY_ADDRESS"
The proposer only needs the DisputeGameFactory
address to submit proposals.
The GAME_TYPE=0
represents the standard fault proof game type.
3. Set up environment variables
Create your .env
file with the actual values:
# Create .env file with your actual values
# L1 Configuration - Replace with your actual RPC URL
L1_RPC_URL=https://sepolia.infura.io/v3/YOUR_ACTUAL_INFURA_KEY
# L2 Configuration - Should match your sequencer setup
L2_RPC_URL=http://localhost:8545
ROLLUP_RPC_URL=http://localhost:8547
# Contract addresses - Extract from your op-deployer output
GAME_FACTORY_ADDRESS=YOUR_ACTUAL_GAME_FACTORY_ADDRESS
# Private key - Replace with your actual private key
PRIVATE_KEY=0xYOUR_ACTUAL_PRIVATE_KEY
# Proposer configuration
PROPOSAL_INTERVAL=3600s
GAME_TYPE=0
POLL_INTERVAL=20s
# RPC configuration
PROPOSER_RPC_PORT=8560
Important: Replace ALL placeholder values (YOUR_ACTUAL_*
) with your real configuration values!
4. Get your private key
Get a private key from your wallet.
Proposer configuration
Create scripts/start-proposer.sh
:
#!/bin/bash
source .env
# Path to the op-proposer binary we built
../optimism/op-proposer/bin/op-proposer \
--poll-interval=$POLL_INTERVAL \
--rpc.port=$PROPOSER_RPC_PORT \
--rpc.enable-admin \
--rollup-rpc=$ROLLUP_RPC_URL \
--l1-eth-rpc=$L1_RPC_URL \
--private-key=$PRIVATE_KEY \
--game-factory-address=$GAME_FACTORY_ADDRESS \
--game-type=$GAME_TYPE \
--proposal-interval=$PROPOSAL_INTERVAL \
--num-confirmations=1 \
--resubmission-timeout=30s \
--wait-node-sync=true \
--log.level=info
Your final directory structure should look like:
~/
├── optimism/ # Contains op-proposer binary
├── sequencer-node/ # Your sequencer setup
├── .deployer/ # From op-deployer
│ └── state.json
└── proposer-node/ # Your proposer working directory
├── state.json # Copied from .deployer
├── .env
└── scripts/
└── start-proposer.sh
Starting the proposer
1. Verify prerequisites
Ensure your sequencer and op-node are running:
# Test L1 connectivity
# Note: Make sure you have exported these environment variables to your current shell session:
# export L1_RPC_URL="https://sepolia.infura.io/v3/YOUR_KEY"
# export L2_RPC_URL="http://localhost:8545"
# export ROLLUP_RPC_URL="http://localhost:8547"
curl -X POST -H "Content-Type: application/json" \
--data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' \
$L1_RPC_URL
# Test L2 connectivity
curl -X POST -H "Content-Type: application/json" \
--data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' \
$L2_RPC_URL
# Test rollup node connectivity
curl -X POST -H "Content-Type: application/json" \
--data '{"jsonrpc":"2.0","method":"optimism_syncStatus","params":[],"id":1}' \
$ROLLUP_RPC_URL
2. Start the proposer
# Make the script executable
chmod +x scripts/start-proposer.sh
# Start the proposer
./scripts/start-proposer.sh
Verification
Verify your proposer is working correctly:
Check proposer status
# Monitor proposal activity
curl -X POST -H "Content-Type: application/json" \
--data '{"jsonrpc":"2.0","method":"optimism_outputAtBlock","params":["latest"],"id":1}' \
http://localhost:8547
# Check if your proposer address has enough ETH for gas
# (Replace with your actual proposer address)
curl -X POST -H "Content-Type: application/json" \
--data '{"jsonrpc":"2.0","method":"eth_getBalance","params":["0xYOUR_PROPOSER_ADDRESS","latest"],"id":1}' \
$L1_RPC_URL
Your proposer is now operational!
Next steps
- Learn how to set up the sequencer node for your OP Stack chain.
- For detailed parameter documentation, see the proposer configuration reference.
- For more detail on deploying new dispute games with OPCM, see the docs.
- checkout the migrating to permissionless fault proofs guide
- For cost optimization resources, check out the Fee calculation tools.