现在所有的文件都已经准备完毕,我们可以启动fabric网络了。

一.启动orderer节点

在orderer服务器上运行:

cd ~/go/src/github.com/hyperledger/fabric/examples/e2e_cli

docker-compose -f docker-compose-orderer.yaml up -d

运行完毕后我们可以使用docker ps看到运行了一个名字为orderer.example.com的容器。

二.启动peer节点

2.1安装couchdb

我们要为每一个peer安装一个couchdb,先切换到peer0.org1服务器上。之前在获取hyperledger fabric镜像的时候已经获得了couchdb的镜像,执行docker images命令可以看到hyperledger/fabric-couchdb这个镜像,但是启动这个镜像的时候经常出现问题自动关闭,我们也可以再pull一个官方发布的couchdb。

docker pull klaemo/couchdb

couchDB在启动的时候需要指定一个本地文件夹映射成CouchDB的数据存储文件夹,所以我们可以在当前用户的目录下创建一个文件夹用于存放数据。

mkdir couchdb

下载完成后,我们只需要执行以下命令即可启用一个CouchDB的实例:

docker run -p 5984:5984 -d --name my-couchdb -e COUCHDB_USER=admin -e COUCHDB_PASSWORD=password -v ~/couchdb:/opt/couchdb/data klaemo/couchdb
启动后我们打开浏览器,访问peer0.org1的IP的5984端口的URL,peer0.org1的IP是10.0.2.11,那么URL是:
http://10.0.2.11:5984/_utils
这个时候我们就可以看到CouchDB的Web管理界面了。输入用户名admin密码password即可进入。

2.2启动peer节点和CLI容器

命令为:

cd ~/go/src/github.com/hyperledger/fabric/examples/e2e_cli
docker-compose -f docker-compose-peer0org1.yaml up –d

运行完毕后我们使用docker ps应该可以看到3个正在运行的容器。

接下来切回到peer0.org2.example.com服务器。运行相同的命令:

mkdir couchdb
docker run -p 5984:5984 -d --name my-couchdb -e COUCHDB_USER=admin -e COUCHDB_PASSWORD=password -v ~/couchdb:/opt/couchdb/data klaemo/couchdb
cd ~/go/src/github.com/hyperledger/fabric/examples/e2e_cli
docker-compose -f docker-compose-peer0org2.yaml up –d

现在我们整个Fabric网络已经成型,接下来是创建channel和运行ChainCode。

三.创建channel

我们切换到peer0.org1.example.com服务器上,使用该服务器上的cli来运行创建Channel和运行ChainCode的操作。先用以下命令进入CLI内部Bash:

docker exec -it cli bash

创建Channel的命令是peer channel create,我们前面创建Channel的配置区块时,指定了Channel的名字是mychannel,那么这里我们必须创建同样名字的Channel。

ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

peer channel create -o orderer.example.com:7050 -c mychannel -f ./channel-artifacts/channel.tx --tls true --cafile $ORDERER_CA

执行该命令后,系统会提示:

2017-10-30 18:30:35.210 UTC [channelCmd] readBlock -> DEBU 020 Received block:0

系统会在cli内部的当前目录创建一个mychannel.block文件,这个文件非常重要,接下来其他节点要加入这个Channel就必须使用这个文件。

四.各个peer加入channel

还是在peer0.org1的CLI上,我们要将这个Peer加入mychannel就很简单,只需要运行如下命令:

peer channel join -b mychannel.block

系统返回消息:

2017-10-30 18:40:21.405 UTC [channelCmd] executeJoin -> INFO 006 Peer joined the channel!

修改cli的环境变量,使其指向peer0.org2

CORE_PEER_LOCALMSPID="Org2MSP"
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
CORE_PEER_ADDRESS=peer0.org2.example.com:7051
peer channel join -b mychannel.block

这样peer0.org1和peer0.org2就都已经加入channel了。

注:这一切都是我在peer0.org1的cli内完成的,这是由于加入channel依赖 [channel-ID].block文件,而且在peer0.org1服务器的cli内也留有了peer0.org2的证书文件,因此两个节点的加入都在一个cli内完成了。其实当一个节点创建channel以后可以把[channel-ID].block文件从容器内拷贝到主机,再分发给其他节点,这样其他节点就可以通过[channel-ID].block加入channel了。当cli容器被销毁时该容器下所有的文件都会被销毁,但是如果备份了[channel-ID].block,那么即使所有的peer和cli被销毁了,也可以再次通过[channel-ID].block加入channel、同步区块。

五.更新锚节点

关于AnchorPeer,其实我的每个组织只有一个peer节点,所以更新不更新锚节点也不重要。

对于Org1来说,peer0.org1是锚节点,我们需要切换到peer0.org1服务器上并更新锚节点:

CORE_PEER_LOCALMSPID="Org1MSP"
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
CORE_PEER_ADDRESS=peer0.org1.example.com:7051

另外对于Org2,peer0.org2是锚节点,切换到peer0.org2服务器上然后执行如下命令:

CORE_PEER_LOCALMSPID="Org2MSP"
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
CORE_PEER_ADDRESS=peer0.org2.example.com:7051
peer channel update -o orderer.example.com:7050 -c mychannel -f ./channel-artifacts/Org2MSPanchors.tx --tls true --cafile $ORDERER_CA

六.chaincode的安装与运行

