1 環(huán)境準(zhǔn)備
環(huán)境準(zhǔn)備請看這篇文章《準(zhǔn)備hyperledger fabric1.4網(wǎng)絡(luò)運行的環(huán)境》
2 網(wǎng)絡(luò)架構(gòu)圖
| 序號 | 組織 | IP | 域名 | 端口映射 | 節(jié)點 |
|---|---|---|---|---|---|
| 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節(jié)點 |
| 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節(jié)點 |
| 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節(jié)點 |
| docker 容器4 | 組織2 - org2 | 172.18.0.9 | peer0.org2.example.com | 0.0.0.0:7050->7050/tcp | peer0節(jié)點 |
| 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節(jié)點 |
| docker 容器6 | 無組織 | 172.18.0.6 | 無 | 無 | cli客戶端 |
3 生成Fabric需要的證書文件
第1步 創(chuàng)建文件夾
$ cd $GOPATH/src/github.com
$ mkdir -p fabric-study/fabricnet02
第2步 生成配置文件
$ cd fabric-study/fabricnet02
$ cryptogen showtemplate > crypto-config.yaml
第3步 修改配置文件crypto-config.yaml
去掉注釋后內(nèi)容如下
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步 根據(jù)crypto-config.yaml生成證書文件
$ cryptogen generate --config=crypto-config.yaml --output ./crypto-config
執(zhí)行上述命令后會生成一個新的文件夾crypto-config,里面存放著相關(guān)的證書文件,可以通過tree命令查看證書文件夾的結(jié)構(gòu)
$ 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
│ └── Admin@example.com
└── 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
│ ├── Admin@org1.example.com
│ ├── User1@org1.example.com
│ ├── User2@org1.example.com
│ └── User3@org1.example.com
└── 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
├── Admin@org2.example.com
├── User1@org2.example.com
└── User2@org2.example.com
40 directories, 14 files
4 生成系統(tǒng)創(chuàng)始區(qū)塊
注:系統(tǒng)創(chuàng)始塊是提供給Orderer節(jié)點使用的
第1步 去fabric源碼中拷貝模板配置文件到本文件夾
$ cp -r $GOPATH/src/github.com/hyperledger/fabric/sampleconfig/configtx.yaml .
第2步 修改拷過來的configtx.yaml
去掉注釋后內(nèi)容如下
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步 生成系統(tǒng)創(chuàng)始塊文件
先創(chuàng)建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 準(zhǔn)備好docker-compose-cli.yaml
$ touch docker-compose-cli.yaml
$ gedit docker-compose-cli.yaml
編輯輸入如下內(nèi)容,然后保存
# 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/Admin@org1.example.com/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目錄作了映射,所以先創(chuàng)建chaincode目錄
$ mkdir chaincode
下面啟動了5個容器,相當(dāng)于啟動了5臺機(jī)器,每一個容器對應(yīng)一臺機(jī)器。
$ 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.'
可以輸入如下命令停止掉對應(yīng)的容器,然后刪除
docker ps -a
docker stop $(docker ps -a -q)
docker rm $(docker ps -a -q)
docker volume prune
7 復(fù)制鏈碼到fabricnet02目錄
注:這里是復(fù)制官方的fabric-samples里提供的鏈碼來直接安裝調(diào)用,你也可以自己編寫鏈碼
$ cp -r ../../hyperledger/fabric-samples/chaincode/chaincode_example02 ./chaincode
8 進(jìn)入cli 容器
$ docker exec -it cli /bin/bash
9 創(chuàng)建通道
設(shè)置環(huán)境變量
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
創(chuàng)建通道
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 讓所有節(jié)點加入通道
10.1 org1的peer0節(jié)點加入通道
先設(shè)置組織1的peer0節(jié)點要用到的環(huán)境變量
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/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節(jié)點加入通道
先設(shè)置組織1的peer1節(jié)點要用到的環(huán)境變量
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/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節(jié)點加入通道
先設(shè)置組織2的peer0節(jié)點要用到的環(huán)境變量
export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/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節(jié)點加入通道
先設(shè)置組織2的peer1節(jié)點要用到的環(huán)境變量
export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/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 更新錨節(jié)點
11.1 更新組織1的錨節(jié)點
設(shè)置環(huán)境變量
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/Admin@org1.example.com/msp
創(chuàng)建通道
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的錨節(jié)點
設(shè)置環(huán)境變量
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/Admin@org2.example.com/msp
創(chuàng)建通道
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節(jié)點安裝鏈碼
首先設(shè)置組織1的peer0節(jié)點要用到的環(huán)境變量
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/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
然后執(zhí)行install安裝鏈碼到組織1的peer0節(jié)點
peer chaincode install -n mycc -v 1.0 -l golang -p github.com/chaincode/chaincode_example02/go
12.2 在組織1的peer1節(jié)點安裝鏈碼
首先設(shè)置組織1的peer1節(jié)點要用到的環(huán)境變量
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/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
然后執(zhí)行install安裝鏈碼到組織1的peer0節(jié)點
peer chaincode install -n mycc -v 1.0 -l golang -p github.com/chaincode/chaincode_example02/go
12.3 在組織2的peer0節(jié)點安裝鏈碼
首先設(shè)置組織2的peer0節(jié)點要用到的環(huán)境變量
export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/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
然后執(zhí)行install安裝鏈碼到組織1的peer0節(jié)點
peer chaincode install -n mycc -v 1.0 -l golang -p github.com/chaincode/chaincode_example02/go
12.4 在組織2的peer1節(jié)點安裝鏈碼
首先設(shè)置組織2的peer1節(jié)點要用到的環(huán)境變量
export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/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
然后執(zhí)行install安裝鏈碼到組織1的peer0節(jié)點
peer chaincode install -n mycc -v 1.0 -l golang -p github.com/chaincode/chaincode_example02/go
13 實例化鏈碼
注:只有需要在4個節(jié)點中選擇中任何一個節(jié)點去實例化就可以了,在這里我們選擇組織1的peer0節(jié)點
首先設(shè)置組織1的peer0節(jié)點要用到的環(huán)境變量
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/Admin@org1.example.com/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 執(zhí)行Query鏈碼
14.1 在組織1的peer1節(jié)點查詢
設(shè)置環(huán)境變量
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/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
執(zhí)行查詢,得到100
peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'
14.2 在組織2的peer1節(jié)點查詢
設(shè)置環(huán)境變量
export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/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
執(zhí)行查詢,得到100
peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'
15 執(zhí)行Invoke鏈碼
15.1 在組織2的peer0節(jié)點調(diào)用
設(shè)置環(huán)境變量
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/Admin@org2.example.com/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
執(zhí)行調(diào)用
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 重新執(zhí)行14.1或者14.2
可以查詢到a賬戶的余額變成了90,b賬戶的余額變成了210
16 總結(jié)
到此為止,我們基于docker環(huán)境成功搭建了hyperledger fabric1.4.0網(wǎng)絡(luò)并且成功安裝執(zhí)行鏈碼。過程會比較煩瑣,有的環(huán)境變量重復(fù)設(shè)置,其實完全沒必要。如何能更好的解決這個問題呢?
一種方案是將上面的所有步驟寫成一個shell腳本,只要運行腳本文件,就能完成上面所有這些操作。實際上官方提供的first-samples/first-net/下的byfs.sh就是官方將上面步驟寫成的腳本,當(dāng)然該腳本里還包含更多的操作,例如更新鏈碼,以及加入新的組織。
第二種方案是將每個peer(或order)節(jié)點的容器,再搭配一個cli容器,單獨部署到每臺機(jī)上,像上述是部署了兩個組織,每個組織2個節(jié)點,再加上orderer節(jié)點,一共五個節(jié)點,準(zhǔn)備五臺機(jī)器,在每臺機(jī)器上部署一個peer節(jié)點容器+cli容器,當(dāng)然部署過程也寫成shell腳本就更好了!