See Superchain Upgrades OP-Stack specifications.
A new Superchain Target can be added by creating a new superchain config directory,
with a superchain.yaml
config file.
cd superchain-registry
export SUPERCHAIN_TARGET=goerli-dev-0
mkdir superchain/configs/$SUPERCHAIN_TARGET
cat > superchain/configs/$SUPERCHAIN_TARGET/superchain.yaml << EOF
name: Goerli Dev 0
l1:
chain_id: 5
public_rpc: https://ethereum-goerli-rpc.allthatnode.com
explorer: https://goerli.etherscan.io
protocol_versions_addr: null # todo
superchain_config_addr: null # todo
EOF
Superchain-wide configuration, like the ProtocolVersions
contract address, should be configured here when available.
Per superchain a set of canonical implementation deployments, per semver version, is tracked. As default, an empty collection of deployments can be set:
cat > superchain/implementations/networks/$SUPERCHAIN_TARGET.yaml << EOF
l1_cross_domain_messenger:
l1_erc721_bridge:
l1_standard_bridge:
l2_output_oracle:
optimism_mintable_erc20_factory:
optimism_portal:
system_config:
EOF
To contribute a full OP-Stack chain configuration, the following data is required: contracts deployment, rollup config, L2 genesis.
For example:
cd optimism
export SUPERCHAIN_REPO=../superchain-registry
export SUPERCHAIN_TARGET=goerli-dev-0
export CHAIN_NAME=op-labs-devnet-0
export DEPLOYMENTS_DIR=./packages/contracts-bedrock/deployments/internal-devnet
export ROLLUP_CONFIG=./internal_devnet_rollup.json
export GENESIS_CONFIG=./internal_devnet_genesis.json
The config is the main configuration source, with genesis data, and address of onchain system configuration:
cat > $SUPERCHAIN_REPO/superchain/configs/$SUPERCHAIN_TARGET/$CHAIN_NAME.yaml << EOF
name: OP Labs devnet 0
chain_id: $(jq -j .l2_chain_id $ROLLUP_CONFIG)
public_rpc: ""
sequencer_rpc: ""
explorer: ""
system_config_addr: "$(jq -j .l1_system_config_address $ROLLUP_CONFIG)"
batch_inbox_addr: "$(jq -j .batch_inbox_address $ROLLUP_CONFIG)"
genesis:
l1:
hash: "$(jq -j .genesis.l1.hash $ROLLUP_CONFIG)"
number: $(jq -j .genesis.l1.number $ROLLUP_CONFIG)
l2:
hash: "$(jq -j .genesis.l2.hash $ROLLUP_CONFIG)"
number: $(jq -j .genesis.l2.number $ROLLUP_CONFIG)
l2_time: $(jq -j .genesis.l2_time $ROLLUP_CONFIG)
EOF
Extra configuration is made available for node-operator UX, but not a hard requirement.
Addresses of L1 contracts.
Note that all L2 addresses are statically known addresses defined in the OP-Stack specification, and thus not configured per chain.
# create extra addresses data
mkdir -p $SUPERCHAIN_REPO/superchain/extra/addresses/$SUPERCHAIN_TARGET
cat > $SUPERCHAIN_REPO/superchain/extra/addresses/$SUPERCHAIN_TARGET/$CHAIN_NAME.json << EOF
{
"AddressManager": "$(jq -j .address $DEPLOYMENTS_DIR/Lib_AddressManager.json)",
"L1CrossDomainMessengerProxy": "$(jq -j .address $DEPLOYMENTS_DIR/Proxy__OVM_L1CrossDomainMessenger.json)",
"L1ERC721BridgeProxy": "$(jq -j .address $DEPLOYMENTS_DIR/L1ERC721BridgeProxy.json)",
"L1StandardBridgeProxy": "$(jq -j .address $DEPLOYMENTS_DIR/Proxy__OVM_L1StandardBridge.json)",
"L2OutputOracleProxy": "$(jq -j .address $DEPLOYMENTS_DIR/L2OutputOracleProxy.json)",
"OptimismMintableERC20FactoryProxy": "$(jq -j .address $DEPLOYMENTS_DIR/OptimismMintableERC20FactoryProxy.json)",
"OptimismPortalProxy": "$(jq -j .address $DEPLOYMENTS_DIR/OptimismPortalProxy.json)",
"ProxyAdmin": "$(jq -j .address $DEPLOYMENTS_DIR/ProxyAdmin.json)"
}
EOF
The extra/genesis
directory hosts compressed genesis.json
definitions that pull in the bytecode by hash
The genesis largely consists of contracts common with other chains:
all contract bytecode is deduplicates and hosted in the extra/bytecodes
directory.
The format is a gzipped JSON genesis.json
file, with either:
- a
alloc
attribute, structured like a standardgenesis.json
, but withcodeHash
(bytes32,keccak256
hash of contract code) attribute per account, instead of thecode
attribute seen in standard Ethereum genesis definitions. - a
stateHash
attribute: to omit a large state (e.g. for networks with a re-genesis or migration history). Nodes can load the genesis block header, and state-sync to complete the node initialization.
# create extra genesis data
mkdir -p $SUPERCHAIN_REPO/superchain/extra/genesis/$SUPERCHAIN_TARGET
go run ./op-chain-ops/cmd/registry-data \
--l2-genesis=$GENESIS_CONFIG \
--bytecodes-dir=$SUPERCHAIN_REPO/superchain/extra/bytecodes \
--output=$SUPERCHAIN_REPO/superchain/extra/genesis/$SUPERCHAIN_TARGET/$CHAIN_NAME.json.gz
Genesis system config data is provided but may be optional for chains deployed with future OP-Stack protocol versions.
Newer versions of the SystemConfig
contract persist the L1 starting block in the contract storage,
and a node can load the initial system-config values from L1
by inspecting the SystemConfig
receipts of this given L1 block.
# create genesis-system-config data
# (this is deprecated, users should load this from L1, when available via SystemConfig).
mkdir -p $SUPERCHAIN_REPO/superchain/extra/genesis-system-configs/$SUPERCHAIN_TARGET
jq -r .genesis.system_config $ROLLUP_CONFIG > $SUPERCHAIN_REPO/superchain/extra/genesis-system-configs/$SUPERCHAIN_TARGET/$CHAIN_NAME.json