第01篇 Windows平台以太坊联盟链搭建步骤(1)

本文操作系统:windows 10 家庭中文版。

1、下载Geth

在官网下载:https://geth.ethereum.org/downloads/

或者从国内镜像下载:https://ethfans.org/wikis/Ethereum-Geth-Mirror

本文从国内镜像下载,版本号:geth-windows-amd64-1.8.3

主要参考文档:https://ethfans.org/posts/how-to-build-private-chain-with-Geth

 

2、安装Geth

双击下载的文件geth-windows-amd64-1.8.3-329ac18e.exe进行安装:

第01篇 Windows平台以太坊联盟链搭建步骤(1)_第1张图片

安装完毕后目录如下:

第01篇 Windows平台以太坊联盟链搭建步骤(1)_第2张图片

3、加载创世区块

首先,需要定义区块链的创世状态;通过geth来配置以太坊私有链,是学习以太坊的入门步骤。而其中,如何配置创世文件,又是最关键的一步。

如果在其中产生错误,有些会导致无法初始化私有链,有些还会导致在以后的过程中发生各种莫名其妙的错误。

新建一个创世文件,该文件的后缀为.json(大部分命名为genesis.json),注意:不同的genesis.json适用于不同的geth版本;将该文件放到geth的安装目录下,文件的内容类似:

{
  "config": {
    "chainId": ,
    "homesteadBlock": 0,
    "eip150Block": 0,
    "eip155Block": 0,
    "eip158Block": 0,
    "byzantiumBlock": 0,
    "constantinopleBlock": 0,
    "petersburgBlock": 0,
    "clique": {
      "period": 5,
      "epoch": 30000
    },
    "ethash": {}
  },
  "alloc": {
    "dbdbdb2cbd23b783741e8d7fcf51e459b497e4a6": { "balance": "1000000000"},
    "e6716f9544a56c530d868e4bfbacb172315bdead": { "balance": "2000000000"},
    ...
  },
  "nonce": "0x000000000000002a",
  "difficulty": "0x020000",
  "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "coinbase": "0x0000000000000000000000000000000000000000",
  "timestamp": "0x00",
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "extraData": "0x",
  "gasLimit": "0x2fefd8"
}

我们对配置项的内容进行一下简单的介绍。

1.config:定义链配置,会影响共识协议,虽然链配置对创世影响不大,但新区块的出块规则均依赖链配置。

(1)chainId: 是 EIP-155 引入的一个用来区分不同 EVM 链的一个标识,主要作用就是避免一个交易在签名之后被重复在不同的链上提交。私有链的 chainId 最好不要和现有任何已经在公开运行的 EVM 链的 chainId 相同。已经被占用的 chainId 可以通过这个列表查看。注意:networkid 参数通常需要与 chainId 的值一致,可用来防止replay attack重发攻击:恶意重复或拖延正确数据传输的一种网络攻击手段。

(2)homesteadBlock:Homestead 硬分叉区块高度,以太坊发展蓝图中的一个阶段。第一阶段是以太坊区块链面世,代号为frontier,第二个阶段即为当前阶段,代号为Homestead(家园),第三阶段为Metropolis(大都会),大都会又细分为两个小阶段,第一个是Byzantium(拜占庭)硬分叉(引入新型零知识证明算法以及pos权益证明共识算法),第二个是Constantinople(君士坦丁堡)硬分叉(以太坊正式应用pow和pos混合链,解决拜占庭引发的问题)。最后一个阶段代号Petersburg(彼得堡),最终版本的以太坊稳定运行。

(3)eip150Block: EIP 150 硬分叉区块高度。

(4)eip155Block: EIP 155 硬分叉区块高度。

(5)eip158Block: EIP 158 硬分叉区块高度。

(6)byzantiumBlock: Byzantium 硬分叉区块高度。

(7)constantinopleBlock: Constantinople 硬分叉区块高度。

(8)petersburgBlock: Petersburg 硬分叉区块高度。

(9)clique: 实现的是PoA(权威证明,Proof of Authority)共识。

(10)ethash: 实现的是PoW(工作量证明,Proof of Work)共识。

