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 – 
往期精彩文章导读: