一个区块链学习项目 GitHub:https://github.com/xianfeng92/Love-Ethereum
------------------------------------------------------
# 假设已经在Ubunbu 14.04 LTS上安装好了以太坊客户端Geth
------------------------------------------------------
## 使用Geth部署以太坊联盟链
* 以太坊Geth客户端提供了以太坊协议相关的许多功能,用户只需对创世区块、Geth参数等进行配置,就可以在自己搭建一个私有的以太坊联盟链网络。下面以同一台Ubuntu系统PC为例,使用Geth搭建一个以太坊联盟链网络。
## 创世区块文件genesis.json
__创世区块文件genesis.json是区块链最重要的识别标志之一__,每一条区块链都有唯一识别的创世区块文件,如果两台机器启动Geth时所选用的创世区块文件不同,就无法被识别为同一条区块链的成员。因此,同一条联盟链中的所有节点必须使用同一份创世区块文件进行初始化配置。
下面是一个创世区块文件genesis.json的示例。
{
"config": {
"chainId": 110,
"homesteadBlock": 0,
"eip155Block": 0,
"eip158Block": 0
},
"alloc" : {
"0x< # 某账户地址A # >": {"balance": "1000000000000000000"},
"0x< # 某账户地址B # >": {"balance": "2000000000000000000"},
"0x< # 某账户地址C # >": {"balance": "3000000000000000000"}
},
"coinbase" : "0x0000000000000000000000000000000000000000",
"difficulty" : "0x400",
"extraData" : "",
"gasLimit" : "0x2fefd8",
"nonce" : "0x0000000000000000",
"mixhash" :
"0x0000000000000000000000000000000000000000000000000000000000000000",
"parentHash" :
"0x0000000000000000000000000000000000000000000000000000000000000000",
"timestamp" : "0x00"
}
其中,config中的内容是区块链相关的基本配置参数,最重要的是链编号chainId,这是用于标识该区块链的编号,这里设为110。alloc中为以太坊账户信息,可以留空,等待部署完成后再启动以太坊创建账户,也可以预先配置好以太坊账户及其余额,这里的账户余额是以wei为单位。其下的coinbase是联盟链挖矿的收益账户,可以设置为零地址,留到运行以太坊挖矿之前再设置。difficulty是初始的挖矿难度,可以设置为较低数值,如0x400。gasLimit为每个区块所消耗的Gas限制。其余的如extraData、nonce、mixhash、parentHash以及timestamp等均可以设置为零或留空。
## 初始化配置
创建完创世区块文件之后,接下来需要创建以太坊联盟链账户。以太坊账户由一对公私钥组成,用户首先设置账户密码,然后使用Geth由账户密码生成一对公私钥,再由公钥生成账户地址,最后将账户地址添加到创世区块文件genesis.json中。
具体操作如下:
* 开启一个以太坊节点
> geth --datadir testNet console
* 查看网络中账户信息
> eth.accounts
[]
账户为空
* 创建以太坊账户
> personal.newAccount()
输入密码即可创建以太坊账户
> eth.accounts
["0x15e504a51e91ee6250412e595a00b49b9d4cab1d"]
账户创建成功!
将该地址复制到genesis.json的alloc参数中。
## 创建联盟链节点
然后将genesis.json文件和testNet文件夹复制传输到另外虚拟机中,并将testNet重命名为testNet1。接下来使用以下命令创建联盟链节点。
> geth --datadir ./testNet1 init ./genesis.json
## 搭建联盟链网络
### 获取完整节点地址
在每台机器上完成联盟链节点初始化配置之后,接下来需要将各个节点连接起来。首先要确认网络连通并且各机器的防火墙已正确配置,Geth所使用的端口正常开放(Geth常用端口有8545、30303等),然后在每个节点上使用以下命令启动Geth并获取节点的地址。
> geth --datadir ./testNet1 --networdid 110 console
然后输入:
> admin.nodeInfo.enode
enode返回的节点信息格式如下,包含节点的公钥地址和Geth端口号(默认为30303)。
"enode://8f3333a83d31763a36ec9fbb0a402a5473a409b0b3fe43d32f65c7d6619e52842d4e1678306e670f74a03c1af914ab9ef0ef3d3fda207e4828f09b850398239b@[::]:30303"
将其中的“[::]”部分替换为该机器的公网IP地址,即可得到该节点的完整地址。
### 创建静态节点文件
在任一节点的.\testNet\geth 目录下创建静态节点文件static-nodes.json,并写入其他节点的完整地址信息,格式如下:
[
"enode://< node1 public key >@< node1 IP address >:< node1 port >",
"enode://< node2 public key >@< node2 IP address >:< node2 port >",
]
在每个节点的机器上使用以下命令启动Geth并查看已连接上的其他节点信息。其中,datadir参数为联盟链的数据存储目录,每次启动时必须指定,否则默认使用公有链数据存储目录,即连接到以太坊公有链上;networkid参数为所连接的网络编号,这一编号需与创世区块文件中的chainId参数一致。如果初始化过程正确且网络状况正常,各节点Geth客户端启动后会按照 __静态节点文件__中的节点地址自动搜索连接其他节点。
> admin.peers
如果其他节点仍未连接上,可以使用动态的方法添加节点。
> admin.addPeer("enode://< node public key >@< node IP address >:< node port >")
节点相互连接之后就完成了联盟链网络的搭建。
## 测试联盟链
首先使用以下命令开启一个节点进行挖矿,其中etherbase参数为指定挖矿所得的以太币收益账户,这里的以太币只能在该联盟链的账户中使用,与公有链上的以太币是完全分隔开的; miner.start的参数为指定的挖矿线程数,由于联盟链挖矿难度低,只需开启一条线程即可。
> eth.setEtherbase(eth.accounts[0])
> miner.start(2)
如果要停止挖矿可以使用以下命令:
> miner.stop()
由于在genesis.json中挖矿难度初始值设置很低,并且以太坊自身有自动调节挖矿难度的机制,因此在联盟链中挖矿的速度很快,消耗的算力也较低,挖矿收益账户很快就会收到很多以太币。不过需要注意的是,挖矿也需要初始化过程,在挖出第一个区块之前,节点需要用大约一分钟的时间生成一个DAG有向图,之后大约两三秒钟就能生成一个区块。
挖矿节点开启之后,在另外一个节点上输入密码解锁账户并在该账户上发送交易信息。以下示例为第二个预设账户向第三个预设账户转账 1 ether,返回该交易信息的散列值。
> personal.unlockAccount(eth.accounts[1])
> eth.sendTransaction({from:eth.accounts[1],to:eth.accounts[2],value:1*1e18})
------------------------------------------------------------------------------
本文参考<<以太坊技术详解与实战>>
-----------------------------------------------------------------------------