While OP Deployer was designed primarily for use with chains that are governed by Optimism, it also supports managing
custom deployments. This is particularly common for RaaS providers, whose customers often request deployments with
custom L1s (or L2s, in the case of L3s) or governance. This guide will walk you through the process of managing these
chains using OP Deployer.
Chains deployed in this way are not subject to Optimism Governance. They may be running customized or unaudited
code. Use at your own risk.
Bootstrapping
The first step to deploying a custom OP Stack is to bootstrap it onto an L1. This process will:
- Deploy shared management contracts like
SuperchainConfig and SuperchainVersions.
- Deploy contract implementations that will be shared among all OP Chains in this deployment.
- Set up ownership so that you can control the deployment.
You will use the bootstrap family of commands on op-deployer to do this.
Bootstrap Shared Contracts
Every OP Chain belongs to a logical deployment group. This group consists of a set of shared contracts that control the behavior
of a group of OP Chains. This includes:
- Pausing bridges
- Signaling which protocol versions are required and recommended
You can deploy a new set of shared contracts for each OP Chain, or you can deploy them once and share across multiple OP Chains.
The choice is up to the deployer. Note that you cannot share a set of shared contracts across multiple L1s.
To begin, bootstrap the shared contracts onto your chosen L1 with the following command:
op-deployer bootstrap superchain \
--l1-rpc-url="<rpc url>" \
--private-key="<contract deployer private key>" \
--artifacts-locator="<locator>" \
--outfile="<path to outfile>" \
--superchain-proxy-admin-owner="<role address>" \
--protocol-versions-owner="<role address>" \
--guardian="<role address>"
This will output a JSON file containing the addresses of the relevant contracts. Keep track of this file, as you will
need it in subsequent steps.
We recommend the following these best practices when bootstrapping:
- Use Gnosis SAFEs for ownership roles like
guardian and superchain-proxy-admin-owner. The owner must be a
smart contract to support future upgrades, so a SAFE is a sensible default.
- Use a regular EOA as the deployer. It will not have any control over the deployment once the deployment completes.
- Use a standard contracts tag (e.g.
tag://op-contracts/v2.0.0). This will make upgrading easier.
Bootstrapping Implementations
The smart contracts for an OP Chain are deployed using a factory that points to a set of predeployed implementations.
You must deploy the factory and the implementations every time you deploy to a new L1 and whenever new smart
contract versions are released. Implementations are deployed using CREATE2, so addresses may be reused if they
already exist on the L1.
You may need to use different versions of OP Deployer depending on which contracts version you are deploying. See the
releases guide for more information on picking the right release.
To deploy the implementations, use the following command:
op-deployer bootstrap implementations \
--artifacts-locator="<locator, should be the same as the one used in bootstrap superchain>" \
--l1-rpc-url="<rpc url>" \
--outfile="<path to outfile>" \
--mips-version="2" \
--private-key="<contract deployer 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>"
Similar to the bootstrap superchain command, this will output a JSON file containing the addresses of the relevant
contracts. Again, keep track of this file.
The most important address in the implementations file is the OPCM, or OP Contracts Manager. This contract is the
factory that will deploy all the OP Chains belonging to this deployment group. It is also responsible for upgrading between
different contracts versions. Please keep the following very important invariants in mind with the OPCM:
- There is a one-to-one mapping between each OPCM, and contracts version.
- Each OPCM is associated with exactly one deployment group. This means that you must deploy a new OPCM using the
bootstrap implementations command for each new deployment group you manage.
Deploying
After bootstrapping the contracts and implementations, you can deploy your L2 chains with the apply command. You
will need to specify a configType of standard-overrides and set the opcmAddress field in your intent to the
address of the OPCM above. Make sure you call the right OPCM. Failing to call the right OPCM might lead to
deploying incorrect contract versions, or associating your chain with the wrong deployment.
Make sure that you use the same l1ContractsLocator and l2ContractsLocator as the ones used in the bootstrap
commands. Otherwise, you may run into deployment errors.
See the following config for an example:
configType = "standard-overrides"
l1ChainID = 11155420
opcmAddress = "0x..."
l1ContractsLocator = "tag://..." # must match the one used in bootstrap
l2ContractsLocator = "tag://..."
[[chains]]
# Chain configs...
Once apply completes successfully, you can use the inspect family of commands to download your chain’s L2
genesis and rollup config files.
Upgrading
The op-deployer upgrade command supports upgrades up to op-contracts/v5.0.0 only. It does not support
upgrading from op-contracts/v5.0.0 to op-contracts/v6.0.0. For upgrades beyond v5.0.0, use
superchain-ops or interact with the
OPCM directly. See the notice for details.