Skip to main content

Purpose and Scope

This document explains how to generate the genesis block, initialize the chain, and prepare validator keys for the StableNet network. It covers both automated generation using the genesis_generator tool and manual genesis file authoring. Related documents:

Genesis File Structure

The genesis file is a JSON file that defines the initial state of the blockchain, including chain configuration, initial account allocations, and consensus parameters.

Core Genesis Fields

Genesis structure:
FieldTypeDescription
Config*params.ChainConfigChain configuration including fork rules and consensus settings
Timestampuint64Genesis block timestamp
ExtraData[]byteIn Anzeon chains, WBFT validator information RLP-encoded
GasLimituint64Initial block gas limit
Difficulty*big.IntInitial difficulty (1 in Anzeon)
Alloctypes.GenesisAllocPre-allocated accounts and deployed contract code
BaseFee*big.IntEIP-1559 base fee

Anzeon Consensus Configuration

For Anzeon/WBFT chains, the ChainConfig includes an Anzeon field. This configuration defines two validator sets:
  • Init: Validators active from block 1 until the first epoch (hardcoded in the genesis block ExtraData)
  • SystemContracts.GovValidator: Validator set applied from the second epoch onward (modifiable via governance)
Unless there is a specific reason, these two sets should be identical.
For details on the epoch transition mechanism, see Anzeon WBFT Consensus Protocol.

System Contracts

StableNet deploys five system contracts at fixed addresses in the genesis block:
ContractAddressPurpose
NativeCoinAdapter0x0000000000000000000000000000000000001000ERC20 wrapper for the native coin
GovValidator0x0000000000000000000000000000000000001001Validator set management and gas tip governance
GovMasterMinter0x0000000000000000000000000000000000001002Master minter registry
GovMinter0x0000000000000000000000000000000000001003Mint/burn governance
GovCouncil0x0000000000000000000000000000000000001004Blacklist and certified account governance
System contracts are deployed without owners and can only be upgraded via hard forks.
For detailed initialization parameters, storage slots, and dependencies of each contract, see System Contracts Overview.

Genesis Initialization Parameters

The following parameters must be configured at genesis. GovValidator:
ParameterDescriptionDefault
membersGovernance member addresses (comma-separated)Required
validatorsValidator addresses (comma-separated)Required
blsPublicKeysBLS public keys (0x-prefixed, comma-separated)Required
quorumMinimum number of votes required to pass a proposalRequired
expiryProposal expiration time (seconds)604800 (7 days)
memberVersionMember set version”1”
maxProposalsMaximum concurrent proposals (1–50)3
gasTipMandatory gas tip (wei)27600000000000 (27600 Gwei)
members, validators, and blsPublicKeys are parallel lists managed in the same order.
Values at the same index across lists define a single validator identity.
  • Operator address (members): EOA or multisig address used for governance voting and validator registration/removal
  • Validator address (validators): Address used for consensus message signing and coinbase (block fee recipient), derived from the node’s nodekey
  • BLS public key (blsPublicKeys): BLS public key derived from the validator key, used for WBFT PREPARE/COMMIT aggregate signatures
For detailed key roles, derivation, and operational guidance, see Validator Operations. NativeCoinAdapter:
ParameterDescriptionDefault
nameToken name”WKRC”
symbolToken symbol”WKRC”
decimalsDecimal places”18”
currencyFiat currency label”KRW”
masterMinterGovMasterMinter contract address0x...1002
mintersGovMinter contract address0x...1003
minterAllowedMaximum mintable amount per minter10^28

Validator Key Preparation

Each validator’s keys must be generated before network initialization.

Node Key Generation

Use the bootnode utility to generate node keys:
# Generate node key
bootnode -genkey nodekey

# Inspect derived address and BLS keys
bootnode -nodekey nodekey -writeaddress
Values derived from the node key:
Derived ItemFunctionPurpose
Validator addresscrypto.PubkeyToAddress(nodeKey.PublicKey)Block signing address (coinbase)
BLS private keybls.DeriveFromECDSA(nodeKey)Consensus message signing
BLS public keyblsKey.PublicKey().Marshal()Registered in genesis (48 bytes, hex-encoded)
For validator key security, rotation, and multisig operator keys, see Validator Operations.