注意:在以太坊的官方源码中,有两个共识算法:clique和ethash,它们都位于以太坊项目的consensus目录下。在以太坊中clique仅在测试网络里使用,真实的以太坊主网还是使用PoW算法(ethash模块实现)。但在自己组成私有网络时,你可以自由选择使用clique还是ethash。本配置文件中clique与ethash只能二选一。

2.alloc: 用来预置账号以及账号的以太币数量,因为私有链挖矿比较容易,所以不需要预置有币的账号,需要的时候自己创建即可以。

3.nonce:一个64位随机数,用于挖矿,和mixhash的设置需要满足以太坊的Yellow paper, 4.3.4.Block Header Validity (44)章节所描述的条件。以证明在该块上进行了足够的计算。

4.difficulty: 设置计算区块的难度,如果数值过大,挖矿时间较长,在测试环境为节省算力和等待时间可设置较小值。它可以根据前一个块的难度级别和时间戳来计算。难度越高,Miner必须执行的统计更多计算才能发现有效块。此值用于控制区块链的块生成时间,将块生成频率保持在目标范围内。

5.mixhash:与nonce配合用于挖矿,由上一个区块的一部分生成的hash。和nonce的设置需要满足以太坊的Yellow paper, 4.3.4. Block Header Validity, (44)章节所描述的条件。以证明在该块上进行了足够的计算。

6.coinbase: 矿工账号,随便填写。

7.timestamp: 设置创世块的时间戳,"0x00"表示北京时间“1970-01-01 08:00:00”。时间戳还允许验证链内的块顺序。

8.parentHash: 上一个区块的hash值,因为是创世块,所以这个值是“0”。

9.extraData: 附加信息,随便填,可以填你的个性信息,必须为十六进制的字符串。

10.gasLimit: 该值设置对gas的消耗总量限制,用来限制区块能包含的交易信息总和。私有链可以填很大,最大“0xffffffff”。

 

4、创世区块初始化

本文实际配置的genesis.json如下:

{
  "config": {
    "chainId": 202005,
    "homesteadBlock": 0,
    "eip155Block": 0,
    "eip158Block": 0
  },
  "alloc": {
    "7610fd66c272332edd59a43460ad24eee1973bfe": {"balance": "1000000000"}
  },
  "nonce": "0x000000000000002a",
  "difficulty": "0x020000",
  "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "coinbase": "0x0000000000000000000000000000000000000000",
  "timestamp": "0x00",
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "extraData": "0x68656c6c6f20776f726c642021",
  "gasLimit": "0x2fefd8"
}

1.执行以下命令来启动初始化创世块的命令:

C:\Program Files\Geth>geth --datadir "d:/data_init1/" init genesis.json

本文将初始化json文件放在geth同级目录下,如果放在其他目录下,指定具体的路径即可。该命令同时创建了一个data_init1目录专门存储节点数据,执行完成会发现在该目录下多出两个目录,一个为geth一个为keystore。其中geth里面放数据相关信息,keystore里面放加密过的私钥文件。

执行时打印日志如下:

C:\Program Files\Geth>geth --datadir "d:/data_init1/" init genesis.json
INFO [05-14|11:40:36] Maximum peer count                       ETH=25 LES=0 total=25
INFO [05-14|11:40:36] Allocated cache and file handles         database=d:\\data_init1\\geth\\chaindata cache=16 handles=16
INFO [05-14|11:40:36] Writing custom genesis block
INFO [05-14|11:40:36] Persisted trie from memory database      nodes=1 size=196.00B time=0s gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [05-14|11:40:36] Successfully wrote genesis state         database=chaindata                       hash=abff60…e74751
INFO [05-14|11:40:36] Allocated cache and file handles         database=d:\\data_init1\\geth\\lightchaindata cache=16 handles=16
INFO [05-14|11:40:36] Writing custom genesis block
INFO [05-14|11:40:36] Persisted trie from memory database      nodes=1 size=196.00B time=0s gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [05-14|11:40:36] Successfully wrote genesis state         database=lightchaindata                       hash=abff60…e74751

C:\Program Files\Geth>

