1. 基础环境
1.1. 环境准备
编号 | 主机名 | IP地址 | 域名 | 备注 | 环境 |
---|---|---|---|---|---|
1 | orderer | 10.20.40.106 | orderer.example.com | order节点 | go docker |
2 | peer0 | 10.20.40.117 | peer0.ogr1.example.com | peer节点 | go docker |
3 | peer1 | 10.20.40.110 | peer1.ogr1.example.com | peer节点 | go docker |
4 | peer2 | 10.20.40.106 | peer0.ogr2.example.com | peer节点 | go docker |
5 | peer3 | 10.20.40.121 | peer1.ogr2.example.com | peer节点 | go docker |
6 | ca01 | 10.20.40.119 | ca.org1.example.com | ca节点 | go docker |
7 | ca02 | ca.org2.example.com | ca节点 | go docker | |
8 | kafka01 | kafka01.example.com | kafka节点 | java |
/etc/hosts 内容
10.20.40.115 order.example.com
10.20.40.117 peer0.ogr1.example.com
10.20.40.110 peer1.ogr1.example.com
10.20.40.106 peer0.ogr2.example.com
10.20.40.121 peer1.ogr2.example.com
1.2. go docker环境部署
1.2.1. go安装
-
卸载低版本golang
yum remove golang yum autoremove
-
下载并解压go二进制包(1.8版本以上)
解压:
tar -xvf go1.8.1.linux-amd64.tar.gz -C /usr/local/
-
设置环境变量
在 ~/.profile 文件末尾添加:
export GOROOT=/usr/local/go export GOBIN=$GOROOT/bin export PATH=$PATH:$GOBIN export GOPATH=/root/go
环境变量生效:
source ~/.profile
把go的目录GOPATH设置为当前用户的文件夹下,所以记得创建go文件夹
cd ~ mkdir go
-
测试
执行
go version
1.2.2. docker安装 (1.12版本以上)
可以使用阿里提供的镜像仓库,执行以下命令来安装Docker
curl -sSL http://acs-public-mirror.oss-cn-hangzhou.aliyuncs.com/docker-engine/internet | sh -
1.2.3. docker-compose安装
-
下载安装docker-compose执行程序
sudo curl -L "https://github.com/docker/compose/releases/download/1.12.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
添加执行权限
sudo chmod +x /usr/local/bin/docker-compose
-
测试
执行docker-compose version,得到结果
docker-compose version 1.10.1, build b252738 docker-py version: 2.0.2 CPython version: 2.7.9 OpenSSL version: OpenSSL 1.0.1t 3 May 2016
1.3. Fabric环境安装
1.3.1. 源码下载
可以用go get命令下载源码
go get github.com/hyperledger/fabric
如果下载失败也可以使用git命令下载源码
mkdir -p ~/go/src/github.com/hyperledger
cd ~/go/src/github.com/hyperledger
git clone https://github.com/hyperledger/fabric.git
由于Fabric一直在更新,所有我们并不需要最新最新的源码,需要切换到v1.0.0版本的源码即可:
cd ~/go/src/github.com/hyperledger/fabric
git checkout v1.0.0
1.3.2. docker fabric镜像下载
官方文件提供了批量下载的脚本。我们直接运行:
cd ~/go/src/github.com/hyperledger/fabric/examples/e2e_cli/
source download-dockerimages.sh -c x86_64-1.0.0 -f x86_64-1.0.0
所有会用到的Fabric docker镜像都会下载下来了
2. Fabric配置
2.1. 编辑docker-compose 模板
2.1.1. 编辑order模板
cp docker-compose-cli.yaml docker-compose-orderer.yaml
修改docker-compose-orderer.yaml 文件内容,最终为: version: ‘2’
services:
orderer.example.com:
extends:
file: base/docker-compose-base.yaml
service: orderer.example.com
container_name: orderer.example.com
修改 base/docker-compose-base.yaml 文件,最终为:
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
version: '2'
services:
orderer.example.com:
container_name: orderer.example.com
image: hyperledger/fabric-orderer
environment:
- ORDERER_GENERAL_LOGLEVEL=debug
- ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
- ORDERER_GENERAL_GENESISMETHOD=file
- ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.genesis.block
- ORDERER_GENERAL_LOCALMSPID=OrdererMSP
- ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/msp
# enabled TLS
- ORDERER_GENERAL_TLS_ENABLED=true
- ORDERER_GENERAL_TLS_PRIVATEKEY=/var/hyperledger/orderer/tls/server.key
- ORDERER_GENERAL_TLS_CERTIFICATE=/var/hyperledger/orderer/tls/server.crt
- ORDERER_GENERAL_TLS_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt]
working_dir: /opt/gopath/src/github.com/hyperledger/fabric
command: orderer
volumes:
- ../channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block
- ../crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/msp:/var/hyperledger/orderer/msp
- ../crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/:/var/hyperledger/orderer/tls
ports:
- 7050:7050 #### 2.1.2. 编辑peer模板
cp docker-compose-cli.yaml docker-compose-peer0org1.yaml
修改 docker-compose-peer0org1.yaml 文件,最终为:
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
version: '2'
services:
peer0.org1.example.com:
container_name: peer0.org1.example.com
extends:
file: base/docker-compose-base.yaml
service: peer0.org1.example.com
extra_hosts:
- "orderer.example.com:10.20.40.106"
cli:
container_name: cli
image: hyperledger/fabric-tools
tty: true
environment:
- GOPATH=/opt/gopath
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_LOGGING_LEVEL=DEBUG
- CORE_PEER_ID=cli
- CORE_PEER_ADDRESS=peer0.org1.example.com:7051
- CORE_PEER_LOCALMSPID=Org1MSP
- CORE_PEER_TLS_ENABLED=true
- CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt
- CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key
- 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
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
# command: /bin/bash -c './scripts/script.sh ${CHANNEL_NAME}; sleep $TIMEOUT'
volumes:
- /var/run/:/host/var/run/
- ../chaincode/go/:/opt/gopath/src/github.com/hyperledger/fabric/examples/chaincode/go
- ./crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
- ./scripts:/opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/
- ./channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts
depends_on:
- peer0.org1.example.com
extra_hosts:
- "orderer.example.com:10.20.40.106"
- "peer0.org1.example.com:10.20.40.117"
- "peer1.org1.example.com:10.20.40.110"
- "peer0.org2.example.com:10.20.40.121"
修改 base/docker-compose-base.yaml 文件,最终为:
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
version: '2'
services:
peer0.org1.example.com:
container_name: peer0.org1.example.com
extends:
file: peer-base.yaml
service: peer-base
environment:
- CORE_PEER_ID=peer0.org1.example.com
- CORE_PEER_ADDRESS=peer0.org1.example.com:7051
- CORE_PEER_CHAINCODELISTENADDRESS=peer0.org1.example.com:7052
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051
- CORE_PEER_LOCALMSPID=Org1MSP
volumes:
- /var/run/:/host/var/run/
- ../crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp:/etc/hyperledger/fabric/msp
- ../crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls:/etc/hyperledger/fabric/tls
ports:
- 7051:7051
- 7052:7052
- 7053:7053
其余peer节点可按照类似配置
2.1.3. 编辑ca模板
编译 docker-compose.yml 文件,最终为:
#
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
fabric-ca-server:
image: hyperledger/fabric-ca
container_name: ca.org1.example.com
ports:
- "7054:7054"
environment:
- FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server
- FABRIC_CA_SERVER_CA_NAME=ca0
- FABRIC_CA_SERVER_TLS_ENABLED=false
volumes:
- "./fabric-ca-server:/etc/hyperledger/fabric-ca-server"
- "./crypto-config/peerOrganizations/org1.example.com/ca/:/etc/hyperledger/fabric-ca-server-config"
command: sh -c 'fabric-ca-server start --ca.certfile /etc/hyperledger/fabric-ca-server-config/ca.org1.example.com-cert.pem --ca.keyfile /etc/hyperledger/fabric-ca-server-config/8a3d322657795bdb78310d50c97c66642f2f91531f1536800c928a6b9cf873b8_sk -b admin:adminpw -d'
其中 启动命令 中ca.certfile 为 crypto-config/peerOrganizations/org1.example.com/ca/ca.org1.example.com-cert.pem
2.2. 编译cryptogen configtxgen,生成公私钥和证书
cryptogen 工具可以生成fabric 系统中order、peer、admin等角色的证书
2.2.1 编译cryptogen
cd ~/go/src/github.com/hyperledger/fabric
make cryptogen 系统返回结果:
build/bin/cryptogen
CGO_CFLAGS=" " GOBIN=/root/go/src/github.com/hyperledger/fabric/build/bin go install -tags "" -ldflags "-X github.com/hyperledger/fabric/common/tools/cryptogen/metadata.Version=1.0.0" github.com/hyperledger/fabric/common/tools/cryptogen
Binary available as build/bin/cryptogen
显示上面证明cryptogen程序已经可以使用了
2.2.2 配置crypto-config.yaml
文件位置: ~/go/src/github.com/hyperledger/fabric/examples/e2e_cli/crypto-config.yaml
文件中已经提供了一个Orderer Org 和两个Peer Org的配置
OrdererOrgs:
- Name: Orderer
Domain: example.com
Specs:
- Hostname: orderer
PeerOrgs:
- Name: Org1
Domain: org1.example.com
Template:
Count: 2
Users:
Count: 1
- Name: Org2
Domain: org2.example.com
Template:
Count: 2
Users:
Count: 1
Name和Domain 就是关于这个组织的名字和域名,主要是用于生成证书的时候,证书内会包含该信息。
Template Count=2 是说我吗要生成2套公钥和证书,一套是peer0.org1的,一套是peer1.org1的
Users Count=1 是说每个Template下面会有几个普通User,这里Admin并不包含在内
可以根据实际配置调整Org User数量
2.2.3 生成公钥和证书
配置好crypto-config.yaml文件后,就可以勇士cryptogen去读取该文件,生成公钥和证书了:
cd examples/e2e_cli/
../../build/bin/cryptogen generate --config=./crypto-config.yaml
生成的文件都保存到crypto-config文件夹,我们可以进入该文件夹查看生成了哪些文件:
tree crypto-config
2.2.4 编译configtxgen
通过make命令生成configtxgen程序:
cd ~/go/src/github.com/hyperledger/fabric
make configtxgen
运行结果为:
build/bin/configtxgen
CGO_CFLAGS=" " GOBIN=/home/studyzy/go/src/github.com/hyperledger/fabric/build/bin go install -tags "nopkcs11" -ldflags "-X github.com/hyperledger/fabric/common/configtx/tool/configtxgen/metadata.Version=1.0.0" github.com/hyperledger/fabric/common/configtx/tool/configtxgen
Binary available as build/bin/configtxgen
2.2.5 配置configtx.yaml
官方提供的examples/e2e_cli/configtx.yaml这个文件里面配置了由2个Org参与的Orderer共识配置TwoOrgsOrdererGenesis,以及由2个Org参与的Channel配置:TwoOrgsChannel。Orderer可以设置共识的算法是Solo还是Kafka,以及共识时区块大小,超时时间等,我们使用默认值即可,不用更改。而Peer节点的配置包含了MSP的配置,锚节点的配置。如果我们有更多的Org,或者有更多的Channel,那么就可以根据模板进行对应的修改。
2.2.6 生成创世区块
配置修改好后,使用configtxgen生成创世区块。并把这个区块保存到本地channel-artifacts文件夹中:
cd examples/e2e_cli/
../../build/bin/configtxgen -profile TwoOrgsOrdererGenesis -outputBlock ./channel-artifacts/genesis.block
2.2.7 生成channel配置区块
../../build/bin/configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID mychannel
另外关于锚节点的更新,我们也需要使用这个程序来生成文件:
../../build/bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID mychannel -asOrg Org1MSP
../../build/bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID mychannel -asOrg Org2MSP
最终,我们在channel-artifacts文件夹中,应该是能够看到4个文件。
channel-artifacts/
├── channel.tx
├── genesis.block
├── Org1MSPanchors.tx
└── Org2MSPanchors.tx
3. 启动Fabric
3.1. 启动Order节点
docker-compose -f docker-compose-orderer.yaml up -d
3.2. 启动Peer节点
docker-compose -f docer-compose-peer.yaml up -d
3.3. 创建Channel
现在我们要进入cli容器内部,在里面创建Channel。先用以下命令进入CLI内部Bash:
docker exec -it cli bash
创建Channel的命令是peer channel create,我们前面创建2.4创建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-08-29 20:36:47.486 UTC [channelCmd] readBlock -> DEBU 020 Received block:0
系统会在cli内部的当前目录创建一个mychannel.block文件,这个文件非常重要,接下来其他节点要加入这个Channel就必须使用这个文件。
3.4. 各个节点加入Channel
前面说过,我们CLI默认连接的是peer0.org1,那么我们要将这个Peer加入mychannel就很简单,只需要运行如下命令:
peer channel join -b mychannel.block
系统返回消息:
2017-08-29 20:40:27.053 UTC [channelCmd] executeJoin -> INFO 006 Peer joined the channel!
那么其他几个Peer又该怎么加入Channel呢?这里就需要修改CLI的环境变量,使其指向另外的Peer。比如我们要把peer1.org1加入mychannel,那么命令是:
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=peer1.org1.example.com:7051
peer channel join -b mychannel.block
系统会返回成功加入Channel的消息。
同样的方法,将peer0.org2加入mychannel:
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
最后把peer1.org2加入mychannel:
CORE_PEER_LOCALMSPID="Org2MSP"
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer1.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=peer1.org2.example.com:7051
peer channel join -b mychannel.block
3.5. 更新锚节点
关于AnchorPeer,我理解的不够深刻,经过我的测试,即使没有设置锚节点的情况下,整个Fabric网络仍然是能正常运行的。
对于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
peer channel update -o orderer.example.com:7050 -c mychannel -f ./channel-artifacts/Org1MSPanchors.tx --tls true --cafile $ORDERER_CA
另外对于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 ### 3.6. chaincode 的安装与运行
以上,整个Fabric网络和Channel都准备完毕,接下来我们来安装和运行ChainCode。这里仍然以最出名的Example02为例。这个例子实现了a,b两个账户,相互之间可以转账。
3.6.1. 安装chaincode
链上代码的安装需要在各个相关的Peer上进行,对于我们现在这种Fabric网络,如果4个Peer都想对Example02进行操作,那么就需要安装4次。
仍然是保持在CLI的命令行下,我们先切换到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
使用peer chaincode install命令可以安装指定的ChainCode并对其命名:
peer chaincode install -n mycc -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02
安装的过程其实就是对CLI中指定的代码进行编译打包,并把打包好的文件发送到Peer,等待接下来的实例化。
其他节点由于暂时还没使用到,我们可以先不安装
3.6.2. 实例化chaincode
实例化链上代码主要是在Peer所在的机器上对前面安装好的链上代码进行包装,生成对应Channel的Docker镜像和Docker容器。并且在实例化时我们可以指定背书策略。我们运行以下命令完成实例化:
peer chaincode instantiate -o orderer.example.com:7050 --tls true --cafile $ORDERER_CA -C mychannel -n mycc -v 1.0 -c '{"Args":["init","a","100","b","200"]}' -P "OR ('Org1MSP.member','Org2MSP.member')"
如果我们新开一个Ubuntu终端,去查看peer0.org1上的日志,那么就可以知道整个实例化的过程到底干了什么:
docker logs -f peer0.org1.example.com
主要几行重要的日志:
2017-08-29 21:14:12.290 UTC [chaincode-platform] generateDockerfile -> DEBU 3fd
FROM hyperledger/fabric-baseos:x86_64-0.3.1
ADD binpackage.tar /usr/local/bin
LABEL org.hyperledger.fabric.chaincode.id.name="mycc" \
org.hyperledger.fabric.chaincode.id.version="1.0" \
org.hyperledger.fabric.chaincode.type="GOLANG" \
org.hyperledger.fabric.version="1.0.0" \
org.hyperledger.fabric.base.version="0.3.1"
ENV CORE_CHAINCODE_BUILDLEVEL=1.0.0
ENV CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/peer.crt
COPY peer.crt /etc/hyperledger/fabric/peer.crt
2017-08-29 21:14:12.297 UTC [util] DockerBuild -> DEBU 3fe Attempting build with image hyperledger/fabric-ccenv:x86_64-1.0.0
2017-08-29 21:14:48.907 UTC [dockercontroller] deployImage -> DEBU 3ff Created image: dev-peer0.org1.example.com-mycc-1.0
2017-08-29 21:14:48.908 UTC [dockercontroller] Start -> DEBU 400 start-recreated image successfully
2017-08-29 21:14:48.908 UTC [dockercontroller] createContainer -> DEBU 401 Create container: dev-peer0.org1.example.com-mycc-1.0
接下来的日志就是各种初始化,验证,写账本之类的。总之完毕后,我们回到Ubuntu终端,使用docker ps可以看到有新的容器正在运行:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
07791d4a99b7 dev-peer0.org1.example.com-mycc-1.0 "chaincode -peer.a..." About a minute ago Up About a minute dev-peer0.org1.example.com-mycc-1.0
6f98f57714b5 hyperledger/fabric-tools "/bin/bash" About an hour ago Up About an hour cli
6e7b3fd0e803 hyperledger/fabric-peer "peer node start" About an hour ago Up About an hour 0.0.0.0:10051->7051/tcp, 0.0.0.0:10052->7052/tcp, 0.0.0.0:10053->7053/tcp peer1.org2.example.com
9e67abfb982f hyperledger/fabric-orderer "orderer" About an hour ago Up About an hour 0.0.0.0:7050->7050/tcp orderer.example.com
908d7fe2a4c7 hyperledger/fabric-peer "peer node start" About an hour ago Up About an hour 0.0.0.0:7051-7053->7051-7053/tcp peer0.org1.example.com
6bb187ac10ec hyperledger/fabric-peer "peer node start" About an hour ago Up About an hour 0.0.0.0:9051->7051/tcp, 0.0.0.0:9052->7052/tcp, 0.0.0.0:9053->7053/tcp peer0.org2.example.com
150baa520ed0 hyperledger/fabric-peer "peer node start" About an hour ago Up About an hour 0.0.0.0:8051->7051/tcp, 0.0.0.0:8052->7052/tcp, 0.0.0.0:8053->7053/tcp peer1.org1.example.com
3.6.3. 发起交易
现在链上代码的实例也有了,并且在实例化的时候指定了a账户100,b账户200,我们可以试着调用ChainCode的查询代码,验证一下,在cli容器内执行:
peer chaincode query -C mychannel -n mycc -c '{"Args":["query","a"]}'
返回结果:Query Result: 100
接下来我们可以试着把a账户的10元转给b。对应的代码:
peer chaincode invoke -o orderer.example.com:7050 --tls true --cafile $ORDERER_CA -C mychannel -n mycc -c '{"Args":["invoke","a","b","10"]}'
3.6.4. 查询
前面的操作都是在org1下面做的,那么处于同一个区块链(同一个Channel下)的org2,是否会看org1的更改呢?我们试着给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/chaincode_example02
由于mycc已经在前面org1的时候实例化了,也就是说对应的区块已经生成了,所以在org2不能再次初始化。我们直接运行查询命令:
peer chaincode query -C mychannel -n mycc -c ‘{“Args”:[“query”,”a”]}’
4. 加入CouchDB
下面我们来说一说这个CouchDB。
CouchDB是一个完全局域RESTful API的键值数据库,也就是说我们不需要任何客户端,只需要通过HTTP请求就可以操作数据库了。LevelDB是Peer的本地数据库,那么肯定是和Peer一对一的关系,那么CouchDB是个网络数据库,应该和Peer是什么样一个关系呢?在生产环境中,我们会为每个组织部署节点,而且为了高可用,可能会在一个组织中部署多个Peer。同样我们在一个组织中也部署多个CouchDB,每个Peer对应一个CouchDB。
HyperLedger在Docker Hub上也发布了CouchDB的镜像,为了能够深入研究CouchDB和Fabric的集成,我们就采用官方发布的CouchDB来做。
docker pull klaemo/couchdb
可以获得官方的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
启动后我们打开浏览器,访问Linux的IP的5984端口的URL,比如我的Linux是192.168.100.129,那么URL是: http://192.168.100.129:5984/_utils 这个时候我们就可以看到CouchDB的Web管理界面了。输入用户名admin密码password即可进入
4.1. 集成到peer节点
version: '2'
services:
couchdb:
container_name: fabric-couchdb
image: klaemo/couchdb
environment:
- COUCHDB_USER=admin
- COUCHDB_PASSWORD=password
volumes:
- /data/couchdb:/opt/couchdb/data
ports:
- 5984:5984
peer0.org1.tansuotv.com:
container_name: peer0.org1.tansuotv.com
environment:
- CORE_LEDGER_STATE_STATEDATABASE=CouchDB
- CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=10.9.13.240:5984
- CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=admin
- CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=password
extends:
file: base/docker-compose-base.yaml
service: peer0.org1.tansuotv.com
extra_hosts:
- "orderer.tansuotv.com:10.9.40.245"