genesis_generator Tool

genesis_generator is a CLI tool that generates a genesis file with correctly configured system contracts.

Build

cd go-stablenet
make genesis_generator

# Binary location: build/bin/genesis_generator

Interactive Mode

Running without arguments starts interactive mode:
./build/bin/genesis_generator
You will be prompted for:
  1. Consensus engine selection: choose Anzeon (WBFT)
  2. Number of nodes: single-node or multi-node
  3. Node key paths: path to each validator’s node key file (default: ./nodekey)
  4. Quorum configuration: governance quorum for multi-node setups (min 2, max = validator count)
  5. Chain ID: unique network identifier (random if omitted)
The tool automatically derives validator addresses and BLS keys from node keys.

Command-Line Flags

Non-interactive usage is also supported (cmd/genesis_generator/genesis_generator.go 50–100):
FlagTypeDescriptionDefault
--chainIdintNetwork chain IDRandom
--validatorsstringValidator addresses (comma-separated)-
--blsKeysstringBLS public keys (comma-separated)-
--membersstringGovernance member addresses (comma-separated)-
--quorumintGovernance quorum-
--epochLengthintBlocks per epoch10
--blockPeriodintTarget block time (seconds)1
--gasLimituint64Genesis block gas limit-
--outputstringOutput file pathgenesis.json

Generation Examples

Single-validator network:
./build/bin/genesis_generator \
  --chainId 9999 \
  --validators 0xaa5f...1234 \
  --blsKeys 0xaec4...5678 \
  --members 0xaa5f...1234 \
  --quorum 1 \
  --output genesis.json
Multi-validator network:
./build/bin/genesis_generator \
  --chainId 9999 \
  --validators 0xaa5f...1234,0x294f...5678 \
  --blsKeys 0xaec4...abcd,0x91b2...efgh \
  --members 0xaa5f...1234,0x294f...5678 \
  --quorum 2 \
  --epochLength 10 \
  --blockPeriod 1 \
  --output genesis.json

Genesis Validation

During generation, genesis_generator automatically validates:
  1. Matching lengths of Init.Validators and Init.BLSPublicKeys arrays
  2. Correct hex encoding and length (96 bytes) of each BLS public key
  3. Valid Ethereum address format for all validator and member addresses
  4. Valid ranges for epoch length, block period, and timeout values
  5. Correct system contract addresses

Chain Initialization

Running gstable init

Initialize the chain database with the genesis file:
# Initialize with default data directory
gstable init genesis.json

# Specify a custom data directory
gstable init genesis.json --datadir /data/gstable
Initialization steps:
  1. Load genesis file and validate Anzeon configuration
  2. Generate WBFT ExtraData from the initial validator set
  3. Deploy system contracts via InjectContracts()
  4. Commit the genesis block to the database
If an existing database is found, the provided genesis is checked against the stored genesis.
A mismatch results in a GenesisMismatchError.

Starting Nodes After Initialization

# Start a validator node
gstable --datadir /data/gstable \
  --networkid 9999 \
  --mine \
  --nodekey /path/to/nodekey \
  --syncmode full \
  --port 30303

# With explicit bootnodes
gstable --datadir /data/gstable \
  --networkid 9999 \
  --bootnodes "enode://pubkey@ip:port"
For full runtime options, see Node Configuration.

Two-Phase Validator Initialization

StableNet manages validator sets in two phases: Phase 1: First Epoch (Block 1 ~ epochLength)
  • Defined in Anzeon.Init.Validators
  • Hardcoded in the genesis block ExtraData
  • Not modifiable via governance
Phase 2: From Second Epoch Onward
  • Defined in SystemContracts.GovValidator.Params
  • Validator set updated at epoch blocks by reading GovValidator contract state
  • Modifiable via governance voting
This design allows the chain to bootstrap with a minimal validator set and then transition to governance-controlled validator management.
For details, see Validator Governance.

