Skip to content
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
---
title: 'Customize genesis state'
description: 'How to configure your Arbitrum chain with a custom genesis state'
author: gmetha2
sme: Jason-W123
content_type: how-to
user_story: 'As an Arbitrum chain operator, I want to create a chain with a custom genesis state.'
---

Arbitrum chain operators are increasingly seeking to deploy chains with pre-existing state by loading an initial state in a file such as `genesis.json`. Specifically, chain operators want to predeploy smart contracts (like Gnosis Safe) to an Arbitrum chain so they exist from genesis, before any user interaction or post-launch governance.

Initializing from a genesis state would be helpful in the following scenarios:

1. Redeploying a new testnet with the pre-existing state if the current testnet is broken.
2. Deploying additional sibling chains with pre-existing contracts.
3. Simplifying self-serve backends for RaaSes, such that hundreds of testnets can be deployed with similar contracts.
4. Reducing lift on third-party infrastructure teams to redeploy contracts for new chains.

## Why should I use a custom genesis state?

Using a custom genesis allows you to initialize a new blockchain with a customized genesis state and network configuration through the following options:

- **Predeployed contracts**: standard chains start without any smart contracts. This feature allows you to preload contract bytecode in the very first block, so infrastructure is available at launch.
- **Initial account state (allocations)**: you can pre-configure the ledger—including account balances and contract storage—before the network opens for transactions.
- **Enable advanced features**: chain operators can use this feature to launch a chain with advanced customizations, such as [minting/burning gas tokens via third-party bridges](http://launch-arbitrum-chain/features/common/gas-and-fees/choose-native-mint-burn) and compliance-focused transaction filtering.

## How to configure

:::info Prerequisites

<!-- what Chain SDK version??? -->

- [Nitro contracts](https://github.com/OffchainLabs/nitro-contracts) >= v3.2
- first version to include full support for custom initialization in `genesis.json`
- [Nitro node](/run-arbitrum-node/02-run-full-node.mdx) >= v3.9.9 is needed for using custom-genesis.
- [Chain SDK](https://github.com/OffchainLabs/arbitrum-chain-sdk) >= xx.xx **or**
- Chain SDK only supports the standard `genesis.json` format, which includes the predeployed contracts.
- [genesis-file-generator tool](https://hub.docker.com/r/offchainlabs/genesis-file-generator)

- If you want to customize the `genesis.json` file or pass accounts/custom chain config, you should use the `genesis-file-generator`.

**Note**: The chain configuration must be exactly the same at the string level, including the order of fields, potential whitespace, or special characters for the `serializedChainConfig` string

:::

### Use the Chain SDK

The script completes the following automated steps:

- Generates a standard `genesis.json` file with the pre-deployed contracts.
- Calculates the `blockhash` and `sendRoot` hash and returns them for your use.
- An option to deploy the rollup. You can either deploy the chain using the `genesis.json` above or use the output from the previous step to set up the chain separately.

#### Core configuration ref

The following is required to generate the `genesis.json` file:

| Variable | Description |
| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CHAIN_ID` | The unique numeric identifier for your chain. |
| `IS_ANYTRUST` | Whether the chain is an AnyTrust (`true`) or rollup (`false`). |
| `ARBOS_VERSION` | The version of ArbOS to use for the genesis block. |
| `CHAIN_OWNER` | The address that will have admin ownership of the deployed chain. |
| `L1_BASE_FEE` | The initial L1 gas price (in wei) used to calibrate the chain initiation. |
| `NITRO_NODE_IMAGE` | The Nitro node Docker image used for hashing and node operations. |
| `ENABLE_NATIVE_TOKEN_SUPPLY` | Flag to launch your chain with native interop tokens as [minting/burning gas tokens via third-party bridges](http:///launch-arbitrum-chain/features/common/gas-and-fees/choose-native-mint-burn) via third-party protocols. |
| `ENABLE_TRANSACTION_FILTERING` | Flag to launch your chain with protocol-level transaction filtering for regulatory or compliance purposes. <br /> _**Note:** This feature requires ArbOS60 and Nitro node v3.10.0._ |

#### Deployment configuration (optional)

This step is only required if you choose to deploy the rollup to the parent chain (Step 3 below).

| Variable | Description |
| ------------------------ | ---------------------------------------------------------------------- |
| DEPLOYER_PRIVATE_KEY | Private key of the account responsible for the rollup deployment. |
| BATCH_POSTER_PRIVATE_KEY | Private key for the sequencer's batch-posting address. |
| VALIDATOR_PRIVATE_KEY | Private key for the validator/bonder address |
| PARENT_CHAIN_RPC | RPC endpoint for the parent chain (e.g., Arbitrum Sepolia or Ethereum) |

#### Execution steps

1. Prepare the environment

- From the repository root, install dependencies and navigate to the generator directory.

```shell
yarn install && yarn build

cd examples/generate-genesis-file && cp .env.example .env
```

2. Generate gensis

- Ensure your .env is configured and run the dev script.
:::info Configuration

Double-check that your .env values match your intended chain specs before running the script.

:::

3. Create rollup (optional)
- After generating the `genesis.json` file, the Chain SDK provides an option to deploy your rollup. Follow the prompts to continue or exit the process and deploy the rollup later.

### Use the `genesis-file-generator` tool

#### Environment variables reference (.env)

These parameters define the identify of your chain

| Variable | Description | Default |
| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- |
| `CHAIN_ID` | The unique numeric identifier for your new chain. | `31337` |
| `IS_ANYTRUST` | Whether the chain is an AnyTrust (`true`) or a rollup (`false`). | `false` |
| `ARBOS_VERSION` | The version of ArbOS to use for the genesis block. | `51` |
| `CHAIN_OWNER` | The address that will have admin ownership of the deployed chain. | -- |
| `L1_BASE_FEE` | The initial L1 gas price (in wei) used to calibrate the chain creation. | `1000000000` (1 gwei) |
| `NITRO_NODE_IMAGE` | The Nitro node Docker image used for hashing and node operations. | -- |
| `CUSTOM_ALLOC_ACCOUNT_FILE` | (optional) Path to a JSON file containing your own account balances, contract bytecode, and storage slots. The file should be in the the standard Geth `alloc` format. | `" "` (empty) |
| `ENABLE_NATIVE_TOKEN_SUPPLY` | (optional) Set to `true` if you want to launch your chain with native interop tokens as [minting/burning gas tokens via third-party bridges](http:///launch-arbitrum-chain/features/common/gas-and-fees/choose-native-mint-burn) via third-party protocols. | `false` |
| `LOAD_DEFAULT_PREDEPLOYS` | (optional) Set to `false` if you don't want the default predeploys. | `true` |
| `ENABLE_TRANSACTION_FILTERING` | (optional) Set to `true` if you want to launch your chain with protocol-level transaction filtering for regulatory or compliance purposes. <br /> _**Note:** This feature requires ArbOS60 and Nitro node v3.10.0._ | `false` |

#### Execution process

1. Prepare the genesis state

- Set up the `.env` file with the required parameters.
- Run the [`genesis-file-generator`](https://hub.docker.com/r/offchainlabs/genesis-file-generator/tags) Docker image to generate a `genesis.json` file with the required pre-deployed contracts and additional configurations.

```shell
mkdir -p genesis

docker run --rm \
--env-file .env \
-v "$(pwd)/genesis":/app/genesis \
offchainlabs/genesis-file-generator:v0.0.2-4c37f62
```

- You can also generate your own `genesis.json` file, but carefully read [this notice about the chain configuration property](https://github.com/OffchainLabs/genesis-file-generator#exclamation-important-note-about-the-chain-config-property) before proceeding with the next steps.

2. Generate the required hashes:

- After the `genesis.json` file is created, run the Nitro container to compute the genesis `blockhash` with the `genesis-generator` endpoint:

```shell
source .env

docker run --rm \
-v "$(pwd)/genesis":/data/genesisDir \
--entrypoint genesis-generator \
"$NITRO_NODE_IMAGE" \
--genesis-json-file /data/genesisDir/genesis.json \
```

- This bind-mounts the current directory into the container so it can read the `genesis.json` file generated in the previous step, and outputs the genesis `blockhash` and `sendRoot` hash. The `blockhash` and `sendRoot` hash will be logged as:

```shell
genesis-hash-calculator | BlockHash: 0xd636d2cae7a75bf41f471639f1cbf98fe2a24216147792510e664a65496f27ed, SendRoot: 0x0000000000000000000000000000000000000000000000000000000000000000, Batch: 1, PosInBatch: 0
```

3. Deploy the rollup:
- Use the `blockhash`, `sendRoot`, `Batch`, and `PosInBatch` in the Chain SDK. The SDK will use these to generate the `assertion_hash` needed to register your rollup's core smart contracts on the parent chain.
```javascript
const genesisAssertionState = {
globalState: {
bytes32Vals: [genesisBlockHash as `0x${string}`, sendRootHash as `0x${string}`] as [
`0x${string}`,
`0x${string}`,
],
// Set inbox position to 1
u64Vals: [1n, 0n] as [bigint, bigint],
},
machineStatus: 1, // FINISHED
endHistoryRoot: toHex(0, { size: 32 }),
};
```
4. Configure and launch your node:
- Set up your node as usual (directions here), but include the following properties to point to your custom state:
- `--init.genesis-json-file=/path/to/genesis.json`: the path to your custom `genesis.json` file
5. Start your chain, with the correct preloaded state.

### Pre-deployed contracts registry

<!-- What's the purpose of this? I ask because I'm forwarding thinking to how are we going to maintain this if it continutes to grow/shrink... may be link to a repo with the predeploys? -->

The following contracts are included by default in the standard `genesis.json` file:

| Category | Contract Name | Address | Note |
| :------------------ | :----------------------------- | :------------------------------------------- | :-------------------------------------- |
| **Factories** | Safe Singleton Factory v1.0.43 | `0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7` | Deterministic Proxy (Safe Key) |
| | Create2Deployer | `0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2` | CREATE (Deployer: `0x5542...`, Nonce 0) |
| | CreateX v1.0.0 | `0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed` | Pre-signed Transaction |
| | Arachnid Proxy | `0x4e59b44847b379578588920cA78FbF26c0B4956C` | Deterministic Proxy (Arachnid) |
| **Safe v1.3.0** | GnosisSafe (Canonical) | `0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552` | Via Arachnid CREATE2 Proxy |
| | GnosisSafe (EIP-155) | `0x69f4D1788e39c87893C980c06EdF4b7f686e2938` | Via Safe Singleton Factory |
| | GnosisSafeL2 (Canonical) | `0x3e5c63644e683549055b9be8653de26e0b4cd36e` | Via Arachnid CREATE2 Proxy |
| | GnosisSafeL2 (EIP-155) | `0xfb1bffC9d739B8D520DaF37dF666da4C687191EA` | Via Safe Singleton Factory |
| | SafeProxyFactory (Canonical) | `0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2` | Via Arachnid CREATE2 Proxy |
| | SafeProxyFactory (EIP-155) | `0xC22834581EbC8527d974F8a1c97E1bEA4EF910BC` | Via Safe Singleton Factory |
| | MultiSend v1.3.0 | `0x998739BFdAAdde7C933B942a68053933098f9EDa` | Via Safe Singleton Factory |
| | MultiSendCallOnly v1.3.0 | `0xA1dabEF33b3B82c7814B6D82A79e50F4AC44102B` | Via Safe Singleton Factory |
| **Safe v1.4.1** | Safe | `0x41675C099F32341bf84BFc5382aF534df5C7461a` | Via Safe Singleton Factory |
| | SafeL2 | `0x29fcB43b46531BcA003ddC8FCB67FFE91900C762` | Via Safe Singleton Factory |
| | SafeProxyFactory | `0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67` | Via Safe Singleton Factory |
| | MultiSend v1.4.1 | `0x38869bf66a61cF6bDB996A6aE40D5853Fd43B526` | Via Safe Singleton Factory |
| | MultiSendCallOnly v1.4.1 | `0x9641d764fc13c8B624c04430C7356C1C7C8102e2` | Via Safe Singleton Factory |
| **ERC-4337 Core** | EntryPoint v0.6.0 | `0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789` | Standard v0.6 |
| | SenderCreator v0.6.0 | `0x7fc98430eAEdbb6070B35B39D798725049088348` | Created during EP v0.6.0 deploy |
| | EntryPoint v0.7.0 | `0x0000000071727De22E5E9d8BAf0edAc6f37da032` | Standard v0.7 |
| | SenderCreator v0.7.0 | `0xEFC2c1444eBCC4Db75e7613d20C6a62fF67A167C` | Created during EP v0.7.0 deploy |
| | EntryPoint v0.8.0 | `0x4337084d9e255ff0702461cf8895ce9e3b5ff108` | Standard v0.8 |
| | SenderCreator v0.8.0 | `0x449ED7C3e6Fee6a97311d4b55475DF59C44AdD33` | Created during EP v0.8.0 deploy |
| **Account Modules** | Safe Module Setup v0.3.0 | `0x2dd68b007B46fBe91B9A7c3EDa5A7a1063cB5b47` | ERC-4337 Initializer |
| | Safe 4337 Module v0.3.0 | `0x75cf11467937ce3F2f357CE24ffc3DBF8fD5c226` | Associated with Entrypoint v0.7.0 |
| | Kernel v3.3 | `0xd6CEDDe84be40893d153Be9d467CD6aD37875b28` | Associated with Entrypoint v0.7.0 |
| | KernelFactory v3.3 | `0x2577507b78c2008Ff367261CB6285d44ba5eF2E9` | Associated with Entrypoint v0.7.0 |
| | MetaFactory v3.0 | `0xd703aaE79538628d27099B8c4f621bE4CCd142d5` | ZeroDev FactoryStaker |
| | ECDSAValidator v3.1 | `0x845ADb2C711129d4f3966735eD98a9F09fC4cE57` | Compiled from commit 8f7fd99 |
| **Infrastructure** | Multicall3 | `0xcA11bde05977b3631167028862bE2a173976CA11` | Pre-signed Transaction |
| | Permit2 | `0x000000000022D473030F116dDEE9F6B43aC78BA3` | Uniswap Permit2 |
| | EAS v1.4.0 | `0xF4C9CCaf46A866e2c12C5Bd95A39694718044444` | Ethereum Attestation Service |
| | EAS SchemaRegistry | `0x822B0B93BE3f3B8Da35a2E90e877C01215be8506` | EAS Registry |
5 changes: 5 additions & 0 deletions sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,11 @@ const sidebars = {
id: 'launch-arbitrum-chain/configure-your-chain/common/validation-and-security/config-smart-contract-size-limit',
label: `Smart contract size limit`,
},
{
type: 'doc',
id: 'launch-arbitrum-chain/configure-your-chain/common/validation-and-security/custom-genesis-state',
label: `Customize genesis state`,
},
],
},
{
Expand Down
Loading