1 环境准备
环境准备请看这篇文章《准备hyperledger fabric1.4网络运行的环境》
2 网络架构图
序号 | 组织 | IP | 域名 | 端口映射 | 节点 |
---|---|---|---|---|---|
docker 容器1 | 组织1 - org1 | 172.18.0.6 | orderer.example.com | 0.0.0.0:9051->7051/tcp, 0.0.0.0:9053->7053/tcp | orderer节点 |
docker 容器2 | 组织1 - org1 | 172.18.0.7 | peer0.org1.example.com | 0.0.0.0:7051->7051/tcp, 0.0.0.0:7053->7053/tcp | peer0节点 |
docker 容器3 | 组织1 - org1 | 172.18.0.8 | peer1.org1.example.com | 0.0.0.0:8051->7051/tcp, 0.0.0.0:8053->7053/tcp | peer1节点 |
docker 容器4 | 组织2 - org2 | 172.18.0.9 | peer0.org2.example.com | 0.0.0.0:7050->7050/tcp | peer0节点 |
docker 容器5 | 组织2 - org2 | 172.18.0.10 | peer1.org2.example.com | 0.0.0.0:10051->7051/tcp, 0.0.0.0:10053->7053/tcp | peer1节点 |
docker 容器6 | 无组织 | 172.18.0.6 | 无 | 无 | cli客户端 |
3 生成Fabric需要的证书文件
第1步 创建文件夹
$ cd $GOPATH/src/github.com
$ mkdir -p fabric-study/fabricnet02
第2步 生成配置文件
$ cd fabric-study/fabricnet02
$ cryptogen showtemplate > crypto-config.yaml
第3步 修改配置文件crypto-config.yaml
去掉注释后内容如下
OrdererOrgs:
- Name: Orderer
Domain: example.com
Specs:
- Hostname: orderer
PeerOrgs:
- Name: Org1
Domain: org1.example.com
EnableNodeOUs: true
Template:
Count: 2
Users:
Count: 3
- Name: Org2
Domain: org2.example.com
EnableNodeOUs: true
Template:
Count: 2
Users:
Count: 2
第4步 根据crypto-config.yaml生成证书文件
$ cryptogen generate --config=crypto-config.yaml --output ./crypto-config
执行上述命令后会生成一个新的文件夹crypto-config,里面存放着相关的证书文件,可以通过tree命令查看证书文件夹的结构
$ tree -L 4 crypto-config
crypto-config
├── ordererOrganizations
│ └── example.com
│ ├── ca
│ │ ├── a23defe42d21c46bf8e1f28d2d34a4bf1d7802ecff39d9a1405729f547f0fb98_sk
│ │ └── ca.example.com-cert.pem
│ ├── msp
│ │ ├── admincerts
│ │ ├── cacerts
│ │ └── tlscacerts
│ ├── orderers
│ │ └── orderer.example.com
│ ├── tlsca
│ │ ├── f40a5b6e899f3f925f8a45b0f7b704ec96d8162ba60c499bbbc754cd6da500be_sk
│ │ └── tlsca.example.com-cert.pem
│ └── users
│ └── [email protected]
└── peerOrganizations
├── org1.example.com
│ ├── ca
│ │ ├── 6e4273039943b44e94d4e7aaba0e988c4e8f14ff819aba3e8c33c0e1a758d4ea_sk
│ │ └── ca.org1.example.com-cert.pem
│ ├── msp
│ │ ├── admincerts
│ │ ├── cacerts
│ │ ├── config.yaml
│ │ └── tlscacerts
│ ├── peers
│ │ └── peer0.org1.example.com
│ ├── tlsca
│ │ ├── 6465585e6729da7cf674ed06c861f02f8ab92294016880d649919cd9a5ebc351_sk
│ │ └── tlsca.org1.example.com-cert.pem
│ └── users
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ └── [email protected]
└── org2.example.com
├── ca
│ ├── 579ce11ac1505fe88c0a40740d46dc9bdc9fce20c0086eb7f19610ac3883304d_sk
│ └── ca.org2.example.com-cert.pem
├── msp
│ ├── admincerts
│ ├── cacerts
│ ├── config.yaml
│ └── tlscacerts
├── peers
│ └── peer0.org2.example.com
├── tlsca
│ ├── e59d2370ddedf3ca67ddf12b596e2e8365e743c6783db4f4aee8e307166bc6b3_sk
│ └── tlsca.org2.example.com-cert.pem
└── users
├── [email protected]
├── [email protected]
└── [email protected]
40 directories, 14 files
4 生成系统创始区块
注:系统创始块是提供给Orderer节点使用的
第1步 去fabric源码中拷贝模板配置文件到本文件夹
$ cp -r $GOPATH/src/github.com/hyperledger/fabric/sampleconfig/configtx.yaml .
第2步 修改拷过来的configtx.yaml
去掉注释后内容如下
Organizations:
- &OrdererOrg
Name: OrdererOrg
ID: OrdererMSP
MSPDir: crypto-config/ordererOrganizations/example.com/msp
Policies:
Readers:
Type: Signature
Rule: "OR('OrdererMSP.member')"
Writers:
Type: Signature
Rule: "OR('OrdererMSP.member')"
Admins:
Type: Signature
Rule: "OR('OrdererMSP.admin')"
- &Org1
Name: Org1MSP
ID: Org1MSP
MSPDir: crypto-config/peerOrganizations/org1.example.com/msp
Policies:
Readers:
Type: Signature
Rule: "OR('Org1MSP.admin', 'Org1MSP.peer', 'Org1MSP.client')"
Writers:
Type: Signature
Rule: "OR('Org1MSP.admin', 'Org1MSP.client')"
Admins:
Type: Signature
Rule: "OR('Org1MSP.admin')"
AnchorPeers:
- Host: peer0.org1.example.com
Port: 7051
- &Org2
Name: Org2MSP
ID: Org2MSP
MSPDir: crypto-config/peerOrganizations/org2.example.com/msp
Policies:
Readers:
Type: Signature
Rule: "OR('Org2MSP.admin', 'Org2MSP.peer', 'Org2MSP.client')"
Writers:
Type: Signature
Rule: "OR('Org2MSP.admin', 'Org2MSP.client')"
Admins:
Type: Signature
Rule: "OR('Org2MSP.admin')"
AnchorPeers:
- Host: peer0.org2.example.com
Port: 7051
Capabilities:
Channel: &ChannelCapabilities
V1_3: true
Orderer: &OrdererCapabilities
V1_1: true
Application: &ApplicationCapabilities
V1_3: true
V1_2: false
V1_1: false
Application: &ApplicationDefaults
Organizations:
Policies:
Readers:
Type: ImplicitMeta
Rule: "ANY Readers"
Writers:
Type: ImplicitMeta
Rule: "ANY Writers"
Admins:
Type: ImplicitMeta
Rule: "MAJORITY Admins"
Capabilities:
<<: *ApplicationCapabilities
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:
Policies:
Readers:
Type: ImplicitMeta
Rule: "ANY Readers"
Writers:
Type: ImplicitMeta
Rule: "ANY Writers"
Admins:
Type: ImplicitMeta
Rule: "MAJORITY Admins"
BlockValidation:
Type: ImplicitMeta
Rule: "ANY Writers"
Channel: &ChannelDefaults
Policies:
Readers:
Type: ImplicitMeta
Rule: "ANY Readers"
Writers:
Type: ImplicitMeta
Rule: "ANY Writers"
Admins:
Type: ImplicitMeta
Rule: "MAJORITY Admins"
Capabilities:
<<: *ChannelCapabilities
Profiles:
TwoOrgsOrdererGenesis:
<<: *ChannelDefaults
Orderer:
<<: *OrdererDefaults
Organizations:
- *OrdererOrg
Capabilities:
<<: *OrdererCapabilities
Consortiums:
SampleConsortium:
Organizations:
- *Org1
- *Org2
TwoOrgsChannel:
Consortium: SampleConsortium
Application:
<<: *ApplicationDefaults
Organizations:
- *Org1
- *Org2
Capabilities:
<<: *ApplicationCapabilities
第3步 生成系统创始块文件
先创建channel-artifact文件夹,用来放置生成的文件
$ mkdir channel-artifacts
$ configtxgen -profile TwoOrgsOrdererGenesis -channelID fabricnet02-sys-channel -outputBlock ./channel-artifacts/genesis.block
查看,多出了genesis.block文件
$ ls channel-artifacts/
genesis.block
第4步 生成channel配置文件,channelID为mychannel
configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID mychannel
查看,多出了channel.tx文件
$ ls channel-artifacts/
channel.tx genesis.block
第5步 生成组织1的锚点文件
$ configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID mychannel -asOrg Org1MSP
第6步 生成组织2的锚点文件
$ configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID mychannel -asOrg Org2MSP
5 准备好docker-compose-cli.yaml
$ touch docker-compose-cli.yaml
$ gedit docker-compose-cli.yaml
编辑输入如下内容,然后保存
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
version: '2'
volumes:
orderer.example.com:
peer0.org1.example.com:
peer1.org1.example.com:
peer0.org2.example.com:
peer1.org2.example.com:
networks:
fabricnet02:
services:
orderer.example.com:
container_name: orderer.example.com
image: hyperledger/fabric-orderer:$IMAGE_TAG
environment:
- FABRIC_LOGGING_SPEC=INFO
- 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]
- ORDERER_KAFKA_TOPIC_REPLICATIONFACTOR=1
- ORDERER_KAFKA_VERBOSE=true
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
- orderer.example.com:/var/hyperledger/production/orderer
ports:
- 7050:7050
networks:
- fabricnet02
peer0.org1.example.com:
container_name: peer0.org1.example.com
image: hyperledger/fabric-peer:$IMAGE_TAG
environment:
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
# the following setting starts chaincode containers on the same
# bridge network as the peers
# https://docs.docker.com/compose/networking/
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=fabricnet02_fabricnet02
- FABRIC_LOGGING_SPEC=INFO
#- FABRIC_LOGGING_SPEC=DEBUG
- CORE_PEER_TLS_ENABLED=true
- CORE_PEER_GOSSIP_USELEADERELECTION=true
- CORE_PEER_GOSSIP_ORGLEADER=false
- CORE_PEER_PROFILE_ENABLED=true
- CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt
- CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key
- CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt
- CORE_PEER_ID=peer0.org1.example.com
- CORE_PEER_ADDRESS=peer0.org1.example.com:7051
- CORE_PEER_GOSSIP_BOOTSTRAP=peer1.org1.example.com:7051
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051
- CORE_PEER_LOCALMSPID=Org1MSP
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: peer node start
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
- peer0.org1.example.com:/var/hyperledger/production
ports:
- 7051:7051
- 7053:7053
networks:
- fabricnet02
peer1.org1.example.com:
container_name: peer1.org1.example.com
image: hyperledger/fabric-peer:$IMAGE_TAG
environment:
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
# the following setting starts chaincode containers on the same
# bridge network as the peers
# https://docs.docker.com/compose/networking/
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=fabricnet02_fabricnet02
- FABRIC_LOGGING_SPEC=INFO
#- FABRIC_LOGGING_SPEC=DEBUG
- CORE_PEER_TLS_ENABLED=true
- CORE_PEER_GOSSIP_USELEADERELECTION=true
- CORE_PEER_GOSSIP_ORGLEADER=false
- CORE_PEER_PROFILE_ENABLED=true
- CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt
- CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key
- CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt
- CORE_PEER_ID=peer1.org1.example.com
- CORE_PEER_ADDRESS=peer1.org1.example.com:7051
- CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org1.example.com:7051
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.org1.example.com:7051
- CORE_PEER_LOCALMSPID=Org1MSP
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: peer node start
volumes:
- /var/run/:/host/var/run/
- ./crypto-config/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/msp:/etc/hyperledger/fabric/msp
- ./crypto-config/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls:/etc/hyperledger/fabric/tls
- peer1.org1.example.com:/var/hyperledger/production
ports:
- 8051:7051
- 8053:7053
networks:
- fabricnet02
peer0.org2.example.com:
container_name: peer0.org2.example.com
image: hyperledger/fabric-peer:$IMAGE_TAG
environment:
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
# the following setting starts chaincode containers on the same
# bridge network as the peers
# https://docs.docker.com/compose/networking/
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=fabricnet02_fabricnet02
- FABRIC_LOGGING_SPEC=INFO
#- FABRIC_LOGGING_SPEC=DEBUG
- CORE_PEER_TLS_ENABLED=true
- CORE_PEER_GOSSIP_USELEADERELECTION=true
- CORE_PEER_GOSSIP_ORGLEADER=false
- CORE_PEER_PROFILE_ENABLED=true
- CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt
- CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key
- CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt
- CORE_PEER_ID=peer0.org2.example.com
- CORE_PEER_ADDRESS=peer0.org2.example.com:7051
- CORE_PEER_GOSSIP_BOOTSTRAP=peer1.org2.example.com:7051
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org2.example.com:7051
- CORE_PEER_LOCALMSPID=Org2MSP
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: peer node start
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
- peer0.org2.example.com:/var/hyperledger/production
ports:
- 9051:7051
- 9053:7053
networks:
- fabricnet02
peer1.org2.example.com:
container_name: peer1.org2.example.com
image: hyperledger/fabric-peer:$IMAGE_TAG
environment:
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
# the following setting starts chaincode containers on the same
# bridge network as the peers
# https://docs.docker.com/compose/networking/
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=fabricnet02_fabricnet02
- FABRIC_LOGGING_SPEC=INFO
#- FABRIC_LOGGING_SPEC=DEBUG
- CORE_PEER_TLS_ENABLED=true
- CORE_PEER_GOSSIP_USELEADERELECTION=true
- CORE_PEER_GOSSIP_ORGLEADER=false
- CORE_PEER_PROFILE_ENABLED=true
- CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt
- CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key
- CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt
- CORE_PEER_ID=peer1.org2.example.com
- CORE_PEER_ADDRESS=peer1.org2.example.com:7051
- CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org2.example.com:7051
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.org2.example.com:7051
- CORE_PEER_LOCALMSPID=Org2MSP
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: peer node start
volumes:
- /var/run/:/host/var/run/
- ./crypto-config/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/msp:/etc/hyperledger/fabric/msp
- ./crypto-config/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls:/etc/hyperledger/fabric/tls
- peer1.org2.example.com:/var/hyperledger/production
ports:
- 10051:7051
- 10053:7053
networks:
- fabricnet02
cli:
container_name: cli
image: hyperledger/fabric-tools:$IMAGE_TAG
tty: true
stdin_open: true
environment:
- GOPATH=/opt/gopath
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
#- FABRIC_LOGGING_SPEC=DEBUG
- FABRIC_LOGGING_SPEC=INFO
- 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/[email protected]/msp
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: /bin/bash
volumes:
- /var/run/:/host/var/run/
- ./chaincode/:/opt/gopath/src/github.com/chaincode
- ./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:
- orderer.example.com
- peer0.org1.example.com
- peer1.org1.example.com
- peer0.org2.example.com
- peer1.org2.example.com
networks:
- fabricnet02
6 启动容器
因为上面对chaincode目录作了映射,所以先创建chaincode目录
$ mkdir chaincode
下面启动了5个容器,相当于启动了5台机器,每一个容器对应一台机器。
$ IMAGE_TAG=1.4.0 docker-compose -f docker-compose-cli.yaml up -d 2>&1
WARNING: The COMPOSE_PROJECT_NAME variable is not set. Defaulting to a blank string.
Creating orderer.example.com ... done
Creating peer0.org2.example.com ... done
Creating peer0.org1.example.com ... done
Creating peer1.org2.example.com ... done
Creating peer1.org1.example.com ... done
Creating cli ... done
注:如果启动失败,报出如下错误
ERROR: for peer0.org1.example.com Cannot create container for service peer0.org1.example.com: b'Conflict. The container name "/peer0.org1.example.com" is already in use by container "481980a1891131a47b1076370602de708595cbbbff0a9e6cc8b13e160c4414de". You have to remove (or rename) that container to be able to reuse that name.'
可以输入如下命令停止掉对应的容器,然后删除
docker ps -a
docker stop $(docker ps -a -q)
docker rm $(docker ps -a -q)
docker volume prune
7 复制链码到fabricnet02目录
注:这里是复制官方的fabric-samples里提供的链码来直接安装调用,你也可以自己编写链码
$ cp -r ../../hyperledger/fabric-samples/chaincode/chaincode_example02 ./chaincode
8 进入cli 容器
$ docker exec -it cli /bin/bash
9 创建通道
设置环境变量
export CHANNEL_NAME=mychannel
export CORE_PEER_TLS_ENABLED=true
export 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 $CHANNEL_NAME -f ./channel-artifacts/channel.tx --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA
10 让所有节点加入通道
10.1 org1的peer0节点加入通道
先设置组织1的peer0节点要用到的环境变量
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp
export 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
export CORE_PEER_ADDRESS=peer0.org1.example.com:7051
export CHANNEL_NAME=mychannel
加入通道
peer channel join -b $CHANNEL_NAME.block
10.2 org1的peer1节点加入通道
先设置组织1的peer1节点要用到的环境变量
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/ca.crt
export CORE_PEER_ADDRESS=peer1.org1.example.com:7051
export CHANNEL_NAME=mychannel
加入通道
peer channel join -b $CHANNEL_NAME.block
10.3 org2的peer0节点加入通道
先设置组织2的peer0节点要用到的环境变量
export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp
export 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
export CORE_PEER_ADDRESS=peer0.org2.example.com:7051
export CHANNEL_NAME=mychannel
加入通道
peer channel join -b $CHANNEL_NAME.block
10.4 org2的peer1节点加入通道
先设置组织2的peer1节点要用到的环境变量
export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp
export 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
export CORE_PEER_ADDRESS=peer1.org2.example.com:7051
export CHANNEL_NAME=mychannel
加入通道
peer channel join -b $CHANNEL_NAME.block
11 更新锚节点
11.1 更新组织1的锚节点
设置环境变量
export CHANNEL_NAME=mychannel
export CORE_PEER_TLS_ENABLED=true
export 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
export CORE_PEER_LOCALMSPID="Org1MSP"
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp
创建通道
peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/${CORE_PEER_LOCALMSPID}anchors.tx --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA
11.2 更新组织1的锚节点
设置环境变量
export CHANNEL_NAME=mychannel
export CORE_PEER_TLS_ENABLED=true
export 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
export CORE_PEER_LOCALMSPID="Org2MSP"
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp
创建通道
peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/${CORE_PEER_LOCALMSPID}anchors.tx --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA
12 安装(install)链码
12.1 在组织1的peer0节点安装链码
首先设置组织1的peer0节点要用到的环境变量
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp
export 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
export CORE_PEER_ADDRESS=peer0.org1.example.com:7051
export CHANNEL_NAME=mychannel
然后执行install安装链码到组织1的peer0节点
peer chaincode install -n mycc -v 1.0 -l golang -p github.com/chaincode/chaincode_example02/go
12.2 在组织1的peer1节点安装链码
首先设置组织1的peer1节点要用到的环境变量
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/ca.crt
export CORE_PEER_ADDRESS=peer1.org1.example.com:7051
export CHANNEL_NAME=mychannel
然后执行install安装链码到组织1的peer0节点
peer chaincode install -n mycc -v 1.0 -l golang -p github.com/chaincode/chaincode_example02/go
12.3 在组织2的peer0节点安装链码
首先设置组织2的peer0节点要用到的环境变量
export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp
export 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
export CORE_PEER_ADDRESS=peer0.org2.example.com:7051
export CHANNEL_NAME=mychannel
然后执行install安装链码到组织1的peer0节点
peer chaincode install -n mycc -v 1.0 -l golang -p github.com/chaincode/chaincode_example02/go
12.4 在组织2的peer1节点安装链码
首先设置组织2的peer1节点要用到的环境变量
export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp
export 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
export CORE_PEER_ADDRESS=peer1.org2.example.com:7051
export CHANNEL_NAME=mychannel
然后执行install安装链码到组织1的peer0节点
peer chaincode install -n mycc -v 1.0 -l golang -p github.com/chaincode/chaincode_example02/go
13 实例化链码
注:只有需要在4个节点中选择中任何一个节点去实例化就可以了,在这里我们选择组织1的peer0节点
首先设置组织1的peer0节点要用到的环境变量
export CORE_PEER_TLS_ENABLED=true
export 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
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp
export 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
export CORE_PEER_ADDRESS=peer0.org1.example.com:7051
export CHANNEL_NAME=mychannel
然后实例化链码
peer chaincode instantiate -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -l golang -v 1.0 -c '{"Args":["init","a","100","b","200"]}' -P "AND ('Org1MSP.peer','Org2MSP.peer')"
14 执行Query链码
14.1 在组织1的peer1节点查询
设置环境变量
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/ca.crt
export CORE_PEER_ADDRESS=peer1.org1.example.com:7051
export CHANNEL_NAME=mychannel
执行查询,得到100
peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'
14.2 在组织2的peer1节点查询
设置环境变量
export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp
export 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
export CORE_PEER_ADDRESS=peer1.org2.example.com:7051
export CHANNEL_NAME=mychannel
执行查询,得到100
peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'
15 执行Invoke链码
15.1 在组织2的peer0节点调用
设置环境变量
export CHANNEL_NAME=mychannel
export CORE_PEER_TLS_ENABLED=true
export 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
export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp
export 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
export CORE_PEER_ADDRESS=peer0.org2.example.com:7051
执行调用
peer chaincode invoke -o orderer.example.com:7050 --tls true --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 mychannel -n mycc --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"Args":["invoke","a","b","10"]}'
15.2 重新执行14.1或者14.2
可以查询到a账户的余额变成了90,b账户的余额变成了210
16 总结
到此为止,我们基于docker环境成功搭建了hyperledger fabric1.4.0网络并且成功安装执行链码。过程会比较烦琐,有的环境变量重复设置,其实完全没必要。如何能更好的解决这个问题呢?
一种方案是将上面的所有步骤写成一个shell脚本,只要运行脚本文件,就能完成上面所有这些操作。实际上官方提供的first-samples/first-net/下的byfs.sh就是官方将上面步骤写成的脚本,当然该脚本里还包含更多的操作,例如更新链码,以及加入新的组织。
第二种方案是将每个peer(或order)节点的容器,再搭配一个cli容器,单独部署到每台机上,像上述是部署了两个组织,每个组织2个节点,再加上orderer节点,一共五个节点,准备五台机器,在每台机器上部署一个peer节点容器+cli容器,当然部署过程也写成shell脚本就更好了!