# 深入学习 Go-Ethereum : 008. CMD 模块 - Geth - chaincmd.go

By [OutOfToken](https://paragraph.com/@lua) · 2022-06-18

---

[《深入学习 Go-Ethereum : 007. CMD 模块 - Geth - accountcmd.go》](https://mirror.xyz/dashboard/edit/UimLyxEqgwRU0udjAhXPAZwVkEmsI1ZGclGiU70zWwY)中罗列了 `accountcmd` 中关于 `account` 和 `wallet` 两个字命令的相关主要源码，接下来描述下关于 `chaincmd.go` 中的代码功能

⬇️以下是 cmd/geth 包中其他代码的介绍：

    ├── accountcmd.go 
    ├── chaincmd.go 🔫
    ├── config.go
    ├── consolecmd.go
    ├── dbcmd.go
    ├── misccmd.go
    ├── snapshot.go
    ├── usage.go
    └── version_check.go
    

> ⬇️ chaincmd.go
> --------------

chaincmd 代码主要包含了7个子命令`（init、dump、dumpgenesis、export-preimages、import-preimages、export、import）` 及对应的实现方法

![chaincmd.go 代码结构](https://storage.googleapis.com/papyrus_images/1c2d006da0785248f3f193f6247a81bfadc57508c2e799c0a0b3df68c6f11941.png)

chaincmd.go 代码结构

**⬇️ 子命令声明**

![](https://storage.googleapis.com/papyrus_images/acd5d43c65983a6a020daf2c380f5be67db3ec310fc788a7b2ff821e9019bf92.png)

### ⬇️ initGenesis 方法：

![initGenesis](https://storage.googleapis.com/papyrus_images/8bd873781e9fee242f3425be32e34cf52ccb33f29dd7bd505b806efca4a47d7c.png)

initGenesis

在使用 `geth init` 命令时需要提供 `genesis.json` 文件（也可以不使用init命令，各种配置项以参数方式进行启动），作为创世区块的基本配置。配置信息可以查看 [私有网络](https://geth.ethereum.org/docs/interface/private-network) 相关介绍。

⚠️ 备注：只有当 **_network_**\*、**chainID**、**创世区块配置** \* 都相同时，才是同一条链。

> Every blockchain starts with the genesis block. When you run Geth with default settings for the first time, it commits the main net genesis to the database. For a private network, you usually want a different genesis block.
> 
> 在一个节点启动的时候，做为默认数据，会使用主网的创世块。如果是一个私有网络，通常需要一个不同的创世块信息。

**关于配置项 ，**`json` 中配置项对应了 `core/genesis.go` 代码中的 [Genesis](https://github.com/HugePages/go-ethereum/blob/cd454edf55ac1939857b88cf89ae36b1a217784d/core/genesis.go#L49) 结构体。

\*示例1： Genesis.json（\*with an empty chain configuration _）:_

    {
      "alloc"      : {},
      "coinbase"   : "0x0000000000000000000000000000000000000000",
      "difficulty" : "0x20000",
      "extraData"  : "",
      "gasLimit"   : "0x2fefd8",
      "nonce"      : "0x0000000000001338",
      "mixhash"    : "0x0000000000000000000000000000000000000000000000000000000000000000",
      "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
      "timestamp"  : "0x00",
       "config"     : {}
    }
    

![json内容可视化](https://storage.googleapis.com/papyrus_images/78142cc729328cc9eb21e2393de421a5d0a7e7dfb2d4d9f85fa511301509f8ac.png)

json内容可视化

配置项解释如下：

`alloc` 初始化区块链，给预定用户进行资产分配（单位时 WEI ）。

`difficulty` 挖矿的难度，能决定酸楚nonce的难度。

`nonce` 挖矿的一次性数字随机数。

`coinbase` 出块的奖励，一般在启动服务作为挖矿节点的时候，会设置当前节点挖矿奖励的目标地址是自己。

`timestamp` 时间戳，规定创世区块开始的时间。

`parentHash` 父区块的 hash 。

`gasLimit` 当前区块的 gas 上限。

`mixhash` pow机制中， 出块权获取后，给别的矿工进行验证的摘要信息。

`extraData` 额外的信息。

_示例2： Genesis.json（_ with specific chain configurations _）:_

    {
      "config": {
        "chainId": 15,
        "homesteadBlock": 0,
        "eip150Block": 0,
        "eip155Block": 0,
        "eip158Block": 0,
        "byzantiumBlock": 0,
        "constantinopleBlock": 0,
        "petersburgBlock": 0,
        ...
        ...指定区块的高度
        "ethash": {}
      },
      "difficulty": "1",
      "gasLimit": "8000000",
      "alloc": {
        "7df9a875a174b3bc565e6424a0050ebc1b2d1d82": {
          "balance": "300000"
        },
        "f41c74c9ae680c1aa78f42e5647a62f353b7bdde": {
          "balance": "400000"
        }
      }
    }
    

![json内容可视化](https://storage.googleapis.com/papyrus_images/b015114c7be3b1fcb6a4e56fdb32d3e1e462ac2b4ceb7a275d43f357a136b497.png)

json内容可视化

配置项解释如下：

`chainId` 区块链的Id，默主网Id是 1 。

`***Block` 区块高度，根据硬分叉等升级需求，指定区块高度（相关信息可以[点击查看源码](https://github.com/HugePages/go-ethereum/blob/cd454edf55ac1939857b88cf89ae36b1a217784d/params/config.go#L59)）。

* * *

⬇️ [主网创世块区块信息](https://etherscan.io/block/0)如图

![Block/0](https://storage.googleapis.com/papyrus_images/ac861712c14c69748e85495efc5c77c3975bc132b128273bfde820bceb6bc95a.png)

Block/0

> ### ⬇️ dumpgenesis 方法：

此方法主要功能是导出创世块的数据信息，默认打印在控制台。执行 `geth dumpgenesis` 效果⬇️

![geth dumpgenesis](https://storage.googleapis.com/papyrus_images/82a9bd1503c729036ec2a2b82b4dba8c3aed7246db9c2c6926ec7217fedee8f0.png)

geth dumpgenesis

![json数据可视化](https://storage.googleapis.com/papyrus_images/6a1fc93cc16ec798d01b7f5886b24a23c3bf7d904114ddea147c9b52a7e76826.png)

json数据可视化

⬇️ 代码截图

![dumpGenesis](https://storage.googleapis.com/papyrus_images/29c788a61ae9bed695c67b6761627e7dea7716a1766b85dd53d16688356f7359.png)

dumpGenesis

调用 `utils.MakeGenesis()` 方法， 最终执行 `core.Genesis` 的 `DefaultGenesisBlock()` 方法

> ### ⬇️ exportChain 方法：

此方法功能是将当前区块链数据导出成文件（使用 gzip 进行文件输出），执行 `append` 模式。具体导出代码可查看 [ExportChain](https://github.com/HugePages/go-ethereum/blob/cd454edf55ac1939857b88cf89ae36b1a217784d/cmd/utils/cmd.go#L241) 和 [ExportAppendChain](https://github.com/HugePages/go-ethereum/blob/cd454edf55ac1939857b88cf89ae36b1a217784d/cmd/utils/cmd.go#L267)

![exportChain](https://storage.googleapis.com/papyrus_images/92503d72febd463d5fbc813d3369bc99a23d16b86d74115320d83122c26f188c.png)

exportChain

> ### ⬇️ importChain 方法：

导入指定文，创建 Blockchain对象。其中主要的方法逻辑是 创建 `node` 对象、创建 `chain` 对象、判断参数数量执行 [ImportChain](https://github.com/HugePages/go-ethereum/blob/cd454edf55ac1939857b88cf89ae36b1a217784d/cmd/utils/cmd.go#L138)

![ImportChain](https://storage.googleapis.com/papyrus_images/008974344c1574961ac8d22748eee2628c8c117be5ce10ffc4a7df21a548bedb.png)

ImportChain

> ### ⬇️ exportPreimages 方法：

以RLP方式编码，导出preimage数据。

![](https://storage.googleapis.com/papyrus_images/34a5e70a5a3e67de5e593575831d35aa85c8a38f691646b247f7ffcc34046bd1.png)

> ### ⬇️ importPreimages 方法：

导入指定文件的 `preimage` 数据，使用 `rawdb` 的[WritePreimages](https://github.com/HugePages/go-ethereum/blob/cd454edf55ac1939857b88cf89ae36b1a217784d/core/rawdb/accessors_state.go#L84)方法进行数据库数据操作。

![](https://storage.googleapis.com/papyrus_images/d1e31b93e749c535d68720ed6fc484bba790b1461e54fe383b57ad5d9e132f90.png)

---

*Originally published on [OutOfToken](https://paragraph.com/@lua/go-ethereum-008-cmd-geth-chaincmd-go)*
