运行fabric-samples项目中的一个例子:first-network,创建第一个网络(Building Your First Network)。

该网络共有4个peer节点,划分为2个组织(organizations),以及1个单独的orderer节点,另外还需要一个容器来执行创建和加入channel、部署和执行chaincode等命令。

运行该例子需要下载的文件有:fabric-samples项目特定的平台二进制文件所需的镜像文件

准备

项目下载

在已设置的GOPATH路径下从github克隆fabric-samples项目

mkdir -p ~/go/src/github.com/hyperledger
cd ~/go/src/github.com/hyperledger
git clone -b master https://github.com/hyperledger/fabric-samples.git
cd fabric-samples
平台文件和镜像文件

一、脚本自动化下载

1.官方文档提供了极为简便的命令,运行即可完成下载

curl https://goo.gl/6wtTN5 | bash -s 1.1.0-alpha

版本可自由选择,这里选的是1.1.0-alpha

2.由于上面的curl命令使用的是google的短网址,在国内下载缓慢,文档提供了可替换的url,命令如下:

curl -sSL https://github.com/hyperledger/fabric/blob/master/scripts/bootstrap.sh | bash -s 1.1.0-alpha

3.上面的下载本质上是利用fabric项目中的bootstrap.sh脚本,所以也可以直接运行https://github.com/hyperledger/fabric/blob/master/scripts/bootstrap.sh。最后将下载后的bin目录至于fabric-samples中并添加到系统环境变量。

二、手动分步下载

1.特定的二进制平台文件(Platform-specific Binaries)

先下载平台文件,打开bootstap.sh脚本文件查看源码,可以找到下载地址,选择合适的版本,当前最新是darwin-amd64-1.1.0-alpha/,然后选择hyperledger-fabric-darwin-amd64-1.1.0-alpha.tar.gz

解压后可获得bin目录,其中包含文件cryptogen, configtxgen, configtxlatorpeer。将bin目录至于fabric-sample目录下并加入系统环境变量,打开配置文件vim ~/.bash_profile后添加

export PATH=$HOME/hyperledger/fabric-samples/bin:$PATH

2.镜像文件下载(images)

所需的镜像文件有peer, orderer, ca, ccenv, javaenv, kafka, zookeeper, couchdbtools。通过docker pull命令从docker hub中逐一拉取镜像,例如:

docker pull hyperledger/fabric-peer:x86_64-1.1.0-alpha

注意后面要带上标签,否则会下载失败,全部拉取完成后,为了保证网络的成功运行,需要给每个镜像打上latest标签。格式和示例如下:

docker tag IMAGEID(镜像id) REPOSITORY:TAG(仓库:标签)
docker tag f00c5d490d19 docker.io/hyperledger/fabric-peer:latest

运行

1.生成配置信息
cd ~/hyperledger/fabric-samples
./byfn.sh -m generate

该命令利用平台文件中的crypotogenconfigtxgen工具主要完成以下工作:生成网络成员所需的证书和密钥,生成创世排序区块(Orderer Genesis block),以及生成一系列配置channel所需的配置交易(configuration transactions),并且生成Org1和Org2的Anchor节点更新交易。成功执行后,生成crypto-config目录和channel-artifacts目录。

2.启动网络
./byfn.sh -m up

该行命令利用docker-compose up命令运行所有镜像,主要完成的工作有:构建4个peer节点和1个orderer节点,创建channel并把4个peer节点加入其中,在各peer节点上安装chaincode并执行相关操作。

3.结束运行

./byfn.sh -m down

该命令会终止所有正在运行的容器,删除生成的配置文件,并删除chaincode镜像。

分析

1.证书生成器
  • 使用二进制平台文件中的cryptogen工具来为网络中的实体生成证书(certificates),这些证书是身份的象征,它们允许我们的实体在交流和交易的时候进行签名(sign)和身份验证(verify authentication)。

  • cryptogen工具读取包含网络拓扑信息的crypto-config.yaml配置文件来生成相关证书,并为组织和这些组织的成员生成一组证书和密钥。每个组织都分配了一个唯一的根证书(ca-cert),它将特定成员(peers and orderer)绑定到该组织。在这个典型的网络中,成员将使用证书授权(Certificate Authority)生成属于自己的证书,Hyperledger Fabric中的交易和通信由实体的私钥(keystore)签名,然后通过公钥(signcerts)进行验证。

