Docker容器化快速构建多集群以太坊网络并部署智能合约

本次打算把私链构建的脚本容器化,达到基于配置文件快速进行区块链网络构建的能力。
以太坊智能合约开发者可以基于以太坊的测试网络进行合约的测试,但是如果想进行持续集成和持续测试(CI&CT),建立一个本地的可控区块链网络非常有必要,另外考虑到未来容器化集群分布式部署的需要,本人特意制作了相关的docker image,这样初学者或者想要构建自己网络的用户就可以在不需要太多了解命令的情况下,运行起自己的网络。能够快速运行起网络并部署智能合约,看到部署的智能合约的效果,对于初学者提高学习效率和提升学习动力具有非常大的作用。

一、测试环境构建说明
作者已经将相关docker image发布在docker hub上,相关的docker compose发布在git hub上,读者可以根据以下的描述快速构建起自己的以太坊区块链网络。
为了快速构建以太坊的多节点集群网络环境,作者将以太坊启动参数化,通过docker compose按照需要启动cluster服务,以下图为例构建区块链网络。


 
作者拟打算构建两个cluster,cluster0和cluster1,每个cluster有4个geth节点,这些节点都用cluster0 的peer 00 作为boot node,cluster1上的4个节点作为验证节点负责挖矿,cluster0的4个节点作为普通节点连接到网络上,所有的geth节点都使用相同的创世文件生成,cluster0和cluster1分别部署在docker 容器里。网络部署的拓扑结构如上图所示。当然按照实际情况,读者可以不必拘泥于上述结构,可以部署更多的cluster,每个cluster也可以只有1个geth节点,只需按照要求修改docker compose文件即可。

二、测试环境构建过程
本次实践我们部署的docker都是运行在一个Ubuntu Linux上,这个Ubuntu Linux是我通过vmware虚拟出来的一个虚机,虚机网络都采用NAT方式,共享host主机的外部网络。其主要参数如下:
Ubuntu 16.04 LTS RAM 4G
IP: 192.168.5.172   gateway: 192.168.5.2  hostname: ubu-blockchain2
Docker Network Bridge
gateway: 172.16.238.0.1  由于指定IP,我们运行的两个cluster的所在container的IP如下:
172.16.238.10: geth-cluster0
172.16.238.11: geth-cluster1

为了便于读者快速进行环境构建和应用测试,本人已经将ethereum测试环境构建所需要的相关资源上传至 github,https://github.com/blockchain101/ethereum-docker
 
所用到的docker images也都上传至docker hub,参见blockchain101/ethereum-geth:1.6.5, 
blockchain101/ethereum-solc:0.4.11
 
 

2.1 首先请安装Docker容器和docker-compose运行环境
请参照安装Docker容器和docker-compose运行环境。
使用docker-compose比较方便的地方是,可以使用别人已经编好的docker-compose.yaml 自动从docker hub pull images并且自动构建应用。

2.2 读者可自行从github下载ethereum-docker 资源
  1. $ git clone https://github.com/blockchain101/ethereum-docker.git
复制代码
2.3 通过docker-compose直接启动测试网络
  1. $ cd ethereum-docker/ethereum-docker/ethereum-testnet-docker/
  2. $ docker-compose -f docker-compose-ethereum-testnet.yaml up
复制代码
 
完全下载image后,会出现cluster0和cluster1的启动界面,由于初始值是需要做全局初始化,生成各节点账号,生成节点数据文件,如果指定基于genesis文件,会生成基于genesis文件的区块链创世区块,另外整个集群会设定某个节点作为bootnode,当然为了可用性,可以改进让每个cluster都设定一个节点作为bootnode,默认的配置cluster0中的四个节点是观察节点,cluster1的四个节点是验证挖矿节点。bootnode文件,genesis文件以及ethash DAG文件作为所有集群共享的文件放在ethcluster_share目录中。系统还自动创建出ethcluster目录,用于放置cluster0和cluster1的区块链数据文件。
由于是第一次启动挖矿节点,需要建立DAG,这个过程会花费很长时间,在这个过程中,我们先做一些配置修改,由于cluster0的四个节点都不挖矿,我们的目的是借助于genesis文件赋予这四个节点的账号有初始的ether,分别给予10,11,12,13个ether给这四个节点,这就需要把这四个节点的账号设置到genesis文件中。请按照下图先查看cluster0四个节点对应的账号。
 
然后更新genesis文件中的alloc部分的账号内容。
 
我们需要重新设定docker compose的启动选项,将cluster0的INIT_CONFIG从Y修改成GENESIS_BLOCK_REGEN,重新启动docker后,对于cluster0不会再生成账号,但是会重建区块链genesis block数据,对于cluster1还是会重新生成账号和基于新的genesis文件初始化genesis block并启动,这样这个网络都会确认上述对genesis文件的修改,确保cluster0的四个节点分别有10,11,12,13个初始ether。当然这个过程可以完全自动化一次性实现,但是为了向初学者演示以太坊这个特性,还是采用手动的方式操作。
 
我们现在等待第一次启动的docker compose的挖矿节点把DAG都生成好,停止网络,并再次启动网络基于新的genesis重新启动区块链网络。
 