经过以上命令,已经完成了私有连的初始化工作。因为本文要建立联盟链,因此需要再创建执行一遍同样的命令,json文件必须相同,datadir目录必须不同。本文使用data_init2和data_init3目录来存储第二个节点和第三个节点的数据。

C:\Program Files\Geth>geth --datadir "d:/data_init2/" init genesis.json
INFO [05-14|11:48:14] Maximum peer count                       ETH=25 LES=0 total=25
INFO [05-14|11:48:14] Allocated cache and file handles         database=d:\\data_init2\\geth\\chaindata cache=16 handles=16
INFO [05-14|11:48:14] Writing custom genesis block
INFO [05-14|11:48:14] Persisted trie from memory database      nodes=1 size=196.00B time=0s gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [05-14|11:48:14] Successfully wrote genesis state         database=chaindata                       hash=abff60…e74751
INFO [05-14|11:48:14] Allocated cache and file handles         database=d:\\data_init2\\geth\\lightchaindata cache=16 handles=16
INFO [05-14|11:48:14] Writing custom genesis block
INFO [05-14|11:48:14] Persisted trie from memory database      nodes=1 size=196.00B time=1.0045ms gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [05-14|11:48:14] Successfully wrote genesis state         database=lightchaindata                       hash=abff60…e74751

C:\Program Files\Geth>geth --datadir "d:/data_init3/" init genesis.json
INFO [05-14|11:48:21] Maximum peer count                       ETH=25 LES=0 total=25
INFO [05-14|11:48:21] Allocated cache and file handles         database=d:\\data_init3\\geth\\chaindata cache=16 handles=16
INFO [05-14|11:48:21] Writing custom genesis block
INFO [05-14|11:48:21] Persisted trie from memory database      nodes=1 size=196.00B time=0s gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [05-14|11:48:21] Successfully wrote genesis state         database=chaindata                       hash=abff60…e74751
INFO [05-14|11:48:21] Allocated cache and file handles         database=d:\\data_init3\\geth\\lightchaindata cache=16 handles=16
INFO [05-14|11:48:21] Writing custom genesis block
INFO [05-14|11:48:21] Persisted trie from memory database      nodes=1 size=196.00B time=997.2µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [05-14|11:48:21] Successfully wrote genesis state         database=lightchaindata                       hash=abff60…e74751

C:\Program Files\Geth>

2.初始化创世块可能的错误:

(1)Fatal: invalid genesis file: missing 0x prefix for hex data:这个错误信息意思很明白,就是你的json文件中,对于16进制数据,需要加上“0x”前缀。

(2)Fatal: invalid genesis file: hex string has odd length: 从v1.6开始,设置的十六进制数值,不能是奇数位, 比如不能是“0x0”,而应该是“0x00”。

(3)Fatal: failed to write genesis block: genesis has no chain configuration :这个错误信息,就是说,你的json文件中,缺少config部分。看到这个信息,我们不需要把geth退回到v1.5版本,而是需要加上config部分。

(4)Error: invalid sender undefined: 这个错误不会导致初始化失败,但是会在以后的转账(eth.sendTransaction),或者部署智能合约的时候产生。解决方法就是chainId 不能设置为0。 

 

5、启动联盟链

本文在同一台机器启动联盟链,开三个窗口来启动三个节点。需要注意的是,虽然是三个节点,但他们的启动程序都是geth,只不过datadir目录不同而已。
在cmd窗口执行以下命令启动节点,注意启动之后不要关闭窗口。

geth --datadir "datadir" --networkid 666 --identity "node" --port 30303 --rpc --rpcport 8545 --rpcapi "db,eth,eth,net,web3,admin" --rpcaddr "0.0.0.0" --rpccorsdomain "*" --nodiscover --verbosity 4 console

参数简介:

  • --networkid         : 指定网路ID,与genesis.json中的chainId一致;
  • --identity             : 设置节点ID;
  • --port                  : 节点端口,默认是30303;
  • --rpc                    : 启用 rpc 服务;
  • --rpcport             : rpc 服务端口,默认是8545;
  • --rpcaddr            : http-rpc服务器接口地址:默认“127.0.0.1”
  • --rpccorsdomain : 相当于域名白名单,“*”是允许通过任意域名访问;
  • --nodiscover        : 此参数确保geth不去寻找peers,主要是为了严格控制联盟链连入的节点;
  • --verbosity           : 日志等级:0=silent, 1=error, 2=warn, 3=info, 4=debug, 5=detail ;默认是3;
  • console                : 进入控制台。