2.配置交易生成器
  • configtxgen tool用来生成4个配置文件:

    orderer genesis block:排序服务(ordering service)的创世区块。

    channel configuration transaction:通道配置交易,会在channel创建时广播给orderer。

    two anchor peer transactions:指定通道上两个组织的锚节点(Anchor Peer)。

  • configtxgen tool读取配置文件configtx.yaml,该文件包含该简单网络的定义。

    1.文件顶部的Profiles部分有两个头部,一个是TwoOrgsOrdererGenesis用于生成orderer genesis block,一个是TwoOrgsChannel,用于生成channel配置交易,这两个头部会在生成配置信息作为参数传递进去。

    2.文件的Organizations部分显示该网络有3个成员,OrdererOrg,Org1,Org2。文件指定了一个联盟(SampleConsortium),由两个Peer Orgs组成。每个Org中指定了MSP的目录位置,其中两个Peer Org里还指定了AnchorPeers,该值定义了能够用于跨越组织通信(cross org gossip communication)的节点的位置。该部分将会在后续的配置中被引用。

    3.文件的Orderer部份定义了一些将会用作排序相关操作参数的值,它们被编码(encode)入配置交易或者创世区块中。

  • 配置文件中保存了网络每个成员(组织和节点)的MSP目录,因此可以将每个组织的根证书(cacerts)存储在orderer genesis block中,当网络实体与ordering service通信时,就能对实体的数字签名进行验证。过程是:通过创世排序区块中的CA证书得到CA公钥,然后用CA公钥对交易或通信中的证书进行验证,身份验证成功后得到实体节点的公钥,然后用该公钥来验证信息的完整性。

3.手动运行工具
  • 生成证书

    当前路径位于first-network目录下,bin文件在上一级目录fabric-samples中,运行以下命令后证书和秘钥(也就是MSP material)会被输出到crypto-config目录中。

    ../bin/cryptogen generate --config=./crypto-config.yaml
  • 生成创世区块

    首先需要告诉configtxgen去哪找到需要的配置文件configtx.yaml,所以要在执行命令前先设置一个环境变量

    export FABRIC_CFG_PATH=$PWD
    ../bin/configtxgen -profile TwoOrgsOrdererGenesis -outputBlock ./channel-artifacts/genesis.block
  • 创建channel配置交易(channel.tx)

    执行命令前需要设置$CHANNEL_NAME环境变量。

    export CHANNEL_NAME=mychannel
    ../bin/configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID $CHANNEL_NAME

    接下来,在我们正在构建的channel上定义两个anchor peer(for Org1 and Org2)。

    ../bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org1MSP
    ../bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org2MSP

    生成的order genesis block 和 channel transaction artifacts都将输出到channel-artifacts目录下。最终目录包含4个文件:genesis.block,channel.tx,Org1MSPanchors.tx和Org2MSPanchors.tx

4.启动网络
  • 注意: 在运行之前,需要修改docker-compose-cli.yaml文件,注释掉以下一行:

    command: /bin/bash -c './scripts/script.sh ${CHANNEL_NAME} ${DELAY}; sleep $TIMEOUT'

    该行代码会使cli容器运行的时候自动运行脚本script.sh,会进行创建channel,加入节点等等一系列操作,此时如果再进行手动执行,并把CHANNEL_NAME设置为mychannel,就会出现channel名称重复问题,从而报错 Error: got unexpected status: BAD_REQUEST

    运行docker-compose命令启动网络

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

    如果cli容器处于睡眠状态,可通过docker run cli重新运行。

  • 创建channel并加入节点

    CLI容器针对peer0.org1.example.com操作所需要的环境变量已经设置好了,但如果需要对其他peer或者orderer节点进行操作,则需要提供这些变量值。

    首先进入CLI容器中:

    docker exec -it cli bash

    接下来先定义CHANNEL_NAME变量,然后创建channel,将channel.tx作为创建channel请求的一部分发送给orderer,其中-c参数是channel name,-f参数是channel配置交易(channel.tx),--cafile参数指定了orderer的根证书路径,用于验证TLS握手。

    export CHANNEL_NAME=mychannel
    peer channel create -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/channel.tx --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

    上述命令将生成一个<channel-ID.block>,在这里是mychannel.block,现在将节点peer0.org1.example.com加入channel。

    peer channel join -b mychannel.block

    当需要加入其它节点的时候,需要将环境变量传入,这里继续加入peer0.org2.example.com

    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 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 peer channel join -b mychannel.block
  • 更新anchor peers

    下面的命令将更新channel的定义从而定义anchor peers,本质上只是在channel的genesis block之上添加了一些配置信息。

    定义Org1的anchor peer: peer0.org1.example.com

    peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/Org1MSPanchors.tx --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

    定义Org2的anchor peer:peer0.org2.example.com,同样的,需要加上环境变量

    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 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 peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/Org2MSPanchors.tx --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
  • 安装并实例化(instantiate)链码(chaincode)

    这里使用的是已经存在的chaincode,应用通过chaincode与区块链进行交互,我们需要在每个peer节点上安装chaincode,源码会被存放在节点的文件系统中,然后在channel上实例化chaincode。

    注意: 文档中chaincode在cli容器文件系统内的地址是

    github.com/chaincode/chaincode_example02/go/

    ,而我的实际路径为github.com/hyperledger/fabric/examples/chainco

    de/go/chaincode_example02
    。(更新于4.12,release-1.1版本的路径与文档中一致)

    安装Golang语言编写的chaincode:

    peer chaincode install -n mycc -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02

    实例化chaincode,这会在channel上初始化chaincode,并为目标节点运行一个chaincode容器。注意-P参数设置了endorsement的策略,这里是OR ('Org0MSP.peer','Org1MSP.peer'),表示需要属于Org1**或者**Org2的1个peer进行1次背书(endorsement)。实例化命令如下:

    peer chaincode instantiate -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n mycc -v 1.0 -c '{"Args":["init","a", "100", "b","200"]}' -P "OR ('Org1MSP.peer','Org2MSP.peer')"
  • 查询(Query)

    首先查询a的值,以确保chaincode成功实例化并且状态数据库(state DB)被成功填充。

    peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'

    查询结果为 Query Result: 100

  • 调用(Invoke)

    从a账户转移10个数额到b账户,这个命令将会把交易发送至orderer节点并创建新的block,同时更新stateDB。

    peer chaincode invoke -o orderer.example.com:7050  --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem  -C $CHANNEL_NAME -n mycc -c '{"Args":["invoke","a","b","10"]}'

    再次调用Query命令可得到结果Query Result: 90

