私有链搭建——基于以太坊

1. 前言

系统平台:Ubuntu

本文介绍了Ubuntu系统平台上基于ethereum的私有链搭建方法。通常,1台pc机作为1个私有链节点,但实际上也可以在1台PC机上运行多个以太坊节点(利于测试)。为了在本地网络运行多个以太坊节点的实例,必须确保一下几点:

  • 每个实例都有独立的数据目录(–datadir)

  • 每个实例运行都有独立的端口(eth和rpc两者都是)(–port 和–rpcprot)。

  • 在集群的情况下,实例之间都必须要知道彼此。

  • 唯一的ipc通信端点,或者禁用ipc。

以下开始构筑以太坊私有链。

2. 安装Geth客户端

详见《以太坊(客户端geth使用入门)》

3. 准备创世块文件

为了区分公有链,以太坊支持自定义创世区块,要运行私有链,我们就需要定义自己的创世区块,创世区块信息写在一个json格式的配置文件中。首先将下面的内容保存到一个json文件中,例如hcgenesis.json。

注意,同一个私有链网络中,创世块必须是一样的,否则无法联通。

{

         “config”               : {

                   “chainId”                     :  10,

                   “homesteadBlock”       : 0,

                   “eip155Block”              : 0,

                   “eip158Block”              : 0

         },

         “coinbase”          : “0x0000000000000000000000000000000000000000”,

         “difficulty”          :  “0x4000”,

         “extraData”         :  “0x00”,

         “gasLimit”           : “0xffffffff”,

         “nonce”               : “0x0000000000000042”,

         “mixhash”           : “0x0000000000000000000000000000000000000000000000000000000000000000”,

         “parentHash”      :  “0x0000000000000000000000000000000000000000000000000000000000000000”,

         “timestamp”       :  “0x00”,

         “alloc”                 :  {}

}


mixhash

与nonce配合用于挖矿,由上一个区块的一部分生成的hash。注意他和nonce的设置需要满足以太坊的Yellow paper, 4.3.4. Block Header Validity, (44)章节所描述的条件

nonce

nonce就是一个64位随机数,用于挖矿,注意他和mixhash的设置需要满足以太坊的Yellow  paper, 4.3.4. Block Header Validity, (44)章节所描述的条件

difficulty

设置当前区块的难度,如果难度过大,cpu挖矿就很难,这里设置较小难度

alloc

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

coinbase

矿工的账号,随便填

timestamp

设置创世块的时间戳

parentHash

上一个区块的hash值,因为是创世块,所以这个值是0

extraData

附加信息,随便填,可以填你的个性信息

gasLimit

该值设置对GAS的消耗总量限制,用来限制区块能包含的交易信息总和,因为我们是私有链,所以填最大。

 

常遇到的几个错误:

  • Fatal: invalid genesis file: missing 0x prefixfor hex data

这个错误信息意思很明白,就是你的json文件中,对于16进制数据,需要加上0x前缀

  • Fatal: invalid genesis file: hex string has oddlength

从v1.6开始,设置的十六进制数值,不能是奇数位,比如不能是0x0,而应该是0x00。

  • Fatal: failed to write genesis block: genesishas no chain configuration

这个错误信息,就是说,你的json文件中,缺少config部分。看到这个信息,我们不需要把geth退回到v1.5版本,而是需要加上config部分。

  • Error: invalid sender undefined

这个错误不会导致初始化失败,但是会在以后的转账(eth.sendTransaction),或者部署智能合约的时候产生。解决方法就是chainId 不能设置为0。如果你完全按照github上给的官方配置文件,就会产生这个错误。

4. 启动第1个节点

4.1. 初始化创世块


# cd /home/zhazha/ethereum/privatechain(hcgenesis.json放在该目录下)

# geth –datadir  data0  init hcgenesis.json

上面的命令的主体是geth init,表示初始化区块链,命令可以带有选项和参数,其中–datadir选项后面跟一个目录名,这里为data0,表示指定数据存放目录为data0,genesis.json是init命令的参数。该命令自动创建data0目录,其中geth/chaindata中存放的是区块数据,keystore中存放的是账户数据。

4.2. 启动私有链节点


启动Geth即可以启动以太坊的区块链,为了构建私有链,需要在Geth启动时加入一些参数,Geth各参数含义如下: 

identity

区块链的标示,随便填写,用于标示目前网络的名字

init

指定创世块文件的位置,并创建初始块

datadir

设置当前区块链网络数据存放的位置

port

网络监听端口

rpc

启动rpc通信,可以进行智能合约的部署和调试

rpcaddr

Rpc接口地址

rpcport

Rpc接口端口号

rpcapi

设置允许连接的rpc的客户端,一般为db,eth,net,web3

networkid

设置当前区块链的网络ID,用于区分不同的网络,是一个数字。网络ID在连接到其他节点的时候会用到,以太坊公网的网络ID是1,为了不与公有链网络冲突,运行私有链节点的时候要指定自己的网络ID。