Network-Specific Configuration

Mainnet

  • Chain ID: 8282
  • Network flag: --mainnet
  • Bootnodes: automatically configured (params.StableNetMainnetBootnodes)
  • Genesis: embedded in the binary (no init required)
# Start a Mainnet node (genesis auto-loaded)
gstable --mainnet --syncmode full --datadir /data/gstable

Testnet

  • Chain ID: 8283
  • Network flag: --testnet
  • Bootnodes: automatically configured (params.StableNetTestnetBootnodes)
  • Genesis: embedded in the binary (no init required)
# Start a Testnet node
gstable --testnet --syncmode full --datadir /data/gstable

Private Network

Private networks require a custom genesis file. Setup procedure:
  1. Generate node keys for each validator (bootnode -genkey)
  2. Generate the genesis file using genesis_generator
  3. Run gstable init genesis.json on all nodes
  4. Start nodes with --networkid and --bootnodes specified
Recommended parameters for private networks:
ParameterDevelopmentProduction
chainIdUnique value not colliding with public networksSame
epochLength5–10 (fast validator changes)100+
blockPeriod1 second1–3 seconds
quorum1 (single node)≥ 2/3 of validators
gasLimitDefaultAdjust to network needs
Private network startup example:
# 1. Generate node keys
bootnode -genkey nodekey1
bootnode -genkey nodekey2

# 2. Generate genesis (interactive mode recommended)
./build/bin/genesis_generator

# 3. Initialize each node
gstable init genesis.json --datadir /data/node1
gstable init genesis.json --datadir /data/node2

# 4. Start the first node
gstable --datadir /data/node1 \
  --networkid 9999 \
  --mine \
  --nodekey nodekey1 \
  --syncmode full \
  --port 30303

# 5. Start the second node (using the first as bootnode)
gstable --datadir /data/node2 \
  --networkid 9999 \
  --mine \
  --nodekey nodekey2 \
  --syncmode full \
  --port 30304 \
  --bootnodes "enode://<node1-pubkey>@<node1-ip>:30303"
For production deployment checklists, Docker deployment, and Debian packages, see Network Deployment.

Post-Initialization Verification

After initialization, verify the following:
# Attach to the node
gstable attach /data/gstable/gstable.ipc

# Check chain ID
> eth.chainId()

# Check genesis block
> eth.getBlock(0)

# Check validator set (system contract call)
> eth.call({to: "0x0000000000000000000000000000000000001001", data: "0x..."})

# Check peer connections
> admin.peers.length

# Check mining status (validator node)
> eth.mining

# Check block production
> eth.blockNumber

Common Initialization Issues and Resolutions

Genesis Mismatch Error

Error: GenesisMismatchError: database contains incompatible genesis Cause: Attempting to initialize with a genesis file that does not match the existing database. Resolution:
# Option 1: Remove existing chain data and reinitialize
rm -rf /data/gstable/gstable/chaindata
gstable init genesis.json --datadir /data/gstable

# Option 2: Use the correct genesis.json matching the existing chain

Validator Count Mismatch

Error: Invalid genesis config: validator count mismatch Cause: Length mismatch between Init.Validators and Init.BLSPublicKeys. Resolution: Ensure members, validators, and blsPublicKeys all have the same number of entries.

System Contract Deployment Failure

Error: Failed to inject system contracts Cause: Invalid initialization parameters or missing contract bytecode. Resolution: Verify system contract parameters, especially address format (0x prefix, 40 hex chars) and comma-separated list syntax.

BLS Key Format Error

Error: Invalid BLS public key format Cause: Incorrect hex encoding or length of the BLS key. Resolution: BLS public keys must include a 0x prefix and be exactly 98 characters long
(0x + 96-byte hex encoding = 0x + 192 hex characters).
Verify using bootnode -nodekey.

Init vs GovValidator Validator Mismatch Warning

If Init.Validators and SystemContracts.GovValidator.Params.validators differ, the validator set will change at the transition from the first to the second epoch.
Unless intentional, keep both sets identical.