5.运行过程分析

以下是通过./byfn.sh -m up启动网络时,运行script.sh脚本所进行步骤:

  • script.sh脚本在CLI容器内执行,该脚本执行了createChannel命令,提供了channel的名字,并且使用channel.tx作为配置文件,来创建一个channel。
  • createChannel的输出是一个genesis block,存储在peer的文件系统中。block中存储了channel的配置信息(由channel.tx指定)。
  • joinChannel命令将4个peer加入channel中,用上面创建的genesis block作为输入,创建了一条以该创世区块为开始的chain
  • 更新两个org的anchor peers,将Org1MSPanchors.txOrg2MSPanchors.tx发送给ordering service以实现更新。
  • chaincode (chaincode_example02)被安装在peer0.org1peer0.org2中。使chaincode在peer0.org2中实例化,将chaincode添加到channel中,运行容器dev-peer0.org2.example.com-mycc-1.0
  • 查询(query)peer0.org1节点中a的值,结果为100, 由于chaincode在该节点已经完成install,所以该查询操作会运行一个chaincode容器。接着在该节点中(invoke)从a的账户向b转移10金额。
  • peer1.org2中下载chaincode。向该节点发送查询a的操作,同样又会运行第3个新的chaincode容器。得到查询的值为90。注意这里的每个fabric节点中,是没有数据库副本的(database replicas),即对数据库的写入是可以保证数据一致性。

最新文章

  1. Jesse Livermore的21句投机至理名言
  2. linux内核学习之七 可执行程序的装载和运行
  3. 创建并追加img元素(jquery!)
  4. good luck
  5. 【Tsinghua OJ】循环移位(Cycle)
  6. JSF的ui标签
  7. ORACLE 数据库概述以及Oracel数据库的安装、卸载、使用
  8. Tornado源码探寻(请求到来)
  9. mysql实现增量备份
  10. Spring框架快速入门之简介
  11. WebApi 自定义过滤器实现支持AJAX跨域的请求
  12. 连载:面向对象的葵花宝典:思考、技巧与实践(39) - 设计原则 vs 设计模式
  13. &quot;类型初始值设定项引发异常&quot;
  14. hello world 为什么我们看到学习中有这一句话!!!
  15. Linux下的进程与线程(一)—— 进程概览
  16. SqlMapConfig配置加注解
  17. 金融量化分析【day113】:PGEC策略
  18. Mysql 用命令行导出导入数据方法
  19. Elasticsearch学习之多种查询方式
  20. 用jquery写的校验用户名

热门文章

  1. Spring Cloud 系列之 Stream 消息驱动(二)
  2. MYSQL隔离级别 与 锁
  3. .NET平台上的编译器不完全列表(转别)
  4. 虚拟化VMware之虚拟机备份(1)
  5. 【STM32 .Net MF开发板学习-05】PC通过Modbus协议远程操控开发板
  6. POJ 1170 Shopping Offers非状态压缩做法
  7. Windows+Ubuntu双系统 ,Ubuntu安装
  8. pytho xlrd简介
  9. Android | 带你零代码实现安卓扫码功能
  10. Java——多线程超详细总结