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