Skip to main content
There are a couple of ways to install op-deployer:

    Deployment usage

    Deploying an OP Stack chain involves deploying multiple contracts, which can consume a substantial amount of gas. On testnets like Sepolia, costs may fluctuate significantly depending on network congestion. We recommend ensuring your deployer wallet has a buffer of at least 1.5 to 3.5 ETH , depending on gas prices and configuration. Always check current gas estimates before deploying.
    The base use case for op-deployer is deploying new OP Chains. This process is broken down into three steps:

    init: configure your chain

    To get started with op-deployer, create an intent file that defines your desired chain configuration. Use the built-in op-deployer utility to generate this file:
    op-deployer uses a declarative intent file to determine how a new chain should be configured. Then, it runs through a deployment pipeline to actually deploy the chain.
    op-deployer init \
      --l1-chain-id <chain ID of your L1> \
      --l2-chain-ids <comma-separated list of chain IDs for your L2s> \
      --workdir .deployer \
      --intent-type <standard|custom|standard-overrides>
    
    
    • Replace <l2-chain-id> with the exact value.
    • The --workdir flag specifies the output directory for the generated intent file and related configs. You can name this directory anything you like , .deployer is just an example.
    This command will create a directory called .deployer in your current working directory containing the intent file and an empty state.json file. state.json is populated with the results of your deployment, and never needs to be edited directly. Your intent file will need to be modified to your parameters, but it will initially look something like this:
    Do not use the default addresses in the intent for a production chain! They are generated from the test... junk mnemonic. Any funds they hold will be stolen on a live chain.
    deploymentStrategy = "live"
    configType = "standard-overrides"
    l1ChainID = 11155111# The chain ID of Sepolia (L1) you'll be deploying to.
    fundDevAccounts = true# Whether or not to fund dev accounts using the test... junk mnemonic on L2.
    l1ContractsLocator = "tag://op-contracts/v1.8.0-rc.4"# L1 smart contracts versions
    l2ContractsLocator = "tag://op-contracts/v1.7.0-beta.1+l2-contracts"# L2 smart contracts versions# Delete this table if you are using the shared Superchain contracts on the L1# If you are deploying your own SuperchainConfig and ProtocolVersions contracts, fill in these details
    [superchainRoles]
      proxyAdminOwner = "0x1eb2ffc903729a0f03966b917003800b145f56e2"
      protocolVersionsOwner = "0x79add5713b383daa0a138d3c4780c7a1804a8090"
      guardian = "0x7a50f00e8d05b95f98fe38d8bee366a7324dcf7e"
    
    # List of L2s to deploy. op-deployer can deploy multiple L2s at once
    [[chains]]
    # Your chain's ID, encoded as a 32-byte hex string
      id = "0x00000000000000000000000000000000000000000000000000000a25406f3e60"
    # Update the fee recipient contract
      baseFeeVaultRecipient = "0x100f829718B5Be38013CC7b29c5c62a08D00f1ff"
      l1FeeVaultRecipient = "0xbAEaf33e883068937aB4a50871f2FD52e241013A"
      sequencerFeeVaultRecipient = "0xd0D5D18F0ebb07B7d728b14AAE014eedA814d6BD"
      eip1559DenominatorCanyon = 250
      eip1559Denominator = 50
      eip1559Elasticity = 6
    # Various ownership roles for your chain. When you use op-deployer init, these roles are generated using the# test... junk mnemonic. You should replace these with your own addresses for production chains.
      [chains.roles]
        l1ProxyAdminOwner = "0xdf5a644aed1b5d6cE0DA2aDd778bc5f39d97Ac88"
        l2ProxyAdminOwner = "0xC40445CD88dDa2A410F86F6eF8E00fd52D8381FD"
        systemConfigOwner = "0xB32296E6929F2507dB8153A64b036D175Ac6E89e"
        unsafeBlockSigner = "0xA53526b516df4eEe3791734CE85311569e0eAD78"
        batcher = "0x8680d36811420359093fd321ED386a6e76BE2AF3"
        proposer = "0x41b3B204099771aDf857F826015703A1030b6675"
        challenger = "0x7B51A480dAeE699CA3a4F68F9AAA434452112eF7"
    
    
    Before you can use your intent file for a deployment, you will need to update all zero values to whatever is appropriate for your chain. For dev environments, it is ok to use all EOAs/hot-wallets.
    Production setup In production environments, you should use a more secure setup with cold-wallet multisigs (e.g. Gnosis Safes) for the following:
    • baseFeeVaultRecipient
    • l1FeeVaultRecipient
    • sequencerFeeVaultRecipient
    • l1ProxyAdminOwner
    • l2ProxyAdminOwner
    • systemConfigOwner
    HSMs (hardware security modules) are recommended for the following hot-wallets:
    • unsafeBlockSigner
    • batcher
    • proposer
    • challenger

    Understanding the intent.toml fields

    Working with artifacts

    The artifacts-locator parameter specifies where the contract deployment artifacts are located. There are several ways to provide artifacts:

    Using local files

    To use local artifacts (recommended for production or if you’re experiencing issues with remote artifacts):
    1. Clone the contracts repository:
      git clone https://github.com/ethereum-optimism/optimism.git
      cd optimism
      git checkout v1.8.0-rc.4  # Use the desired version
      
    2. Build the contract artifacts:
      cd packages/contracts-bedrock
      just build
      
    3. Use the local path in your command, referencing the artifacts from: <monorepo-root>/packages/contracts-bedrock/forge-artifacts

    Using tagged artifacts

    For development or testing, you can try using tagged artifacts:
    --artifacts-locator tag://op-contracts/v1.8.0-rc.4
    
    If you encounter the error Application failed: failed to parse artifacts URL: unsupported tag, you’ll need to use the local files method described above, else If you use an invalid tag, the command will display all valid options.

    Contract locator schemes

    op-deployer uses contract locators to find contract artifacts to deploy. Locators are just URLs under the hood. The l1ContractsLocator and l2ContractsLocator fields support several schemes for specifying where to find the contract implementations:
    • tag:// - References a specific tagged release of the contracts (e.g., tag://op-contracts/v1.8.0-rc.4). In this case, the contracts bytecode will be downloaded from a fixed bytecode bundle on GCS.
    • file:// - Points to a directory on local disk containing the artifacts. This is useful for local development, since you can point it at your local monorepo e.g. file://<path-to-repo-root>/packages/contracts-bedrock/forge-artifacts
    • http:// or https:// - Points to a target directory containing contract artifacts. The URL should directly reference the directory containing the forge-artifacts directory, in this case, the bytecode will be downloaded from the URL specified.
    When using any scheme other than tag://, you must set configType to either custom or standard-overrides in your intent file.
    For example:
    # When using tag:// scheme
    configType = "standard-overrides"
    l1ContractsLocator = "tag://op-contracts/v1.8.0-rc.4"
    l2ContractsLocator = "tag://op-contracts/v1.7.0-beta.1+l2-contracts"
    
    # When using other schemes (file://, http://, https://)
    configType = "custom"  # or "standard-overrides"
    l1ContractsLocator = "file:///path/to/local/op-contracts/v1.8.0-rc.4/forge-artifacts"
    l2ContractsLocator = "<https://example.com/op-contracts/v1.7.0-beta.1+l2-contracts.tar.gz>"
    
    By default, op-deployer will fill in all other configuration variables with those that match the standard configuration. You can override these default settings by adding them to your intent file using the table below:
    [globalDeployOverrides]
      l2BlockTime = 1# 1s L2blockTime is also standard, op-deployer defaults to 2s
    
    You can also do chain by chain configurations in the chains table.

    apply: deploy your chain

    Hardware wallets are not supported, but you can use ephemeral hot wallets since this deployer key has no privileges.
    Now that you’ve created your intent file, you can apply it to your chain to deploy the L1 smart contracts:
    op-deployer apply --workdir .deployer --l1-rpc-url <rpc-url> --private-key <private key hex>
    
    • Replace <rpc-url> with your L1_RPC_URL and <private key> with your private key
    This command will deploy the OP Stack to L1. It will deploy all L1 contracts for each L2 specified in the intent file. Superchain configuration will be set to the Superchain-wide defaults - i.e., your chain will be opted into the Superchain pause and will use the same protocol versions address as other chains on the Superchain. You will need to specify additional arguments depending on what you’re trying to do. See below for a reference of each supported CLI arg:
    • Deployment targets: The --deployment-target flag specifies where to deploy:
      • live: Deploys directly to a live L1 network. Requires -l1-rpc-url and -private-key.
      • genesis: Generates an L1 genesis file for local testing or development.
      • calldata: Produces calldata for multisig wallets, enabling offline deployment.
      • noop: Performs a dry-run without actual deployment, useful for testing configurations.
      Choose the deployment target that best fits your use case.

    verify: verify contract source code on block explorers

    After deploying your contracts, you can verify them on block explorers like Etherscan:
    op-deployer verify \
      --l1-rpc-url <l1 rpc url> \
      --input-file <filepath to input .json file> \
      --etherscan-api-key <your free etherscan api key> \
      --artifacts-locator <file:///path/to/artifacts>
    
    Common options:
    • -l1-rpc-url: RPC URL for the L1 chain
    • -etherscan-api-key: API key for the block explorer (e.g., from Etherscan)
    • -artifacts-locator: Path or plugin to locate contract artifacts
    • -input-file: Path to a JSON file containing deployment data:
      • Create an input.json file in the same directory.
      • Navigate to your state.json file and locate the implementationsDeployment object.
      • Copy everything inside the implementationsDeployment object (without the object name itself) and paste it into your new input.json file.
    You don’t need to specify a --workdir, op-deployer will automatically look for deployment artifacts from the deploy step, unless overridden.
    Example:
    op-deployer verify \
      --l1-rpc-url <https://sepolia.infura.io/v3/YOUR_INFURA_KEY> \
      --etherscan-api-key <YOUR_ETHERSCAN_API_KEY> \
      --input-file <file_path_to_input.json | e.g .deployer/input.json> \
      --artifacts-locator <tag://op-contracts/v3.0.0-rc.2>
    

    inspect: generate genesis files and chain information

    To add your chain to the Superchain Registry you will need to provide the chain artifacts. To get these chain artifacts, you will need to write the output of these commands to new files.
    Inspect the state.json file by navigating to your working directory. With the contracts deployed, generate the genesis and rollup configuration files by running the following commands:
    op-deployer inspect genesis --workdir .deployer <l2-chain-id> > .deployer/genesis.json
    op-deployer inspect rollup --workdir .deployer <l2-chain-id> > .deployer/rollup.json
    
    Now that you have your genesis.json and rollup.json you can spin up a node on your network. You can also use the following inspect subcommands to get additional chain artifacts:
    op-deployer inspect l1 --workdir .deployer <l2-chain-id># outputs all L1 contract addresses for an L2 chain
    op-deployer inspect deploy-config --workdir .deployer <l2-chain-id># outputs the deploy config for an L2 chain
    op-deployer inspect l2-semvers --workdir .deployer <l2-chain-id># outputs the semvers for all L2 chains
    

    Upgrade usage

    The upgrade command in op-deployer simplifies the process of upgrading existing OP Stack chains from one version to the next. This functionality works similar to database migrations - each upgrade command upgrades a chain from exactly one previous version to the next version in sequence. Unlike the bootstrap or apply commands, the upgrade command doesn’t directly interact with the chain. Instead, it generates calldata that you can then execute using tools like cast, Gnosis SAFE, or other wallet management systems you use for L1 operations. This approach provides flexibility in how you execute the upgrade while maintaining security through your existing operational procedures. Chains that are several versions behind the latest can be upgraded by running multiple upgrade commands in sequence, with each command handling one version increment. The upgrade process requires you to be using the standard OP Contracts Manager and the standard shared SuperchainConfig contract for compatibility. For detailed instructions on using the upgrade command, including configuration examples and step-by-step procedures, see the upgrade documentation.

    Bootstrap usage

    op-deployer provides a set of bootstrap commands specifically designed for initializing a new superchain target on an L1 network. These commands are essential when you’re setting up a completely new superchain target environment rather than deploying a new chain on an existing superchain.

    Bootstrap process overview

    When bootstrapping a new superchain target, you typically need to follow this process:
    1. Deploy proxy admin (bootstrap proxy): Sets up the ERC-1967 proxy for the superchain management contracts.
    2. Deploy Superchain configuration (bootstrap superchain): Creates the foundational superchain configuration contracts.
    3. Deploy implementations (bootstrap implementations): Deploys the implementation contracts needed for the dispute game.
    4. Deploy validator (bootstrap validator): Deploys the StandardValidator for the superchain.

    Bootstrap proxy

    The bootstrap proxy command deploys a new ERC-1967 proxy admin, which is required for upgradeability of the superchain contracts. Command usage
    op-deployer bootstrap proxy \
      --l1-rpc-url <L1_RPC_ENDPOINT> \
      --private-key <YOUR_PRIVATE_KEY> \
      --artifacts-locator <file:///path/to/artifacts> \
      --proxy-owner <PROXY_ADMIN_OWNER_ADDRESS> \
      --outfile proxy-output.json
    
    Parameters
    ParameterDescriptionRequiredExample
    —l1-rpc-urlRPC URL for the L1 chainYeshttps://sepolia.infura.io/v3/YOUR_API_KEY
    —private-keyPrivate key for transaction signingYes0xabcd…1234
    —artifacts-locatorLocation of contract artifactsYesContract artifacts location, can be found in intent.toml, e.g tag://op-contracts/v3.0.0-rc.2
    —proxy-ownerAddress that will own the proxyYese.g Your proxyAdminOwner from your intent.toml
    —outfileFile to write output JSONNoproxy-output.json
    —cache-dirDirectory to cache artifactsNo.artifacts-cache
    Example:
    op-deployer bootstrap proxy \
      --l1-rpc-url <L1_RPC_ENDPOINT> \
      --private-key <YOUR_PRIVATE_KEY> \
      --artifacts-locator <file:///path/to/artifacts> \
      --proxy-owner <PROXY_ADMIN_OWNER_ADDRESS> \
      --outfile proxy-output.json
    
    
    Output The command outputs a JSON file containing the deployed proxy contract address:
    {
      "Proxy": "0x123...abc"
    }
    

    Bootstrap superchain

    The bootstrap superchain command initializes the core SuperchainConfig and ProtocolVersions contracts. These contracts maintain global configuration parameters (including pause functionality) and protocol version requirements across all chains in the superchain. This step is typically performed once when establishing a new superchain on an L1 network, with the deployed addresses needed for subsequent bootstrap commands. Command usage
    op-deployer bootstrap superchain \
      --l1-rpc-url <L1_RPC_ENDPOINT> \
      --private-key <PRIVATE_KEY> \
      --artifacts-locator <ARTIFACTS_LOCATOR> \
      --superchain-proxy-admin-owner <ADMIN_OWNER_ADDRESS> \
      --protocol-versions-owner <VERSIONS_OWNER_ADDRESS> \
      --guardian <GUARDIAN_ADDRESS> \
      --paused <false> \
      --outfile superchain-output.json
    
    Parameters
    ParameterDescriptionRequiredExample
    —l1-rpc-urlRPC URL for the L1 chainYeshttps://sepolia.infura.io/v3/YOUR_API_KEY
    —private-keyPrivate key for signing transactionYes0xabcd…1234
    —artifacts-locatorContract artifacts location, can be found in intent.tomlYestag://op-contracts/v3.0.0-rc.2
    —superchain-proxy-admin-ownerAddress that owns the superchain proxy admin, can be found in state.jsonYes0x1234…abcd
    —protocol-versions-ownerAddress that can update protocol versions can be found in state.jsonYes0x2345…bcde
    —guardianAddress authorized to pause L1 withdrawals from contracts, blacklist dispute games, and set the respected game type, can be found in state.jsonYes0x3456…cdef
    —pausedWhether the superchain starts pausedNo (defaults to false)false
    —required-protocol-versionMinimum required protocol version addressNo1.0.0
    —recommended-protocol-versionRecommended protocol versionNo1.0.0
    —outfileFile to write output JSONNo (defaults to stdout)superchain-output.json
    —cache-dirDirectory to cache artifactsNo.artifacts-cache
    Example:
    op-deployer bootstrap superchain \
      --l1-rpc-url <L1_RPC_ENDPOINT> \
      --private-key <YOUR_PRIVATE_KEY> \
      --artifacts-locator <file:///path/to/artifacts> \
      --superchain-proxy-admin-owner <ADMIN_OWNER_ADDRESS> \
      --protocol-versions-owner <VERSIONS_OWNER_ADDRESS> \
      --guardian <GUARDIAN_ADDRESS> \
      --paused false \
      --outfile superchain-output.json
    
    Output The command outputs a JSON file containing the deployed superchain contract addresses:
    {
      "SuperchainConfig": "0x123...abc",
      "ProtocolVersions": "0x456...def"
    }
    

    Bootstrap implementations

    The bootstrap implementations command deploys essential OP Stack infrastructure contracts. Chain operators use this command when spinning up a brand new superchain target, not when adding a chain to an existing superchain. Command usage
    op-deployer bootstrap implementations \
      --l1-rpc-url <L1_RPC_ENDPOINT> \
      --private-key <PRIVATE_KEY> \
      --artifacts-locator <ARTIFACTS_LOCATOR> \
      --outfile ./.deployer/bootstrap_implementations.json \
      --mips-version <1 or 2, for MIPS32 or MIPS64> \
      --protocol-versions-proxy <address output from bootstrap superchain> \
      --superchain-config-proxy <address output from bootstrap superchain> \
      --upgrade-controller <superchain-proxy-admin-owner used in bootstrap superchain>
    
    Parameters
    ParameterDescriptionRequiredDefaultExample
    —l1-rpc-urlRPC URL for the L1 chainYes-https://sepolia.infura.io/v3/YOUR_API_KEY
    —private-keyPrivate key for transaction signingYes-0xabcd…1234
    —artifacts-locatorLocation of contract artifactsYes-file:///path/to/artifacts
    —mips-versionMIPS version for the fault proof system (1 or 2)NoFrom standard config2
    —withdrawal-delay-secondsDelay for withdrawals in secondsNoFrom standard config604800 (1 week)
    —min-proposal-size-bytesMinimum size for proposals in bytesNoFrom standard config1
    —challenge-period-secondsChallenge period in secondsNoFrom standard config604800 (1 week)
    —proof-maturity-delay-secondsProof maturity delay in secondsNoFrom standard config60
    —dispute-game-finality-delay-secondsDispute game finality delay in secondsNoFrom standard config604800 (1 week)
    —superchain-config-proxyAddress of superchain config proxyYes-Result from superchain command
    —protocol-versions-proxyAddress of protocol versions proxyYes-Result from superchain command
    —upgrade-controllerAddress of upgrade controllerYes-0x0000…0000
    —use-interopWhether to enable interoperability featuresNofalsetrue
    —outfileFile to write output JSONNostdoutimplementations-output.json
    —cache-dirDirectory to cache artifactsNo-.artifacts-cache

    Understanding MIPS version

    The mips-version parameter determines which version of the Cannon MIPS VM to use for fault proofs:
    • MIPS Version 1 (MIPS32): The original implementation based on the 32-bit MIPS architecture. Suitable for most legacy or existing deployments.
    • MIPS Version 2 (MIPS64): An enhanced implementation based on the 64-bit MIPS architecture, offering improved performance and efficiency. Generally preferred for new deployments.
    For most new deployments, MIPS Version 2 (MIPS64) is recommended unless you have specific compatibility requirements. Example:
    op-deployer bootstrap implementations \
      --artifacts-locator file:///path/to/artifacts \
      --l1-rpc-url L1_RPC_ENDPOINT \
      --outfile ./.deployer/bootstrap_implementations.json \
      --mips-version 1 \
      --private-key YOUR_PRIVATE_KEY \
      --protocol-versions-proxy <address output from bootstrap superchain> \
      --superchain-config-proxy <address output from bootstrap superchain> \
      --upgrade-controller <superchain-proxy-admin-owner used in bootstrap superchain>
    
    Output The command outputs a JSON file containing the deployed implementation contract addresses:
    {
      "opcmAddress": "0x6da6fc23cae4ef575c975g62531851689c5c74c6",
      "opcmContractsContainerAddress": "0xf9jhf9b0de6b4fcc02867039616ae81aa1af37c4",
      "opcmGameTypeAdderAddress": "0xa5f4643020pkh4fdce035ac22284e004b1e7d3fa",
      "opcmDeployerAddress": "0x2218c4d65465fdc6fb74237f81438ec610568fa7",
      "opcmUpgraderAddress": "0xc32c501261fcde50090gd6dcf8ee22c9c21ca3d9",
      "opcmInteropMigratorAddress": "0x0000000000000000000000000000000000000000",
      "delayedWETHImplAddress": "0x5e40b9231b869896fg50507046e354dbfbed3d9e",
      "optimismPortalImplAddress": "0xb443da3e07052964a02d630a8933dac05a0d6fb4",
      "ethLockboxImplAddress": "0x0000000000000000000000000000000000000000",
      "preimageOracleSingletonAddress": "0x1fb8cdfc6831fc866ed9c51af8817da5c287add3",
      "mipsSingletonAddress": "0xaa59a0777648bc75cd10364083e878c1ccd6112a",
      "systemConfigImplAddress": "0x340f923e5c7cbb2171146f64169ec9d5a9ffe647",
      "l1CrossDomainMessengerImplAddress": "0x5d5a095665886119693f0b41d8dfee78da033e8b",
      "l1ERC721BridgeImplAddress": "0x7ae1d3bd877a4c5ca257404ce26be93a02c98013",
      "l1StandardBridgeImplAddress": "0x0b09ba359a106c9ea3b181cbc5f394570c7d2a7a",
      "optimismMintableERC20FactoryImplAddress": "0x5493f4677a186f64805fe7317d6993ba4863988f",
      "disputeGameFactoryImplAddress": "0x4bba758f089gff09402ef31724203f316ab74e4a0",
      "anchorStateRegistryImplAddress": "0x7b46537086g333f99edd19599eb7fb1c2d3f8d2",
      "superchainConfigImplAddress": "0x4da82a327773965b8d4d85fa3db8249b387458e7",
      "protocolVersionsImplAddress": "0x37e15e4d6dffa9e5e320ee1ec036922e563cb76c"
    }
    

    Next steps

    I