genesis.json文件详解
配置文件
{
"config": {
// 链ID:用于交易签名防重放;与你的 networkid 不强制相等,但通常保持一致更清晰
"chainId": 202601, // 链ID,必须唯一,不能和主网、测试网冲突
// 下面这些 *Block=0 表示:从创世块开始就启用对应的硬分叉规则
// 好处:规则一致、少踩坑;坏处:没什么坏处(私链推荐这样写)
"homesteadBlock": 0, // 升级到 Homestead 协议的区块高度
"eip150Block": 0, // 升级到 EIP150 协议的区块高度
"eip155Block": 0, // 升级到 EIP155 协议的区块高度
"eip158Block": 0, // 升级到 EIP158 协议的区块高度
"byzantiumBlock": 0, // 升级到 Byzantium 协议的区块高度
"constantinopleBlock": 0, // 升级到 Constantinople 协议的区块高度
"petersburgBlock": 0, // 升级到 Petersburg 协议的区块高度
"istanbulBlock": 0, // 升级到 Istanbul 协议的区块高度
"clique": { "period": 2, "epoch": 30000 } // Clique 共识机制配置
},
"nonce": "0x0", // 随机数,用于挖矿
"timestamp": "0x0", // 时间戳,创世区块时间
"extraData": "0x00000000000000000000000000000000000000000000000000000000000000002f02ca3b39c3e86566246489787f37c0453888a2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", // 额外数据,包含出块者地址
"gasLimit": "0x2FAF080", // 创世区块的 Gas 上限
"difficulty": "0x1", // 创世区块的难度
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", // 混合哈希
"coinbase": "0x0000000000000000000000000000000000000000", // 创世区块的矿工地址
"alloc": { // 创世区块的预分配账户
"0xe8aCb15b1d4dB40292B10C8169d369dff180C2f9": { "balance": "0x3635C9ADC5DEA00000" } // 预分配1000个ETH
}
}1)config:链规则与共识参数
"config": {
"chainId": 202601,
"homesteadBlock": 0,
"eip150Block": 0,
"eip155Block": 0,
"eip158Block": 0,
"byzantiumBlock": 0,
"constantinopleBlock": 0,
"petersburgBlock": 0,
"istanbulBlock": 0,
"clique": { "period": 2, "epoch": 30000 }
}1.1 chainId: 202601
用途:EIP-155 的“防重放攻击”字段,用来区分不同链。
效果:同一笔交易签名,在不同
chainId的链上不能复用(防止把私链交易拿去主网/别的链广播)。- 私链随便取,但要确保全网一致。
- 一旦链启动并产生数据,不要改,改了就是另一条链。
1.2 homesteadBlock / eip150Block / eip155Block / eip158Block / byzantiumBlock / constantinopleBlock / petersburgBlock / istanbulBlock
这些都是以太坊历史上的“硬分叉规则开关”,字段含义统一:
- 结构是:
xxxBlock: <某个区块高度> - 含义:从该高度开始,启用对应升级的规则。
这里全部是 0,表示:
从创世块(高度 0)开始就启用这些规则。
这在私链里非常常见(好处是规则一致、不会出现“老规则 vs 新规则”的兼容问题)。
常见坑
- 如果把某些升级设成未来高度(比如 100000),链在升级点附近可能出现和工具/合约预期不一致的问题。
- 所以私链一般都设 0。
1.3 clique: { "period": 2, "epoch": 30000 }
这表明用的是 Clique PoA(授权签名出块)。
period: 2
含义:目标出块间隔是 2 秒。
效果:
- 出块者(signer/validator)会尽量每 2 秒产一个块。
- 交易被打包进区块的平均等待时间通常也会跟这个数量级相关(但还跟交易池、节点延迟等有关)。
注意:Clique 不是“收到交易才出块”,它更像“定时出块”(只不过没交易也会出空块)。
epoch: 30000
含义:每隔 30000 个块,会插入一个 “checkpoint(检查点)块”。
效果:
- 检查点块会把“当前授权签名者集合”写入链上(用于加速同步、保证签名者集合的确定性)。
估算一下周期:2 秒/块 → 30000 块 ≈ 60000 秒 ≈ 16.7 小时出一次 checkpoint。
建议:这个数值挺常见。epoch 太小会增加开销,太大会让某些同步/恢复过程变慢。
2)创世块头部字段(“这条链的第 0 块长什么样”)
2.1 nonce
"nonce": "0x0"- 在 PoW 时代:nonce 用来配合挖矿找哈希。
- 在 Clique:它不再承担挖矿意义,但仍是块头字段。
- 通常:创世块这里用
0x0没问题(Geth 会按 Clique 规则处理)。
2.2 timestamp
"timestamp": "0x0"含义:创世块的时间戳(单位秒)。
0x0表示时间戳为 0(Unix epoch 起点)。影响:
- 仅影响创世块的显示;后续块时间戳由出块节点按规则递增。
建议:也可以填一个当前时间戳(更“像真的”),但不影响链的功能。
2.3 extraData(Clique 最核心的“签名者信息载体”)
"extraData": "0x0000...00002f02ca3b39c3e86566246489787f37c0453888a2...0000"在 Clique 里,extraData 有固定格式:
- Vanity(32 字节):随便填,常用全 0
- Signer 列表(N * 20 字节):把“初始授权出块者地址”一个个拼进去
- Signature(65 字节):创世块这里没有真实签名,通常全 0 占位
这串里非常典型地出现了一个地址:
2f02ca3b39c3e86566246489787f37c0453888a2
这通常就是设置的 初始 signer(出块者)。
关键点
- Clique 要能出块,必须至少有 1 个 signer。
- signer 必须是节点里真正持有私钥的账户(并在启动时
--unlock/签名)。 - 如果
extraData里的 signer 地址写错了:链能初始化,但后续没人能合法签名出块 → 链就“看起来启动了但永远不出块”。
2.4 gasLimit
"gasLimit": "0x2FAF080"- 含义:创世块设置的“每个区块 gas 上限”,决定一个块里最多能容纳多少计算/交易工作量。
0x2FAF080转成十进制是:
2F AF 08 0(hex) = 50,000,000 gas
所以0x2FAF080“≈ 50,000,000 gas”就是这么来的。
对私链意味着什么
gasLimit 不是“区块大小限制(MB)”,而是“一块里 EVM 最多允许做多少事”。
交易能写多少数据(calldata / storage)也受 gas 约束:
- calldata 每字节收费(而且 0 字节/非 0 字节收费不同)
- 写 storage(SSTORE)更贵
所以不是想塞 100MB 文本就能塞:先看 gas 是否够,通常会非常贵、并且受单笔交易 gas 限制与节点配置影响。
2.5 difficulty
"difficulty": "0x1"- PoW 时代:难度用于挖矿。
- Clique:难度字段仍存在,但被用作“出块轮次/授权相关”的信号(Geth 内部会用它表达某些状态)。
- 创世块:设成
0x1是常见写法。
2.6 mixHash
"mixHash": "0x0000...0000"- PoW 时代:挖矿工作量证明相关。
- Clique:通常要求固定为全 0(或 Clique 规则指定值),这写全 0 是标准做法。
2.7 coinbase
"coinbase": "0x0000000000000000000000000000000000000000"PoW 时代:矿工收取区块奖励的地址(又叫
beneficiary)。Clique/PoA:
- 没有 PoW 挖矿奖励的概念(尤其在这种私链设置里一般也不靠区块奖励驱动)。
coinbase多数情况下对业务无意义,所以写 0 地址很常见。
3)alloc:创世预分配余额(给哪些地址发“初始原生币”)
"alloc": {
"0xe8aCb15b1d4dB40292B10C8169d369dff180C2f9": { "balance": "0x3635C9ADC5DEA00000" }
}含义:在创世块就把原生币余额写死在状态里。
用途:
- 给管理账户/服务账户一些初始 ETH(用于支付 gas,或做转账测试)。
- 私链里这通常就是“系统启动资金”。
3.1 balance: "0x3635C9ADC5DEA00000"
这是十六进制的余额,单位是 wei(1 ETH = 10^18 wei,EVM 里这个换算是固定常量)。
它是一个 Wei 数额的十六进制表示。
3.2 以太坊系金额单位
- 1 原生币 = 10^18 Wei
- Wei 是最小单位(类似“分/厘”)
3.3 为什么是 1000 余额?
0x3635C9ADC5DEA00000(十六进制)转换成十进制是:
1000000000000000000000 Wei
把它除以 10^18(1 ETH = 10^18 wei):
- 1000000000000000000000 ÷ 1000000000000000000
= 1000
所以它等价于 1000 个原生币(链上的“ETH 类单位”)。