当cluster1出现mining potential block日志时,说明DAG 已经准备好30000 blocks epoch0,我们停止当前docker compose,并且重启docker compose。
另外打开两个终端,分别输入命令,启动连接到cluster0 peer01和cluster1 peer01的控制台

  1. $ geth attach http://192.168.5.172:8201 #访问 cluster1 peer01 console
  2. $ geth attach http://192.168.5.172:9201 #访问 cluster1 peer01 console
复制代码
注意:如果本地机器没有geth命令,可以启动容器来执行geth命令
  1. $ docker run -i blockchain101/ethereum-geth:1.6.5 geth attach http://192.168.5.172:8201 #访问 cluster1 peer01 console
  2. $ docker run -i blockchain101/ethereum-geth:1.6.5 geth attach http://192.168.5.172:9201 #访问 cluster1 peer01 console
复制代码
cluster0 peer01上执行net.peerCount和检查主账号的ether值
 
显示出写在genesis文件中的账号"0xc7f9a898d14f91fde9a3d37c150c6a4f9b104545"的ether值是11,我们在cluster1 peer01的console同样查看该账号值也是11,另外eth.accounts[0]作为挖矿奖励的默认账户也存在ether值。
 
读者可以检查其他几个写在genesis文件中的账号的ether值,也可以连接到其他的节点。

三、 智能合约的编译
下面我们进行智能合约的编译,我们将编译一个简单的合约叫sample.sol,只是进行一个值的设置和查询。
首先在当前目录下建立一个目录ethcontract,在目录中建立sample.sol文件

  1. contract Sample {
  2.     uint public value;

  3.           function Sample(uint v){
  4.                     value=v;
  5.           }

  6.           function set(uint v){
  7.                     value=v;
  8.           }

  9.           function get() constant returns (uint){
  10.                     return value;
  11.           }
  12. }
复制代码
读者可以使用remix开发工具,进行合约的编写和测试。

我们使用solc执行合约的编译,执行命令,生成合约接口abi文件和evm二进制bin文件

  1. $ solc --abi -o ethcontract ethcontract/sample.sol
  2. $ solc --bin -o ethcontract ethcontract/sample.sol
复制代码
如果本地机器没有solc,可以使用容器执行solc命令,这样在ethcontract目录会生成出Sample.abi和Sample.bin两个文件
  1. $ docker run -v ~/ethereum-docker/ethereum-docker/ethereum-testnet-docker/dockercomposefiles/ethcontract:/ethcontract blockchain101/ethereum-solc:0.4.11 solc --bin  --overwrite -o /ethcontract /ethcontract/sample.sol
  2. $ docker run -v ~/ethereum-docker/ethereum-docker/ethereum-testnet-docker/dockercomposefiles/ethcontract:/ethcontract blockchain101/ethereum-solc:0.4.11 solc --abi  --overwrite -o /ethcontract /ethcontract/sample.sol
复制代码
我们需要修改这两个文件分别增加相应的变量赋值SampleABI和SampleHEX,这样在加载合约abi和bin的时候,可以通过控制台直接访问到这个变量。
 
后面我们将这个智能合约编译后的版本发布在区块链网络上。

四、 智能合约的部署和访问
我们连接到cluster0 的peer01节点上执行上面编译后的合约的发布。

  1. > primary=eth.accounts[0]
  2. > balance=web3.fromWei(eth.getBalance(primary),"ether")
  3. > loadScript("./ethcontract/Sample.abi")
  4. > loadScript("./ethcontract/Sample.bin")
  5. > sample=eth.contract(SampleABI)
  6. > thesample=sample.new(10,{from:primary,data:SampleHEX,gas:3000000})
  7. > samplerecpt=eth.getTransactionReceipt(thesample.transactionHash)
  8. > samplecontract=sample.at(samplerecpt.contractAddress)
  9. > samplecontract.get.call()
  10. > samplecontract.set.sendTransaction(9, {from:primary, gas:3000000})
  11. > samplecontract.get.call()

复制代码
 
 
 
 

我们再打开一个终端,打开cluster1的peer02的控制台,直接at到上一个终端部署的智能合约地址并进行set操作
  1. > primary=eth.accounts[0]
  2. > loadScript("./ethcontract/Sample.abi")
  3. > loadScript("./ethcontract/Sample.bin")
  4. > sample=eth.contract(SampleABI)
  5. > samplecontract=sample.at("0x8087fa310b15579f7e1423aafc199c10c91a5dfb")
  6. > samplecontract.get.call()
  7. > samplecontract.set.sendTransaction(6, {from:primary, gas:3000000})
  8. > samplecontract.get.call()
复制代码
 
 
 
再回到cluster0 的peer01节点的控制台,也查询到的最新的值。

值得提醒的是,如果docker compose停止后,若下次再想从上次的区块继续进行下去,需要修改docker compose文件geth_cluster0和geth_cluster1的INIT_CONFIG值为N,然后启动docker compose。

至此,我们使用docker容器快速构建以太坊多集群网络并部署智能合约整个过程全部完成。

你可能感兴趣的:(以太坊,docker-工具)