以上,整个Fabric网络和Channel都准备完毕,接下来我们来安装和运行ChainCode。社区联盟的chaincode代码已经在上一章贴上了。

6.1安装chaincode

在cli上为每一个peer安装链上代码

,用peer chaincode install命令可以安装指定的ChainCode并对其命名:

CORE_PEER_LOCALMSPID="Org1MSP"
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
CORE_PEER_ADDRESS=peer0.org1.example.com:7051
peer chaincode install -n mycc -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/community

安装的过程其实就是对CLI中指定的代码进行编译打包,并把打包好的文件发送到Peer,等待接下来的实例化。

切换到peer0.org2服务器,给peer0.org2安装链上代码:

CORE_PEER_LOCALMSPID="Org2MSP"
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
CORE_PEER_ADDRESS=peer0.org2.example.com:7051
peer chaincode install -n mycc -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/community

6.2实例化chaincode

实例化链上代码主要是在Peer所在的机器上对前面安装好的链上代码进行包装,生成对应Channel的Docker镜像和Docker容器。并且在实例化时我们可以指定背书策略。我们在peer0.org1服务器的cli内运行以下命令完成实例化:

CORE_PEER_LOCALMSPID="Org1MSP"
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
CORE_PEER_ADDRESS=peer0.org1.example.com:7051
peer chaincode instantiate -o orderer.example.com:7050 --tls true --cafile $ORDERER_CA -C mychannel -n mycc -v 1.0 -c '{"Args":["init"]}' -P "OR      ('Org1MSP.member','Org2MSP.member')"

使用docker ps可以看到有新的容器 dev-peer0.org1.example.com-mycc-1.0正在运行。

6.3在一个peer发起交易

我们可以调用initLedger功能,该功能会初始化两个帖子。对应的代码:

peer chaincode invoke -o orderer.example.com:7050  --tls true --cafile $ORDERER_CA -C mychannel -n mycc -c '{"Args":["initLedger"]}'

6.4在另一个节点上查询帖子

前面的操作都是在org1下面做的,那么处于同一个区块链(同一个Channel下)的org2,是否会看org1的更改呢?切换到peer0.org2服务器,由于mycc已经在前面org1的时候实例化了,也就是说对应的区块已经生成了,所以在org2不能再次初始化。我们直接运行查询命令:

CORE_PEER_LOCALMSPID="Org2MSP"
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
CORE_PEER_ADDRESS=peer0.org2.example.com:7051
peer chaincode query -C mychannel -n mycc -c '{"Args":["queryPost","POST1"]}'

因为peer0.org2也需要生成Docker镜像,创建对应的容器,才能通过容器返回结果,所以等的时间会稍长一点。我们回到Ubuntu终端,执行docker ps,可以看到peer0.org2也多了一个容器:dev-peer0.org2.example.com-mycc-1.0

七. 查看日志

这样整个区块链网络算是正式跑通了!如果想知道orderer和peer之间具体都发生了些什么我们可以进入对应的服务器,输入命令:

docker logs -f orderer.example.com
docker logs -f peer0.org1.example.com
docker logs -f peer0.org2.example.com

这样就可以查看对应的日志,也可以查询报错。

八.出错记录

8.1 阿里云问题

在前言里说过了,生成创世区块失败,但是容器连接没有问题,在docker-compose文件里每个容器里加如下一条环境变量即可解决。

GODEBUG=netdns=go

8.2 容器连接问题

peer无法连接couchdb,cli无法和orderer通信,都是timeout。首先因为容器把端口都映射在主机上了,在外网都可以访问,但是在容器内curl主机端口却失败。原因就是防火墙把宿主机的容器给墙了,关闭防火墙即可解决。

sudo ufw disable

最新文章

  1. 浅析Ajax跨域原理及JQuery中的实现分析
  2. 注册、启动、停止windows服务
  3. 【转】MySQL USE NAMES 'UTF8'
  4. 在线体验K2 BPM微信审批
  5. du -sh 目录名称 查看目录大小
  6. UVa 1149 (贪心) Bin Packing
  7. linux调度器系列
  8. 【HDOJ】4628 Pieces
  9. mysql 批量删除分区
  10. VS2015配置Andriod开发环境
  11. java基础之集合篇
  12. 钉钉自定义机器人配合SVN钩子事件进行消息的推送实践
  13. javascript中的XML
  14. Oracle Advanced Pricing White Papers
  15. TensorFlow之RNN:堆叠RNN、LSTM、GRU及双向LSTM
  16. C#中public、private、protected等关键字说明
  17. python调试之pdb
  18. centos6.9安装crontab
  19. 解决Gerrit的git unpack error问题
  20. WebAPI框架里设置异常返回格式统一

热门文章

  1. Quartz教程二:API,Job和Trigger
  2. 009——数组(九) each list array_map array_walk array_walk_recursive
  3. hdu 5802 Windows 10 (dfs)
  4. Unix系统中system函数的返回值
  5. 分布式锁-基于ZK和Redis实现
  6. 【LeetCode 110_二叉树_遍历】Balanced Binary Tree
  7. 《Effective C++》第3章 资源管理(2)-读书笔记
  8. Unicode 和 UTF-8 有何区别? - 引自知乎
  9. Python程序员不完全指南
  10. (转)MapReduce Design Patterns(chapter 3 (part 2))(六)