本文启动第一个节点命令:

geth --datadir "d:/data_init1/" --networkid 202005 --port 30303 --rpc --rpcport 8545 --rpcapi "eth,net,web3,admin" --rpccorsdomain "*" --nodiscover  console

注意:在windows中,同一台主机启动第二个节点如果报错:“Fatal: Error starting protocol stack: Access is denied.”;需要添加参数:--ipcdisable;停止ipc。

本文启动第二个节点命令:

geth --datadir "d:/data_init2/" --networkid 202005 --port 30305 --rpc --rpcport 8547 --rpcapi "eth,net,web3,admin" --rpccorsdomain "*" --nodiscover --ipcdisable console

本文启动第三个节点命令:

geth --datadir "d:/data_init3/" --networkid 202005 --port 30307 --rpc --rpcport 8549 --rpcapi "eth,net,web3,admin" --rpccorsdomain "*" --nodiscover --ipcdisable console

其中,第一个节点执行时日志如下:

C:\Program Files\Geth>geth --datadir "d:/data_init1/" --networkid 202005 --port 30303 --rpc --rpcapi "eth,net,web3,admin" --rpccorsdomain "*" --nodiscover  console
INFO [05-14|12:25:50] Maximum peer count                       ETH=25 LES=0 total=25
INFO [05-14|12:25:50] Starting peer-to-peer node               instance=Geth/v1.8.3-stable-329ac18e/windows-amd64/go1.10
INFO [05-14|12:25:50] Allocated cache and file handles         database=d:\\data_init1\\geth\\chaindata cache=768 handles=1024
WARN [05-14|12:25:50] Upgrading database to use lookup entries
INFO [05-14|12:25:50] Initialised chain configuration          config="{ChainID: 202005 Homestead: 0 DAO:  DAOSupport: false EIP150:  EIP155: 0 EIP158: 0 Byzantium:  Constantinople:  Engine: unknown}"
INFO [05-14|12:25:50] Database deduplication successful        deduped=0
INFO [05-14|12:25:50] Disk storage enabled for ethash caches   dir=d:\\data_init1\\geth\\ethash count=3
INFO [05-14|12:25:50] Disk storage enabled for ethash DAGs     dir=C:\\Users\\liyuq\\AppData\\Ethash count=2
INFO [05-14|12:25:50] Initialising Ethereum protocol           versions="[63 62]" network=202005
INFO [05-14|12:25:50] Loaded most recent local header          number=0 hash=abff60…e74751 td=131072
INFO [05-14|12:25:50] Loaded most recent local full block      number=0 hash=abff60…e74751 td=131072
INFO [05-14|12:25:50] Loaded most recent local fast block      number=0 hash=abff60…e74751 td=131072
INFO [05-14|12:25:50] Regenerated local transaction journal    transactions=0 accounts=0
INFO [05-14|12:25:50] Starting P2P networking
INFO [05-14|12:25:50] RLPx listener up                         self="enode://11ccf92aef003418bbbc278a1fb2d9162a61532bc43061c253ba68e6fd42509afd412a5ef55c065073a7caccaa5b109b2077caf38af0b724b68f9a4d372ce200@[::]:30303?discport=0"
INFO [05-14|12:25:50] IPC endpoint opened                      url=\\\\.\\pipe\\geth.ipc
INFO [05-14|12:25:50] HTTP endpoint opened                     url=http://127.0.0.1:8545 cors=* vhosts=localhost
Welcome to the Geth JavaScript console!

instance: Geth/v1.8.3-stable-329ac18e/windows-amd64/go1.10
 modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

>

第二个节点和第三个节点输出日志类似。

这样,我们就顺利的启动了三个节点,进入了控制台,接下来的操作都在控制台中进行。

你可能感兴趣的:(区块链基础)