console

启动命令行模式,可以在Geth中执行命令

nodiscover

禁止被网络中其它节点发现,需要手动添加该节点到网络

verbosity

打印详细的日志信息

targetgaslimit

每个块的gas上限,这里可以暂时理解为容量

rpccorsdomain   

限制rpc访问源的ip,代表不限制

nodiscover   

禁止被网络中其他节点发现,需要手动添加该节点到网络。

maxpeers 

最大节点数量

unlock 

解锁某用户(此处用用户坐标来控制,解锁后的用户调用接口发起交易时,不要需要提供密码)

mine 

允许挖矿

ipcdisable   

如果不设置–ipcdisable,在datadir目录下会有文件geth.ipc。可通过命令 # geth  attach  geth.ipc打开节点。

启动私有链节点的命令是:

# geth –targetgaslimit 4294967295  –identity  “HcEthereum”  –rpc  –rpcaddr”192.168.1.74″  –rpcport  8101  –rpccorsdomain  “*” –datadir  data0  –ipcdisable  –port 30303  –rpcapi  “personal,db,eth,net,web3”  –networkid 168  -nodiscover  -maxpeers 5  -unlock  0  -mine  console


或者上述命令可简化为:

# geth –datadir  data0  –ipcdisable –port  30303  –rpcport 8101  –networkid  168 console


上面命令的主体是geth console,表示启动节点并进入交互式控制台,–datadir选项指定使用data0作为数据目录,–networkid选项后面跟一个数字,这里是168,表示指定这个私有链的网络ID为168。

5. 启动第2个节点

5.1. 初始化创世块


cd /home/zhazha/ethereum/privatechain(hcgenesis.json放在该目录下)

geth –datadir  data1  init hcgenesis.json

5.2. 启动私有链节点


geth –datadir  data1  –ipcdisable –port  30306  –rpcport 8201  –networkid  168 console

6. 启动第n个节点

请参考第4,5节。

按照这样的方式继续扩展,可以非常容易就可以建立本地节点集群。这些工作都可以写成脚本代码来完成,里面还可以包含创建账户,挖矿等。

请参考:https://github.com/ethersphere/eth-utils下的gethcluster.sh脚本,以及README中的使用方法和示例。

7. 链接节点

有2种方法建立节点集群。

7.1. 方法1


  • 获得连接目标节点(例如第1个节点)的节点号,在第一个节点运行下面命令。


> admin.nodeInfo.enode

“enode://12bcaeb91de58d9c48a0383cc77f7c01decf30c7da6967408f31dc793e08b14e2b470536ebe501a4f527e98e84c7f5431755eae5e0f4ba2556539ab9faa77318@[ : : ]:30303”


  • 在第2个节点添加peer

>admin.addPeer(“enode://12bcaeb91de58d9c48a0383cc77f7c01decf30c7da6967408f31dc793e08b14e2b470536ebe501a4f527e98e84c7f5431755eae5e0f4ba2556539ab9faa77318@192.168.1.74:30303”)


注意:添加peer时,节点1的红色部分[ : : ]需变更为节点1的ip地址,其他拷贝即可。

7.2. 方法2


用下面命令启动私有链节点(注意红色部分):

# geth –datadir  data1  –ipcdisable –port  30306  –rpcport 8201  –networkid  168  –bootnodes ” enode://12bcaeb91de58d9c48a0383cc77f7c01decf30c7da6967408f31dc793e08b14e2b470536ebe501a4f527e98e84c7f5431755eae5e0f4ba2556539ab9faa77318@192.168.1.74:30303″  console


注:该方法目前未验证。

7.3. 相关命令


可在各节点用以下命令查询节点和链接信息:

  • admin.nodeInfo.enode

         本节点节点码。

                     

  • admin.nodeInfo.enode

         本节点详细信息。

  • net.peerCount

         伙伴节点数量。peer添加成功后,该值将加1(比如,由0变1)。

  • admin.peers

         伙伴节点信息列表。

8. 数字货币转账

转账方法可参考《以太坊(客户端geth使用入门)》中的相关章节。

注意:

  • 转账账户需解锁

  • 需用全网唯一的钱包帐号(红色部分)才能网络转账。

         eth.sendTransaction({from:”0x66c62f1afa08eae5343bd2b3129e0ae9aa141fc3″,to: “0xd600f5622024bb8f53ca3f0506cf1a13c811e17b”,value: web3.toWei(1, “ether”)})


  • 需挖矿让转账生效

miner.start()

9. 设置coinbase帐号

  • > miner.setEtherbase(“帐号”)

 

 – END – 



往期精彩文章导读:


流传最广的区块链研究报告


麦肯锡《区块链,银行业游戏规则的颠覆者》报告导读


穆迪《区块链的现状及未来》报告导读


TED演讲:区块链将如何改变金融与贸易(文字版)


顶级投资人和经济学家是如何看待区块链?