diff --git a/docs/launch-arbitrum-chain/deploy/custom-genesis-state.mdx b/docs/launch-arbitrum-chain/deploy/custom-genesis-state.mdx new file mode 100644 index 0000000000..f233117499 --- /dev/null +++ b/docs/launch-arbitrum-chain/deploy/custom-genesis-state.mdx @@ -0,0 +1,271 @@ +--- +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](/launch-arbitrum-chain/chain-config/costs/configure-native-mint-burn.mdx) and compliance-focused transaction filtering. + + + +Preallocating account balances in the genesis state credits **ETH** (or your custom gas token) on your Arbitrum chain **without** depositing anything into the parent-chain bridge. The protocol does **not** require the bridge to hold ETH equal to the balances you preallocate, and there is no deploy-time check. + +If your chain will accept user deposits, a chain whose total preallocated balances exceed the bridge's backing is **insolvent from genesis**: withdrawals can fail once the bridge is drained. Only preallocate non-zero balances if you accept responsibility for backing them—for example, a private or test chain, or one where you deposit the equivalent amount into the bridge before opening it to users. + + + +## How to configure + +:::info Prerequisites + + + +- [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.11.0 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](/launch-arbitrum-chain/chain-config/costs/configure-native-mint-burn.mdx) via third-party protocols. | +| `ENABLE_TRANSACTION_FILTERING` | Flag to launch your chain with protocol-level transaction filtering for regulatory or compliance purposes.
_**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) | + + + +`DEPLOYER_PRIVATE_KEY`, `BATCH_POSTER_PRIVATE_KEY`, and `VALIDATOR_PRIVATE_KEY` are secrets. Keep them in your `.env` (which should be `.gitignore`d) and never commit your `.env`—or any generated node configuration that embeds these keys—to version control. + + + +#### Execution steps + +1. Prepare the environment + + - From the repository root, install dependencies and navigate to the generator directory. + + ```shell + pnpm install && pnpm build + + cd examples/generate-genesis-file && cp .env.example .env + ``` + +2. Generate genesis + + - Ensure your `.env` is configured and run the dev script. + - To preallocate custom accounts, set `CUSTOM_ALLOC_ACCOUNT_FILE=custom-alloc.json` in your `.env` and place the file (standard Geth `alloc` format) in the example directory. See the [`genesis-file-generator` section](#use-the-genesis-file-generator-tool) below for a sample, and review the solvency warning above before setting non-zero balances. + :::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. +4. Configure and launch your node: + - Set up your node as usual (see the [full node guide](/run-arbitrum-node/02-run-full-node.mdx)), 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 + - `--init.empty=false`: **(Required)** Forces the node to load the provided genesis file instead of initializing a blank state. +5. Start your chain, with the correct preloaded state. + + + +Your custom genesis is loaded via the `--init.genesis-json-file` and `--init.empty=false` flags when you start the node—it is **not** read from `node-config.json`. If you generate your node configuration with the Chain SDK's `prepare-node-config`, it won't include these, so make sure to pass them on the command line. + + + +### 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](/launch-arbitrum-chain/chain-config/costs/configure-native-mint-burn.mdx) 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.
_**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.3-rc-deffec7 + ``` + + - 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. + + - To preallocate your own accounts—balances, contract bytecode, or storage slots—create a `custom-alloc.json` file (standard Geth `alloc` format) next to your `.env`, set `CUSTOM_ALLOC_ACCOUNT_FILE=custom-alloc.json` in the `.env`, and add a read-only bind mount for it to the `docker run` command: + + ```shell + docker run --rm \ + --env-file .env \ + -v "$(pwd)/genesis":/app/genesis \ + -v "$(pwd)/custom-alloc.json":/app/custom-alloc.json:ro \ + offchainlabs/genesis-file-generator:v0.0.3-rc-deffec7 + ``` + + Example `custom-alloc.json` (preallocates 1 ETH—review the solvency warning above before setting non-zero balances): + + ```json + { + "0x299a89EE3Ee2BBC2cf9586ABd9AB1b57CF51B41F": { "balance": "0xde0b6b3a7640000" } + } + ``` + +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. + - If you write your own deploy script with `@arbitrum/chain-sdk` (instead of the bundled `generate-genesis-file` example), make sure the rollup config includes the `dataCostEstimate` field. The bundled example sets it, and omitting it is a common cause of failed custom-genesis deployments. + ```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 (see the [full node guide](/run-arbitrum-node/02-run-full-node.mdx)), 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 + - `--init.empty=false`: **(Required)** Forces the node to load the provided genesis file instead of initializing a blank state. +5. Start your chain, with the correct preloaded state. + +### Pre-deployed contracts registry + +The following contracts are included by default in the standard `genesis.json` file. For the authoritative, maintained list—and details on how each contract is deployed—see the [`genesis-file-generator` README](https://github.com/OffchainLabs/genesis-file-generator#pre-deployed-contracts). + +| 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) | +| | Zoltu Deployment Proxy | `0x7A0D94F55792C434d74a40883C6ed8545E406D12` | Deterministic Proxy (Zoltu) | +| | ERC-2470 Singleton Factory | `0xce0042B868300000d44A59004Da54A005ffdcf9f` | Singleton Factory (ERC-2470) | +| **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 (Canonical) | `0xA238CBeb142c10Ef7Ad8442C6D1f9E89e07e7761` | Via Arachnid CREATE2 Proxy | +| | MultiSend v1.3.0 (EIP-155) | `0x998739BFdAAdde7C933B942a68053933098f9EDa` | Via Safe Singleton Factory | +| | MultiSendCallOnly v1.3.0 (Canonical) | `0x40A2aCCbd92BCA938b02010E17A5b8929b49130D` | Via Arachnid CREATE2 Proxy | +| | MultiSendCallOnly v1.3.0 (EIP-155) | `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 | +| | ERC-1820 Registry | `0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24` | Pseudo-introspection Registry | +| | Permit2 | `0x000000000022D473030F116dDEE9F6B43aC78BA3` | Uniswap Permit2 | +| | EAS v1.4.0 | `0xF4C9CCaf46A866e2c12C5Bd95A39694718044444` | Ethereum Attestation Service | +| | EAS SchemaRegistry | `0x822B0B93BE3f3B8Da35a2E90e877C01215be8506` | EAS Registry | diff --git a/sidebars.js b/sidebars.js index cf9e8a095d..36cd4b6939 100644 --- a/sidebars.js +++ b/sidebars.js @@ -420,6 +420,11 @@ const sidebars = { id: 'launch-arbitrum-chain/deploy/canonical-factory-contracts', label: `Canonical factory contracts`, }, + { + type: 'doc', + id: 'launch-arbitrum-chain/deploy/custom-genesis-state', + label: `Custom genesis state`, + }, { type: 'doc', id: 'launch-arbitrum-chain/deploy/configure-node',