Ubuntu基于docker的二节点geth私链

一、准备工作

(一)、docker宿主机的时间校对

geth建立多节点私链时,本地时间如果与网络基准时间有12秒以上偏差就会导致节点之间不能建立连接,甚至影响整个私链的正常运行。所以,在所有工作开始前,务必先保证宿主机的时间是准确的。本地宿主机的操作系统是Ubuntu14.04 AMD64,系统校时的命令如下。
    $ sudo echo "Asia/Shanghai" > /etc/timezone
    $ sudo ln -sf /usr/share/zoneinfo/Asia/Shanghai  /etc/localtime
以上两步设置本地时区为亚太/上海时区。
    $ sudo ntpdate cn.pool.ntp.org
    $ sudo hwclock --systohc
以上两步设置系统时间与网络时间同步,并将系统时间写入硬件时间。如果执行上两步时发现ntpdate没安装,则执行sudo apt-get install ntpdate安装ntpdate。校准好本地宿主机的时间后,可以输入date命令查看系统时间。之后,就可以准备下载docker镜像了。

(二)、下载带有geth的docker镜像

笔者已经将“半成品”镜像制作好并上传到了docker hub上,用户只需在本地宿主机上执行如下命令就可以获取到。
    $ docker pull zhaoxiaoyu/geth:latest

(三)、加载镜像,运行容器,并向容器里拷贝时区文件

由于下载到的镜像里缺失时区相关的系统文件,用户在加载镜像运行容器时需要将宿主机的时区文件挂载到容器里,宿主机的时区文件都在/usr/share/zoneinfo/目录下。下面两个命令分别运行第一个节点和第二个节点的容器。
运行第一个节点的容器:
    $ docker run -v /usr/share/zoneinfo/:/usr/share/zoneinfo -it -p 0.0.0.0:8545:8545 zhaoxiaoyu/geth:latest /bin/bash
再开一个终端窗口,运行第二个节点的容器:
    $ docker run -v /usr/share/zoneinfo/:/usr/share/zoneinfo -it -p 0.0.0.0:8546:8545 zhaoxiaoyu/geth:latest /bin/bash
注意,上面两行命令在实际运行时根据用户的实际情况选择映射到宿主机的端口号,但需要记牢他们,以便后来通过rpc连接私链时使用。

(四)、两个节点容器的时间校对

确保了宿主机的时间准确还不够,这里需要进一步确保两个容器的时区和时间也是正确和准确的。(三)中的两行命令会自动进入容器内部的命令行,在其中一个容器内部,运行如下命令。
    # apt-get install ntpdate
    # ntpdate -s cn.pool.ntp.org
`# date`   查看时间是否正确
其中一个无误后,再在另一个容器里重复上面的命令。

至此,所有的准备工作完毕。

二、搭建含有两个节点的geth以太坊私链

(一)、新建账户

进入第一个容器命令行后,执行如下命令来新建账户。
    # geth account new
接下来会提示输入密码,回车后提示再次确认密码,再回车后会返回创建的账户的地址(又叫公钥)。重复几次,就可以建立多个账户。第二个容器进行同样的操作。

(二)、新建创世块

1、新建生成创世块的json文件
每个容器里的/home/目录下已经包含一个能生成创世块的json文件“myGenesis.json”。该文件内容如下。
vim编辑该文件,将“alloc”中的两个地址换成(一)中新建的账户,可以填(一)中新建的第一个账户和第二个账户。将“coinbase”后面的地址换成(一)中新建的第一个账户。其余的部分保持不变,然后保存。
在第二个容里进行同样的操作,保证两个节点容器的创世块json文件一模一样,以便以后将它们建立连接形成集群。

2、生成创世块

在第一个容器的命令行里执行如下命令来建立创世块
    # geth --datadir "/root/.ethereum/" init /home/myGenesis.json
如果不出问题,创世块就建立了。第二个容器进行同样的操作。

(三)、启动节点和集群

1、分别在两个容器的“/root/.ethereum/”目录下建立账号密码文件
/root/.ethereum/# vim password
然后在文件里输入每个账号对应的密码,每行对应一个账号的密码。

2、分别在两个容器的“/home/”目录下建立启动脚本文件
    /home/# vim privateChainStart.sh
然后输入如下指令,注意指令里的 - -networkid 必须相同,- -port 后面的数字要记号,便于后续建立节点之间的连接用。

 保存之后,分别在两个容器的该目录下输入bash privateChainStart.sh。之后,两个节点分别启动,并进入JS的交互式命令行。

3、增加节点

这时,在宿主机上用docker inspect <Container> 命令查看两个容器的内网IP在第一个容器的交互式命令行里输入如下命令。
>admin.addPeer(“第二个节点启动后输出的日志信息里的enode,但注意将后面’@[::]’中的’[::]’替换为第二个容器的内网IP地址”)
示例如下图所示。
稍等片刻,在第一个容器的JS交互式命令行里输入>admin.peers命令,就能看到如下连接信息。
这样,两个节点就组成了集群,并开始同步。

4、开始挖矿

在第一个节点的JS命令行里输入如下命令开始挖矿。
    >miner.start(3)
其中的数字3代表开启的挖矿线程数,开启后会有如下输出,开始挖矿。

三、测试搭建的私链

(一)、使用python测试搭建的两节点私链

在装有ethjsonrpc包的python环境里输入如下信息来测试私链。
可见,私链的第一个账户里有大量的余额,足以进行交易。账户0向账户1发起transaction后,可以得到transaction的收据,交易成功。稍等片刻,这笔交易就会被写到区块链上,如下所示。
而且,写到链上之后被矿工挖到了,并将挖到的钱存到第一个账户里,如下所示。
明显看到账户0的余额比之前多了5000000000000000000。

至此,基于docker的两个节点的私链搭建并测试完毕。

阅读更多

更多精彩内容