ps:之前自己部署时记录的,上传作个笔记。
教程系统centos7
镜像下载脚本:
#!/bin/bash
DOCKER_NS=hyperledger
ARCH=x86_64
VERSION=1.0.5
FABRIC_IMAGES=(fabric-peer fabric-orderer fabric-ccenv fabric-javaenv fabric-kafuka fabric-zookeeper fabric-couchdb fabric-ca fabric-tools)
for image in ${FABRIC_IMAGES [@]}; do
echo “Pulling ${DOCKER_NS}/$image:${ARCH}-${VERSION}”
docker pull ${DOCKER_NS}/$image:${ARCH}-${VERSION}
done
下载辅助工具
(注意复制进去可能会显示成中文字符)
# cd ~/workspace #目录自己定
# VERSION=1.0.5
# ARCH=$(echo "$(uname -s|tr '[:upper:]' '[:lower:]' | sed 's/mingw64_nt.*/windows/')-$(uname -m | sed 's/x86_64/amd64/g')" | awk '{print tolower($0)}')
#curl https://nexus.hyperledger.org/content/repositories/releases/org/hyperledger/fabric/hyperledger-fabric/${ARCH}-${VERSION}/hyperledger-fabric-${ARCH}-${VERSION}.tar.gz | tar xz
1、安装openssl
yum install openssl openssl-devel
2、openssl version -a 查看证书目录
3、进入curl安装目录 执行 ./configure –with-ssl=上一步的证书目录,查看结果是否如下
4、重新编译安装curl
make make install
[root@localhost /]# cd ~/workspace
[root@localhost workspace]# mkdir -p first_network/crypto-config
[root@localhost workspace]# mkdir -p first_network/channel-artifacts
注意: YAML⽂件对缩进格式有严格要求。 YAML⽂件的常⽤语法:
- '#': 注释
- ':': 对象定义
- '-': 数组成员
- '&': 声明锚点对象
- '*': 引⽤锚点内容
- '<<': 合并内容到当前位置
参考: http://www.yaml.org/spec/1.2/spec.html
[root@localhost first_network]# vi crypto-config.yaml
OrdererOrgs:
- Name: Orderer
Domain: example.com
Specs:
- Hostname: orderer
PeerOrgs:
- Name: Org1
Domain: org1.example.com
Template:
Count: 1
Users:
Count: 1
- Name: Org2
Domain: org2.example.com
Template:
Count: 1
Users:
Count: 1
[root@localhost first_network]# ../bin/cryptogen generate --config=crypto-config.yaml
'configtx.yaml'⽂件⽤于定义区块链⽹络中的排序节点信息和Channel信息,包括排序节点的共识⽅式、域名和IP,以及Channel的内部组织节点构成等。
#
# configtx.yaml
#
---
Profiles:
TwoOrgsOrdererGenesis:
Orderer:
<<: *OrdererDefaults
Organizations:
- *OrdererOrg
Consortiums:
SampleConsortium:
Organizations:
- *Org1
- *Org2
TwoOrgsChannel:
Consortium: SampleConsortium
Application:
<<: *ApplicationDefaults
Organizations:
- *Org1
- *Org2
Organizations:
- &OrdererOrg
Name: OrdererOrg
ID: OrdererMSP
MSPDir: crypto-config/ordererOrganizations/example.com/msp
- &Org1
Name: Org1MSP
ID: Org1MSP
MSPDir: crypto-config/peerOrganizations/org1.example.com/msp
AnchorPeers:
- Host: peer0.org1.example.com
Port: 7051
- &Org2
Name: Org2MSP
ID: Org2MSP
MSPDir: crypto-config/peerOrganizations/org2.example.com/msp
AnchorPeers:
- Host: peer0.org2.example.com
Port: 7051
Orderer: &OrdererDefaults
OrdererType: solo
Addresses:
- orderer.example.com:7050
BatchTimeout: 2s
BatchSize:
MaxMessageCount: 10
AbsoluteMaxBytes: 99 MB
PreferredMaxBytes: 512 KB
Kafka:
Brokers:
- 127.0.0.1:9092
Organizations:
Application: &ApplicationDefaults
Organizations:
$ cd ~/workspace/first-network
$ export FABRIC_CFG_PATH=$PWD
$../bin/configtxgen -profile TwoOrgsOrdererGenesis -outputBlock
./channel-artifacts/genesis.block
$../bin/configtxgen -profile TwoOrgsChannel -outputCreateChannelTx
./channel-artifacts/channel01.tx -channelID channel01
$../bin/configtxgen -profile TwoOrgsChannel -
outputAnchorPeersUpdate ./channe-lartifacts/channel01_Org1MSPanchors.tx -channelID channel01 -asOrg Org1MSP
$ ../bin/configtxgen -profile TwoOrgsChannel -
outputAnchorPeersUpdate ./channel-artifacts/channel01_Org2MSPanchors.tx -channelID channel01 -asOrg Org2MSP
genesis.block --- 排序节点的起始区块⽂件,channel01.tx --- Channel定义⽂件
Org1MSPanchors.tx --- Org1的锚点定义⽂件,Org2MSPanchors.tx --- Org2的锚点定义⽂件
⾸先需要为Docker⽹络设置⼀个环境变量 COMPOSE_PROJECT_NAME ,保存在当前⽂件
夹下的⽂件'.env'中:
$ cd ~/workspace/first_network
$ echo "COMPOSE_PROJECT_NAME=net" > .env
该配置文件定义各组织节点的概要信息
#
# peer-base.yaml
#
version: '2'
services:
peer-base:
image: hyperledger/fabric-peer:x86_64-1.0.5
environment:
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=${COMPOSE_PROJECT_NAME}_bc-dev
- CORE_LOGGING_LEVEL=DEBUG
- CORE_PEER_TLS_ENABLED=false
- CORE_PEER_GOSSIP_USELEADERELECTION=true
- CORE_PEER_GOSSIP_ORGLEADER=false
- CORE_PEER_PROFILE_ENABLED=true
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: peer node start
参考链接:
https://raw.githubusercontent.com/hyperledger/fabric-samples/release/first-network/base/peer-base.yaml
定义各组织节点的详细信息。(可能不全,注意文件路径是否一致)
#
# docker-compose-base.yaml
#
version: '2'
services:
orderer.example.com:
container_name: orderer.example.com
image: hyperledger/fabric-orderer:x86_64-1.0.5
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
- ORDERER_GENERAL_TLS_ENABLED=false
working_dir: /opt/gopath/src/github.com/hyperledger/fabric
command: orderer
volumes:
- ../channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.bl
ock
- ../crypto-config/ordererOrganizations/example.com/orderers/orderer.example.co
m/msp:/var/hyperledger/orderer/msp
- ../crypto-config/ordererOrganizations/example.com/orderers/orderer.example.co
m/tls/:/var/hyperledger/orderer/tls
ports:
- 7050:7050
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_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
- 7053:7053
peer0.org2.example.com:
container_name: peer0.org2.example.com
extends:
file: peer-base.yaml
service: peer-base
environment:
- CORE_PEER_ID=peer0.org2.example.com
- CORE_PEER_ADDRESS=peer0.org2.example.com:7051
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org2.example.com:7051
- CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org2.example.com:7051
- CORE_PEER_LOCALMSPID=Org2MSP
volumes:
- /var/run/:/host/var/run/
- ../crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/msp:/etc/hyperledger/fabric/msp
- ../crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls:/etc/hyperledger/fabric/tls
ports:
- 9051:7051
- 9053:7053
参考链接:
https://raw.githubusercontent.com/hyperledger/fabric-samples/release/first-network/base/docker-compose-base.yaml
将前⾯定义好的各个节点进⾏组⽹,⽤于⽹络启动。在first_network目录下(可能不全,注意文件路径是否一致)
#
# docker-compose.yaml
#
version: '2'
networks:
bc-dev:
services:
orderer.example.com:
extends:
file: base/docker-compose-base.yaml
service: orderer.example.com
container_name: orderer.example.com
networks:
- bc-dev
peer0.org1.example.com:
container_name: peer0.org1.example.com
extends:
file: base/docker-compose-base.yaml
service: peer0.org1.example.com
networks:
- bc-dev
peer0.org2.example.com:
container_name: peer0.org2.example.com
extends:
file: base/docker-compose-base.yaml
service: peer0.org2.example.com
networks:
- bc-dev
cli:
container_name: cli
image: hyperledger/fabric-tools:x86_64-1.0.5
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=false
- CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: /bin/bash
volumes:
- /var/run/:/host/var/run/
- ./../chaincodes/:/opt/gopath/src/chaincodes
- ./crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
- ./channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts
depends_on:
- orderer.example.com
- peer0.org1.example.com
- peer0.org2.example.com
networks:
- bc-dev
在first_network目录下启动:
$ docker-compose up -d或docker-compose -f xx.yaml
打开终端窗⼝,执⾏下述命令(登录到 cli 容器的系统) 注意docker容器重启后,要重新执行本步骤:
$ cd ~/workspace/first_network
$ docker exec -it cli bash
在 cli 的终端中执⾏如下命令(设置环境变量,表明当前操作代表的节点
是 peer0.org1.exmple.com ):
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/[email protected]/msp
CORE_PEER_ADDRESS=peer0.org1.example.com:7051
注意: 通过定义修改这些环境变量,我们可以在同⼀个容器中模拟不同的节点
身份。
在 cli 的终端中执⾏如下命令(创建Channel channel01 ):
$ peer channel create -o orderer.example.com:7050 -c channel01 -f ./channel-artifacts/channel01.tx
该操作会产⽣⼀个⽂件( channel01.block ),将作为加⼊这个Channel的唯⼀凭
据。
在 cli 的终端中执⾏如下命令(将节点 peer0.org1.example.com 加⼊到该Channel
channel01 中):
$ peer channel join -b channel01.block
在 cli 的终端中执⾏如下命令(将节点 peer0.org1.example.com 设置为Channel
channel01 中的锚点,代表 Org1 参与共识):
peer channel update -o orderer.example.com:7050 -c channel01 -f
./channel-artifacts/channel01_Org1MSPanchors.tx
在 cli 的终端中执⾏如下命令(验证节点 peer0.org1.example.com ⼀共加⼊了哪些
Channel):
$ peer channel list
以peer0.org2.exmple.com 的身份
在 cli 的终端中执⾏如下命令(设置环境变量,表明当前操作代表的节点
是 peer0.org2.exmple.com ):
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/[email protected]/msp
CORE_PEER_ADDRESS=peer0.org2.example.com:7051
在 cli 的终端中执⾏如下命令(将节点 peer0.org2.example.com 加⼊到该Channel
channel01 中):
$ peer channel join -b channel01.block
在 cli 的终端中执⾏如下命令(将节点 peer0.org2.example.com 设置为Channel
channel01 中的锚点,代表 Org2 参与共识):
peer channel update -o orderer.example.com:7050 -c channel01 -f./channel-artifacts/channel01_Org2MSPanchors.tx
在 cli 的终端中执⾏如下命令(验证节点 peer0.org2.example.com ⼀共加⼊了哪些
Channel):
$ peer channel list
2018-01-25 03:29:08.934 UTC [channelCmd] list -> INFO 006 Channels
peers has joined to:
2018-01-25 03:29:08.937 UTC [channelCmd] list -> INFO 007 channel01
2018-01-25 03:29:08.939 UTC [main] main -> INFO 008 Exiting.....
先从源码中随便拿一个带单元测试的CC放在workspace内,我选的 /hyperledger/fabric/examples/chaincode/go/chaincode_example02
放在 ~/workspace/ chaincodes/chaincode_example
以 peer0.org1.exmple.com 的身份安装指定Chaincode
$ peer chaincode install -n example -v 1.0 -p chaincodes/chaincode_example
(节点身份设置⽅法,就是上一步设置channel中更改变量的步骤,若两个节点部署在不同服务器就不用这么麻烦)
以 peer0.org2.exmple.com 的身份,安装指定Chaincode
$ peer chaincode install -n example -v 1.0 -p chaincodes/chaincode_example
'-p'参数⽤来指定chaincode的存放路径, 这是当前登录的系统中 ('cli')$GOPATH/src下⾯的相对路径。
在Channel channel01 中将cc实例化, 同时指定共识策略):
$ peer chaincode instantiate -o orderer.example.com:7050 -C channel01 -n example -v 1.0 -c '{"Args": ["init","a","100","b","100"]}' -P "OR('Org1MSP.member','Org2MSP.member')"
注:Chaincode调⽤的参数是个字符串数组, 第⼀个参数代表调⽤的功能名称(对于
部署操作时, 该值只能为'init'),从第⼆个参数开始的字符串数组将作为实际被
调⽤的功能参数。'-P'参数后⾯是共识策略的表达⽅式, 语法: OR(x, y) 或 AND(x, y), 甚⾄可以是AND(x, OR(y,z))。
此操作结束后docker将生成专门用于运行CC的镜像和容器
参考:
http://hyperledger-fabric.readthedocs.io/en/latest/endorsementpolicies.html#endorsement-policy-syntax-in-the-cli
常用操作
#删除所有容器
docker rm -f `docker ps -qa`
#删除所有⾃动⽣成的镜像
docker rmi -f `docker images | grep "dev\|none\|test-vp\|peer[0-9]-
" | awk '{print $3}'`
#查看现有docker⽹络
docker network list
#删除所有docker⽹络
docker network prune