Hyperledger Fabric v2.4联盟链+浏览器搭建
搭建Hyperledger Fabric联盟链
创建文件夹/root/fabric
:
mkdir -p /root/fabric && cd /root/fabric
本实验所有操作均在文件夹/root/fabric
下执行。
检查系统环境
确保系统中安装有Docker、docker-compose和vim。
检查docker是否已安装:
docker --version
检查docker-compose是否已安装:
docker-compose --version
拉取镜像
本实验需要如下3个镜像:
- hyperledger/fabric-tools:包含了 Fabric 所有的二进制程序并且设置 PATH 变量,可以直接通过 Docker 执行相关命令。
- hyperledger/fabric-peer:peer 节点镜像,安装了 peer 相关文件。
- hyperledger/fabric-orderer:orderer 节点镜像,安装了 orderer 相关文件。
执行如下命令检查镜像是否已经拉取:
docker images | grep hyperledger
生成密钥文件
创建crypto-config.yaml
文件:
vim crypto-config.yaml
输入:
进入命令模式,输入命令set paste
进入粘贴模式,将如下内容粘贴至文件中:
OrdererOrgs:
- Name: Orderer
Domin: flxdu.cn
Specs:
- Hostname: orderer
PeerOrgs:
- Name: Org1
Domain: org1.flxdu.cn
EnableNodeOUs: true
Template:
Count: 2
Users:
Count: 1
- Name: Org2
Domain: org2.flxdu.cn
EnableNodeOUs: true
Template:
Count: 2
Users:
Count: 1
注意:vim的粘贴模式有可能会丢失粘贴内容开头的几个字符,请注意检查粘贴完整。
按下ESC
退出粘贴模式,随后输入:
进入命令模式,输入wq
保存并退出。
使用cryptogen generate生成密钥文件:
docker run --privileged --rm -v /root/fabric:/data hyperledger/fabric-tools:2.4 cryptogen generate --config=/data/crypto-config.yaml --output=/data/crypto-config
程序结束后可以看到已经多了一个名为 crypto-config
的文件夹。
配置系统链创世块
创建 configtx.yaml
文件,粘贴如下内容:
Organizations:
- &OrdererOrg
Name: OrdererOrg
ID: OrdererMSP
MSPDir: crypto-config/ordererOrganizations/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.flxdu.cn/msp
AnchorPeers:
- Host: peer0.org1.flxdu.cn
Port: 7051
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')"
Endorsement:
Type: Signature
Rule: "OR('Org1MSP.peer')"
- &Org2
Name: Org2MSP
ID: Org2MSP
MSPDir: crypto-config/peerOrganizations/org2.flxdu.cn/msp
AnchorPeers:
- Host: peer0.org2.flxdu.cn
Port: 7051
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')"
Endorsement:
Type: Signature
Rule: "OR('Org2MSP.peer')"
Capabilities:
Channel: &ChannelCapabilities
V2_0: true
Orderer: &OrdererCapabilities
V2_0: true
Application: &ApplicationCapabilities
V2_0: true
Application: &ApplicationDefaults
Organizations:
Policies:
Readers:
Type: ImplicitMeta
Rule: "ANY Readers"
Writers:
Type: ImplicitMeta
Rule: "ANY Writers"
Admins:
Type: ImplicitMeta
Rule: "MAJORITY Admins"
LifecycleEndorsement:
Type: ImplicitMeta
Rule: "MAJORITY Endorsement"
Endorsement:
Type: ImplicitMeta
Rule: "MAJORITY Endorsement"
Capabilities:
<<: *ApplicationCapabilities
Channel: &ChannelDefaults
Policies:
Readers:
Type: ImplicitMeta
Rule: "ANY Readers"
Writers:
Type: ImplicitMeta
Rule: "ANY Writers"
Admins:
Type: ImplicitMeta
Rule: "MAJORITY Admins"
Capabilities:
<<: *ChannelCapabilities
Orderer: &OrdererDefaults
OrdererType: solo
Addresses:
- orderer.flxdu.cn:7050
BatchTimeout: 2s
BatchSize:
MaxMessageCount: 10
AbsoluteMaxBytes: 99MB
PreferredMaxBytes: 512KB
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"
Capabilities:
<<: *OrdererCapabilities
Profiles:
# TwoOrgsOrdererGenesis配置文件用于创建系统通道创世块
TwoOrgsOrdererGenesis:
<<: *ChannelDefaults
# 定义排序服务
Orderer:
<<: *OrdererDefaults
# 定义排序服务的管理员
Organizations:
- *OrdererOrg
# 创建一个名为SampleConsortium的联盟,包含两个组织Org1,Org2
Consortiums:
SampleConsortium:
Organizations:
- *Org1
- *Org2
# 测试网络使用TwoOrgsChannel配置文件创建应用程序通道
TwoOrgsChannel:
<<: *ChannelDefaults
Consortium: SampleConsortium
Application:
<<: *ApplicationDefaults
Organizations:
- *Org1
- *Org2
新建文件夹configtx
,用于存放生成的创世块配置。
mkdir -p /root/fabric/configtx
使用configtxgen
命令生成的创世块配置,其中-channelID hellodeploy
定义了系统通道的名称,系统通道定义了形成排序服务的Orderer节点集合和充当排序服务管理员的组织集合。
docker run --privileged -v /root/fabric:/data -e FABRIC_CFG_PATH=/data --rm hyperledger/fabric-tools:2.4 configtxgen -profile TwoOrgsOrdererGenesis -outputBlock /data/configtx/genesis.block -channelID hellodeploy
接下来,我们要创建一个应用通道,通道成员为configtx.yaml
文件最后部分TwoOrgsChannel
所定义的两个组织Org1和Org2。
docker run --privileged -v /root/fabric:/data -e FABRIC_CFG_PATH=/data --rm hyperledger/fabric-tools:2.4 configtxgen -profile TwoOrgsChannel -outputCreateChannelTx /data/configtx/hello.tx -channelID hello
我们根据configtx.yaml
文件的profile-TwoOrgsChannel
部分创建了新通道hello
,通道文件为hello.tx
,这个文件非常重要,接下来其他节点要加入这个通道就必须使用这个文件。注意文件后缀为tx
,这是一个交易,是因为我们可以追加交易来更新对其的设置,最终的设置是由所有应用于此的交易生效后的结果。
接下来,我们要指定锚节点。我们在上面已经声明了两个组织:Org1和Org2,这两个组织分别有两个节点:peer0和peer1。我们计划使用通道hello
将Org1和Org2两个组织连接起来,使其可以相互通信,形成联盟。当然也可以建立第二个通道hello2
,让Org2和Org3连接起来形成联盟,此时Org2会维护两套账本(我们接下来不会这样做,只是为了说明)。
我们将会指定节点Org1.peer0和Org2.peer0作为通道hello
上面各自组织的的锚节点。注意节点是否是锚节点取决于通道,比如Org2.peer0在通道hello
上面是锚节点,但是对于连接Org2和Org3的通道hello2
,我们可以指定Org2.peer1为锚节点,那么Org2.peer0在通道hello2
就不是锚节点了。
执行如下命令,生成Org1组织的节点在通道hello
上面更新为锚节点的配置交易。最后-asOrg Org1MSP
是启动节点时的环境变量CORE_PEER_LOCALMSPID
。
docker run --privileged -v /root/fabric:/data -e FABRIC_CFG_PATH=/data --rm hyperledger/fabric-tools:2.4 configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate /data/configtx/Org1MSPanchors_hello.tx -channelID hello -asOrg Org1MSP
同理,生成Org2组织的节点在通道hello
上面更新为锚节点的配置交易。
docker run --privileged -v /root/fabric:/data -e FABRIC_CFG_PATH=/data --rm hyperledger/fabric-tools:2.4 configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate /data/configtx/Org2MSPanchors_hello.tx -channelID hello -asOrg Org2MSP
启动私有集群
接下来,我们使用docker启动一个排序节点,2个组织各有2个节点的私有集群。
创建文件docker-compose.yaml
:
version: '3'
networks:
byfn:
services:
orderer.flxdu.cn:
container_name: orderer.flxdu.cn
image: hyperledger/fabric-orderer:2.4
restart: always
privileged: true
environment:
- ORDERER_GENERAL_LOGLEVEL=debug
- ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
- ORDERER_GENERAL_GENESISMETHOD=file
- ORDERER_GENERAL_GENESISFILE=/etc/hyperledger/configtx/genesis.block
- ORDERER_GENERAL_LOCALMSPID=OrdererMSP
- ORDERER_GENERAL_LOCALMSPDIR=/etc/hyperledger/msp/orderer/msp
volumes:
- ./configtx/genesis.block:/etc/hyperledger/configtx/genesis.block
- ./crypto-config/ordererOrganizations/orderers/orderer./msp:/etc/hyperledger/msp/orderer/msp
- ./var/orderer.flxdu.cn:/var/hyperledger/production/orderer
ports:
- "7050:7050"
command: orderer start
networks:
- byfn
cli:
container_name: cli
image: hyperledger/fabric-tools:2.4
tty: true
privileged: true
environment:
- GOPATH=/opt/gopath
- FABRIC_LOGGING_SPEC=DEBUG
- CORE_PEER_ID=cli
- CORE_CHAINCODE_KEEPALIVE=10
command: /bin/bash
volumes:
- ./chaincode:/opt/gopath/src/github.com
- ./crypto-config:/opt/crypto-config
- ./configtx:/opt/configtx
networks:
- byfn
peer0.org1.flxdu.cn:
container_name: peer0.org1.flxdu.cn
image: hyperledger/fabric-peer:2.4
privileged: true
environment:
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=${PROJECT_NAME}_byfn
- FABRIC_LOGGING_SPEC=INFO
- CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/peer/msp
- CORE_PEER_ID=peer0.org1.flxdu.cn
- CORE_PEER_ADDRESS=peer0.org1.flxdu.cn:7051
- CORE_PEER_LOCALMSPID=Org1MSP
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.flxdu.cn:7051
- CORE_PEER_GOSSIP_ORGLEADER=false
- CORE_PEER_GOSSIP_USELEADERELECTION=true
- CORE_PEER_GOSSIP_STATE_ENABLED=true
- CORE_CHAINCODE_NODE_RUNTIME=hyperledger/fabric-nodeenv:2.4
command: peer node start
volumes:
- /var/run/docker.sock:/host/var/run/docker.sock
- ./crypto-config/peerOrganizations/org1.flxdu.cn/peers/peer0.org1.flxdu.cn/msp:/etc/hyperledger/peer/msp
- ./var/peer0.org1.flxdu.cn:/var/hyperledger/production
ports:
- "7051:7051"
- "7053:7053"
networks:
- byfn
peer1.org1.flxdu.cn:
container_name: peer1.org1.flxdu.cn
image: hyperledger/fabric-peer:2.4
privileged: true
environment:
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=${PROJECT_NAME}_byfn
- FABRIC_LOGGING_SPEC=INFO
- CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/peer/msp
- CORE_PEER_ID=peer1.org1.flxdu.cn
- CORE_PEER_ADDRESS=peer1.org1.flxdu.cn:7051
- CORE_PEER_LOCALMSPID=Org1MSP
- CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org1.flxdu.cn:7051
- CORE_PEER_GOSSIP_ORGLEADER=false
- CORE_PEER_GOSSIP_USELEADERELECTION=true
- CORE_PEER_GOSSIP_STATE_ENABLED=true
- CORE_CHAINCODE_NODE_RUNTIME=hyperledger/fabric-nodeenv:2.4
command: peer node start
volumes:
- /var/run/docker.sock:/host/var/run/docker.sock
- ./crypto-config/peerOrganizations/org1.flxdu.cn/peers/peer1.org1.flxdu.cn/msp:/etc/hyperledger/peer/msp
- ./var/peer1.org1.flxdu.cn:/var/hyperledger/production
ports:
- "8051:7051"
- "8053:7053"
networks:
- byfn
peer0.org2.flxdu.cn:
container_name: peer0.org2.flxdu.cn
image: hyperledger/fabric-peer:2.4
privileged: true
environment:
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=${PROJECT_NAME}_byfn
- FABRIC_LOGGING_SPEC=INFO
- CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/peer/msp
- CORE_PEER_ID=peer0.org2.flxdu.cn
- CORE_PEER_ADDRESS=peer0.org2.flxdu.cn:7051
- CORE_PEER_LOCALMSPID=Org2MSP
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org2.flxdu.cn:7051
- CORE_PEER_GOSSIP_ORGLEADER=false
- CORE_PEER_GOSSIP_USELEADERELECTION=true
- CORE_PEER_GOSSIP_STATE_ENABLED=true
- CORE_CHAINCODE_NODE_RUNTIME=hyperledger/fabric-nodeenv:2.4
command: peer node start
volumes:
- /var/run/docker.sock:/host/var/run/docker.sock
- ./crypto-config/peerOrganizations/org2.flxdu.cn/peers/peer0.org2.flxdu.cn/msp:/etc/hyperledger/peer/msp
- ./var/peer0.org2.flxdu.cn:/var/hyperledger/production
ports:
- "9051:7051"
- "9053:7053"
networks:
- byfn
peer1.org2.flxdu.cn:
container_name: peer1.org2.flxdu.cn
image: hyperledger/fabric-peer:2.4
privileged: true
environment:
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=${PROJECT_NAME}_byfn
- FABRIC_LOGGING_SPEC=INFO
- CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/peer/msp
- CORE_PEER_ID=peer1.org2.flxdu.cn
- CORE_PEER_ADDRESS=peer1.org2.flxdu.cn:7051
- CORE_PEER_LOCALMSPID=Org2MSP
- CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org2.flxdu.cn:7051
- CORE_PEER_GOSSIP_ORGLEADER=false
- CORE_PEER_GOSSIP_USELEADERELECTION=true
- CORE_PEER_GOSSIP_STATE_ENABLED=true
- CORE_CHAINCODE_NODE_RUNTIME=hyperledger/fabric-nodeenv:2.4
command: peer node start
volumes:
- /var/run/docker.sock:/host/var/run/docker.sock
- ./crypto-config/peerOrganizations/org2.flxdu.cn/peers/peer1.org2.flxdu.cn/msp:/etc/hyperledger/peer/msp
- ./var/peer1.org2.flxdu.cn:/var/hyperledger/production
ports:
- "10051:7051"
- "10053:7053"
networks:
- byfn
启动私有集群
PROJECT_NAME=fabric docker-compose -f /root/fabric/docker-compose.yaml up -d
检查私有集群的运行状态:
docker ps -a
接下来基于在文件hello.tx
中的配置交易创建通道hello,使用的排序器端结点为orderer.flxdu.cn:7050
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/crypto-config/peerOrganizations/org1.flxdu.cn/users/Admin@org1.flxdu.cn/msp -e CORE_PEER_LOCALMSPID="Org1MSP" cli peer channel create -o orderer.flxdu.cn:7050 -c hello -f /opt/configtx/hello.tx
此命令会生成一个名为hello.block的文件,说明通道hello已经成功创建,第0块已经加入到该通道的区块链中并返回给节点,该区块在本地文件中正是hello.block,路径为cli容器的/go/hello.block。
第0块通常被称为创世块,因为它提供了通道的起始配置。
我们把hello.block挪到我们自己的配置文件路径。
docker exec cli mv /go/hello.block /opt/configtx/
接下来,我们将使用6个命令,将4个节点加入通道hello,将其中2个节点设置为锚节点。
将org1.peer0加入通道
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/crypto-config/peerOrganizations/org1.flxdu.cn/users/Admin@org1.flxdu.cn/msp -e CORE_PEER_LOCALMSPID="Org1MSP" -e CORE_PEER_ADDRESS=peer0.org1.flxdu.cn:7051 cli peer channel join -b /opt/configtx/hello.block
将org1.peer1加入通道
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/crypto-config/peerOrganizations/org1.flxdu.cn/users/Admin@org1.flxdu.cn/msp -e CORE_PEER_LOCALMSPID="Org1MSP" -e CORE_PEER_ADDRESS=peer1.org1.flxdu.cn:7051 cli peer channel join -b /opt/configtx/hello.block
将org2.peer0加入通道
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/crypto-config/peerOrganizations/org2.flxdu.cn/users/Admin@org2.flxdu.cn/msp -e CORE_PEER_LOCALMSPID="Org2MSP" -e CORE_PEER_ADDRESS=peer0.org2.flxdu.cn:7051 cli peer channel join -b /opt/configtx/hello.block
将org2.peer1加入通道
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/crypto-config/peerOrganizations/org2.flxdu.cn/users/Admin@org2.flxdu.cn/msp -e CORE_PEER_LOCALMSPID="Org2MSP" -e CORE_PEER_ADDRESS=peer1.org2.flxdu.cn:7051 cli peer channel join -b /opt/configtx/hello.block
将org1.peer0设置为锚节点
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/crypto-config/peerOrganizations/org1.flxdu.cn/users/Admin@org1.flxdu.cn/msp -e CORE_PEER_LOCALMSPID="Org1MSP" -e CORE_PEER_ADDRESS=peer0.org1.flxdu.cn:7051 cli peer channel update -o orderer.flxdu.cn:7050 -c hello -f /opt/configtx/Org1MSPanchors_hello.tx
将org2.peer0设置为锚节点
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/crypto-config/peerOrganizations/org2.flxdu.cn/users/Admin@org2.flxdu.cn/msp -e CORE_PEER_LOCALMSPID="Org2MSP" -e CORE_PEER_ADDRESS=peer0.org2.flxdu.cn:7051 cli peer channel update -o orderer.flxdu.cn:7050 -c hello -f /opt/configtx/Org2MSPanchors_hello.tx
这样,整个网络就搭起来了,可以进行链码(智能合约)部署等进一步操作。
停止网络
执行
PROJECT_NAME=fabric docker-compose -f /root/fabric/docker-compose.yaml down
即可停止网络。
可通过
PROJECT_NAME=fabric docker-compose -f /root/fabric/docker-compose.yaml up -d
再次启动网络。
部署链码
与实验一相同,本实验所有操作均在文件夹/root/fabric
下执行,且确保系统中安装有Docker、docker-compose和vim。
需要确保实验一中的联盟链已经搭建并运行成功。
Go语言
打包链码sacc
创建目录/root/fabric/chaincode/sacc/
:
mkdir -p /root/fabric/chaincode/sacc/
将链码sacc.go拷贝至目录/root/fabric/chaincode/sacc/
下。
进入cli容器进行后续操作
docker exec -it cli /bin/sh
# 接下来的命令均在容器内执行
cd /opt/gopath/src/github.com/sacc
# 设置代理
go env -w GOPROXY=https://goproxy.cn,direct
# 设置依赖
go mod init
go mod tidy
# 打包链码
peer lifecycle chaincode package sacc.tar.gz --path github.com/sacc/ --label sacc_1
# 退出容器
exit
打包完成后,会在目录/root/fabric/chaincode/sacc/
下发现文件sacc.tar.gz
。
安装链码sacc
链码要安装至Org1和Org2。
在Org1安装链码
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/crypto-config/peerOrganizations/org1.flxdu.cn/users/Admin@org1.flxdu.cn/msp -e CORE_PEER_LOCALMSPID="Org1MSP" -e CORE_PEER_ADDRESS=peer0.org1.flxdu.cn:7051 cli peer lifecycle chaincode install /opt/gopath/src/github.com/sacc/sacc.tar.gz
看到输出Chaincode code package identifier
即为成功,如下图:
在Org2安装链码
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/crypto-config/peerOrganizations/org2.flxdu.cn/users/Admin@org2.flxdu.cn/msp -e CORE_PEER_LOCALMSPID="Org2MSP" -e CORE_PEER_ADDRESS=peer0.org2.flxdu.cn:7051 cli peer lifecycle chaincode install /opt/gopath/src/github.com/sacc/sacc.tar.gz
安装成功的输出与Org1安装链码的输出相同。
安装后的链码要在组织中确定。
在Org1中确定链码,注意--package-id
后面是上一步的Chaincode code package identifier
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/crypto-config/peerOrganizations/org1.flxdu.cn/users/Admin@org1.flxdu.cn/msp -e CORE_PEER_LOCALMSPID="Org1MSP" -e CORE_PEER_ADDRESS=peer0.org1.flxdu.cn:7051 cli peer lifecycle chaincode approveformyorg --channelID hello --name sacc --version 1.0 --init-required --package-id sacc_1:4b29ffe6a929d1253f3ed2f9ed6c6855ad9cff68b9a0a8237c1311a0df1927dd --sequence 1
安装成功后会输出,如下图:
在Org2中确定链码,注意--package-id
后面是上一步的Chaincode code package identifier
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/crypto-config/peerOrganizations/org2.flxdu.cn/users/Admin@org2.flxdu.cn/msp -e CORE_PEER_LOCALMSPID="Org2MSP" -e CORE_PEER_ADDRESS=peer0.org2.flxdu.cn:7051 cli peer lifecycle chaincode approveformyorg --channelID hello --name sacc --version 1.0 --init-required --package-id sacc_1:4b29ffe6a929d1253f3ed2f9ed6c6855ad9cff68b9a0a8237c1311a0df1927dd --sequence 1
确定成功的输出与Org1确定链码的输出相同。
确定完成后,检查是否配置正常
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/crypto-config/peerOrganizations/org1.flxdu.cn/users/Admin@org1.flxdu.cn/msp -e CORE_PEER_LOCALMSPID="Org1MSP" -e CORE_PEER_ADDRESS=peer0.org1.flxdu.cn:7051 cli peer lifecycle chaincode checkcommitreadiness --channelID hello --name sacc --version 1.0 --init-required --sequence 1 --output json
此时输出如下内容表示配置正常,如有 false 则表示安装有问题:
{
"approvals": {
"Org1MSP": true,
"Org2MSP": true
}
}
提交、初始化并执行链码
提交链码
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/crypto-config/peerOrganizations/org1.flxdu.cn/users/Admin@org1.flxdu.cn/msp -e CORE_PEER_LOCALMSPID="Org1MSP" -e CORE_PEER_ADDRESS=peer0.org1.flxdu.cn:7051 cli peer lifecycle chaincode commit -o orderer.flxdu.cn:7050 --channelID hello --name sacc --version 1.0 --sequence 1 --init-required --peerAddresses peer0.org1.flxdu.cn:7051 --peerAddresses peer0.org2.flxdu.cn:7051
初始化
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/crypto-config/peerOrganizations/org1.flxdu.cn/users/Admin@org1.flxdu.cn/msp -e CORE_PEER_LOCALMSPID="Org1MSP" -e CORE_PEER_ADDRESS=peer0.org1.flxdu.cn:7051 cli peer chaincode invoke -o orderer.flxdu.cn:7050 --isInit --channelID hello --name sacc --peerAddresses peer0.org1.flxdu.cn:7051 --peerAddresses peer0.org2.flxdu.cn:7051 -c '{"Args":["hello", "world"]}'
看到输出Chaincode invoke successful. result: status:200
可认为成功。
查询
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/crypto-config/peerOrganizations/org1.flxdu.cn/users/Admin@org1.flxdu.cn/msp -e CORE_PEER_LOCALMSPID="Org1MSP" -e CORE_PEER_ADDRESS=peer0.org1.flxdu.cn:7051 cli peer chaincode query --channelID hello -n sacc -c '{"Args":["query", "hello"]}'
可以得到结果为world,说明初始化的参数已被存储。
设置/修改
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/crypto-config/peerOrganizations/org1.flxdu.cn/users/Admin@org1.flxdu.cn/msp -e CORE_PEER_LOCALMSPID="Org1MSP" -e CORE_PEER_ADDRESS=peer0.org1.flxdu.cn:7051 cli peer chaincode invoke -o orderer.flxdu.cn:7050 --channelID hello -n sacc --peerAddresses peer0.org1.flxdu.cn:7051 --peerAddresses peer0.org2.flxdu.cn:7051 -c '{"Args":["set", "hello", "block chain"]}'
再执行上一步查询,可以得到结果为block chain,说明修改成功。也可以set一个新键值对,在查询时同样可以查到。链码具体逻辑可以查看链码文件。
JavaScript语言
宿主机需先执行:
echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf && systemctl restart network
本实验需要如下1个镜像:
- hyperledger/fabric-nodeenv:包含了NodeJS的所有二进制程序并且设置 PATH 变量,可以直接通过 Docker 执行相关命令。
打包链码abstore
打包JavaScript链码所需的镜像hyperledger/fabric-nodeenv:2.4
使用的npm源在国内无法访问,所以我们需要自己造一个镜像来使用:
# 创建Dockerfile
cat <<EOF>> Dockerfile
FROM hyperledger/fabric-nodeenv:2.4
RUN npm config set registry http://mirrors.cloud.tencent.com/npm/
EOF
# 构建镜像
docker build -t temp/fabric-nodeenv:2.4 .
# 删除原有的hyperledger/fabric-nodeenv:2.4
docker rmi hyperledger/fabric-nodeenv:2.4
# 修改镜像标签
docker tag temp/fabric-nodeenv:2.4 docker.io/hyperledger/fabric-nodeenv:2.4 && docker rmi temp/fabric-nodeenv:2.4
创建目录/root/fabric/chaincode/abstore/
:
mkdir -p /root/fabric/chaincode/abstore/
将package.json和链码abstore.js拷贝至目录/root/fabric/chaincode/abstore/
下。
打包链码:
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/crypto-config/peerOrganizations/org1.flxdu.cn/users/Admin@org1.flxdu.cn/msp -e CORE_PEER_LOCALMSPID="Org1MSP" -e CORE_PEER_ADDRESS=peer0.org1.flxdu.cn:7051 cli peer lifecycle chaincode package /opt/gopath/src/github.com/abstore/abstore.tar.gz --path /opt/gopath/src/github.com/abstore --label abstore_1 -l node
打包完成后,会在目录/root/fabric/chaincode/abstore/
下发现文件abstore.tar.gz
。
安装链码abstore
在org1中安装链码
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/crypto-config/peerOrganizations/org1.flxdu.cn/users/Admin@org1.flxdu.cn/msp -e CORE_PEER_LOCALMSPID="Org1MSP" -e CORE_PEER_ADDRESS=peer0.org1.flxdu.cn:7051 cli peer lifecycle chaincode install /opt/gopath/src/github.com/abstore/abstore.tar.gz
看到输出Installed remotely: response:<status:200 payload:"OK" >
即为成功,如下图:
在org2中安装链码
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/crypto-config/peerOrganizations/org2.flxdu.cn/users/Admin@org2.flxdu.cn/msp -e CORE_PEER_LOCALMSPID="Org2MSP" -e CORE_PEER_ADDRESS=peer0.org2.flxdu.cn:7051 cli peer lifecycle chaincode install /opt/gopath/src/github.com/abstore/abstore.tar.gz
看到输出Installed remotely: response:<status:200 payload:"OK" >
即为成功。
安装后的链码要在组织中确定。
在Org1中确定链码,注意--package-id
后面是上一步的Chaincode code package identifier
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/crypto-config/peerOrganizations/org1.flxdu.cn/users/Admin@org1.flxdu.cn/msp -e CORE_PEER_LOCALMSPID="Org1MSP" -e CORE_PEER_ADDRESS=peer0.org1.flxdu.cn:7051 cli peer lifecycle chaincode approveformyorg --channelID hello --name abstore --version 1.0 --init-required --package-id abstore_1:1aff8f80f9b007823cd9be5523569a3088b5b2018c346ea72aeee426f5274f99 --sequence 1
在Org2中确定链码,
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/crypto-config/peerOrganizations/org2.flxdu.cn/users/Admin@org2.flxdu.cn/msp -e CORE_PEER_LOCALMSPID="Org2MSP" -e CORE_PEER_ADDRESS=peer0.org2.flxdu.cn:7051 cli peer lifecycle chaincode approveformyorg --channelID hello --name abstore --version 1.0 --init-required --package-id abstore_1:1aff8f80f9b007823cd9be5523569a3088b5b2018c346ea72aeee426f5274f99 --sequence 1
确定成功的输出与Org1确定链码的输出相同。
确定完成后,检查是否配置正常
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/crypto-config/peerOrganizations/org1.flxdu.cn/users/Admin@org1.flxdu.cn/msp -e CORE_PEER_LOCALMSPID="Org1MSP" -e CORE_PEER_ADDRESS=peer0.org1.flxdu.cn:7051 cli peer lifecycle chaincode checkcommitreadiness --channelID hello --name abstore --version 1.0 --init-required --sequence 1 --output json
此时输出如下内容表示配置正常,如有 false 则表示安装有问题:
{
"approvals": {
"Org1MSP": true,
"Org2MSP": true
}
}
提交、初始化并执行链码
提交链码
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/crypto-config/peerOrganizations/org1.flxdu.cn/users/Admin@org1.flxdu.cn/msp -e CORE_PEER_LOCALMSPID="Org1MSP" -e CORE_PEER_ADDRESS=peer0.org1.flxdu.cn:7051 cli peer lifecycle chaincode commit -o orderer.flxdu.cn:7050 --channelID hello --name abstore --version 1.0 --sequence 1 --init-required --peerAddresses peer0.org1.flxdu.cn:7051 --peerAddresses peer0.org2.flxdu.cn:7051
初始化,初始化a和b两个主体,其各有100、200单位的余额:
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/crypto-config/peerOrganizations/org1.flxdu.cn/users/Admin@org1.flxdu.cn/msp -e CORE_PEER_LOCALMSPID="Org1MSP" -e CORE_PEER_ADDRESS=peer0.org1.flxdu.cn:7051 cli peer chaincode invoke -o orderer.flxdu.cn:7050 --isInit --channelID hello --name abstore --peerAddresses peer0.org1.flxdu.cn:7051 --peerAddresses peer0.org2.flxdu.cn:7051 -c '{"Args":["init","a","100","b","200"]}'
看到输出Chaincode invoke successful. result: status:200
可认为成功。
查询a的余额:
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/crypto-config/peerOrganizations/org1.flxdu.cn/users/Admin@org1.flxdu.cn/msp -e CORE_PEER_LOCALMSPID="Org1MSP" -e CORE_PEER_ADDRESS=peer0.org1.flxdu.cn:7051 cli peer chaincode query --channelID hello -n abstore -c '{"Args":["query", "b"]}'
可以得到结果为100,说明初始化的参数已被存储。
a向b转账1个单位
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/crypto-config/peerOrganizations/org1.flxdu.cn/users/Admin@org1.flxdu.cn/msp -e CORE_PEER_LOCALMSPID="Org1MSP" -e CORE_PEER_ADDRESS=peer0.org1.flxdu.cn:7051 cli peer chaincode invoke -o orderer.flxdu.cn:7050 --channelID hello -n abstore --peerAddresses peer0.org1.flxdu.cn:7051 --peerAddresses peer0.org2.flxdu.cn:7051 -c '{"Args":["invoke", "a", "b", "1"]}'
再执行上一步查询,可以看到a的余额变味了99,b的余额变为了201,说明修改成功。也可以把a和b删除,链码具体逻辑可以查看链码文件。链码中没有新增主体的函数,可以尝试修改链码以增加这个功能。
部署浏览器
创建文件夹/root/fabric-explorer
:
mkdir -p /root/fabric-explorer && cd /root/fabric-explorer
本实验所有操作均在文件夹/root/fabric-explorer
下执行,且确保系统中安装有Docker、docker-compose和vim。
需要确保实验一中的联盟链已经搭建并运行成功。
拉取镜像
本实验需要如下3个镜像:
- hyperledger/explorer-db:浏览器所需的Postgresql数据库。
- hyperledger/explorer:浏览器镜像。
执行如下命令检查镜像是否已经拉取:
docker images | grep hyperledger/explorer
拷贝密钥文件
将我们在部署网络时生成的文件夹crypto-config
拷贝到fabric-explorer
,并重命名为organizations
。
cp -a /root/fabric/crypto-config /root/fabric-explorer/organizations
在fabric-explorer
下新建文件夹connection-profile
,后续浏览器会使用文件夹下的配置连接各个节点:
mkdir -p /root/fabric-explorer/connection-profile
因为我们希望能查看两个组织的情况,所以我们要在connection-profile
下放两个配置文件。
在connection-profile
下新建文件org1-network.json
:
{
"name": "org1-network",
"version": "1.0.0",
"client": {
"tlsEnable": false,
"adminCredential": {
"id": "exploreradmin",
"password": "exploreradminpw"
},
"enableAuthentication": true,
"organization": "Org1MSP",
"connection": {
"timeout": {
"peer": {
"endorser": "300"
},
"orderer": "300"
}
}
},
"channels": {
"hello": {
"peers": {
"peer0.org1.flxdu.cn": {}
}
}
},
"organizations": {
"Org1MSP": {
"mspid": "Org1MSP",
"adminPrivateKey": {
"path": "/tmp/crypto/peerOrganizations/org1.flxdu.cn/users/Admin@org1.flxdu.cn/msp/keystore/priv_sk"
},
"peers": ["peer0.org1.flxdu.cn"],
"signedCert": {
"path": "/tmp/crypto/peerOrganizations/org1.flxdu.cn/users/Admin@org1.flxdu.cn/msp/signcerts/Admin@org1.flxdu.cn-cert.pem"
}
}
},
"peers": {
"peer0.org1.flxdu.cn": {
"tlsCACerts": {
"path": "/tmp/crypto/peerOrganizations/org1.flxdu.cn/peers/peer0.org1.flxdu.cn/tls/ca.crt"
},
"url": "grpc://peer0.org1.flxdu.cn:7051"
}
}
}
在connection-profile
下新建文件org2-network.json
:
{
"name": "org2-network",
"version": "1.0.0",
"client": {
"tlsEnable": false,
"adminCredential": {
"id": "exploreradmin",
"password": "exploreradminpw"
},
"enableAuthentication": true,
"organization": "Org2MSP",
"connection": {
"timeout": {
"peer": {
"endorser": "300"
},
"orderer": "300"
}
}
},
"channels": {
"hello": {
"peers": {
"peer0.org2.flxdu.cn": {}
}
}
},
"organizations": {
"Org2MSP": {
"mspid": "Org2MSP",
"adminPrivateKey": {
"path": "/tmp/crypto/peerOrganizations/org2.flxdu.cn/users/Admin@org2.flxdu.cn/msp/keystore/priv_sk"
},
"peers": ["peer0.org2.flxdu.cn"],
"signedCert": {
"path": "/tmp/crypto/peerOrganizations/org2.flxdu.cn/users/Admin@org2.flxdu.cn/msp/signcerts/Admin@org2.flxdu.cn-cert.pem"
}
}
},
"peers": {
"peer0.org2.flxdu.cn": {
"tlsCACerts": {
"path": "/tmp/crypto/peerOrganizations/org2.flxdu.cn/peers/peer0.org2.flxdu.cn/tls/ca.crt"
},
"url": "grpc://peer0.org2.flxdu.cn:7051"
}
}
}
注意在org1-network.json
和org2-network.json
中,字段adminCredential
配置了访问浏览器所需要的用户名和密码;字段tlsEnable
配置了要连接的节点是否为TLS节点,因为我们的节点没开启TLS,所以此项为false,且位于最后面的字段peers.url
前缀为grpc://
,如果是TLS节点的话应写为grpcs://
。
在fabric-explorer
目录下创建浏览器的配置文件config.json
,其配置了两个组织的网络。
{
"network-configs": {
"org1-network": {
"name": "org1-network",
"profile": "./connection-profile/org1-network.json"
},
"org2-network": {
"name": "org2-network",
"profile": "./connection-profile/org2-network.json"
}
},
"license": "Apache-2.0"
}
以上配置文件文档在Github - README-CONFIG.md
在fabric-explorer
目录下创建docker-compose.yaml
文件。
# SPDX-License-Identifier: Apache-2.0
version: '2.1'
volumes:
pgdata:
walletstore:
networks:
mynetwork.com:
external:
name: fabric_byfn
services:
explorerdb.mynetwork.com:
image: hyperledger/explorer-db:1.1.8
container_name: explorerdb.mynetwork.com
hostname: explorerdb.mynetwork.com
privileged: true
environment:
- DATABASE_DATABASE=fabricexplorer
- DATABASE_USERNAME=hppoc
- DATABASE_PASSWORD=password
healthcheck:
test: "pg_isready -h localhost -p 5432 -q -U postgres"
interval: 30s
timeout: 10s
retries: 5
volumes:
- pgdata:/var/lib/postgresql/data
networks:
- mynetwork.com
explorer.mynetwork.com:
image: hyperledger/explorer:1.1.8
container_name: explorer.mynetwork.com
hostname: explorer.mynetwork.com
privileged: true
environment:
- DATABASE_HOST=explorerdb.mynetwork.com
- DATABASE_DATABASE=fabricexplorer
- DATABASE_USERNAME=hppoc
- DATABASE_PASSWD=password
- LOG_LEVEL_APP=debug
- LOG_LEVEL_DB=debug
- LOG_LEVEL_CONSOLE=info
- LOG_CONSOLE_STDOUT=true
- DISCOVERY_AS_LOCALHOST=false
volumes:
- ./config.json:/opt/explorer/app/platform/fabric/config.json
- ./connection-profile:/opt/explorer/app/platform/fabric/connection-profile
- ./organizations:/tmp/crypto
- walletstore:/opt/explorer/wallet
ports:
- "8080:8080"
depends_on:
explorerdb.mynetwork.com:
condition: service_healthy
networks:
- mynetwork.com
文件中使用的网络是部署网络时创建的fabric_byfn,必须使用同一网络,否则浏览器无法通过域名连接节点。
接下来就可以启动浏览器了
docker-compose up -d
等待浏览器完全启动后,在Chrome打开http://127.0.0.1:8080/
,可以看到登录页面,输入用户名exploreradmin
,密码exploreradminpw
即可登录,如下图所示:
向组织中添加新节点
目前我们的Fabric网络中包含两个组织,每个组织都有两个节点:
- org1:
- peer0.org1.flxdu.cn
- peer1.org1.flxdu.cn
- org2:
- peer0.org2.flxdu.cn
- peer1.org2.flxdu.cn
我们需要在 org1 中添加一个 peer2.org1.flxdu.cn 节点。
生成新节点证书
每个节点都有相应的证书才能连接网络,需要使用 cryptogen 工具生成新节点的证书。因为是新节点加入现有网络组织,因此,需要使用 cryptogen extend 命令首先对现有网络的证书文件进行扩展。在执行该命令之前需要首先修改 crypto-config.yaml 配置文件,将 org1 组织的节点数增加 1,其它的配置信息不要修改。
修改后的 crypto-config.yaml 配置文件:
OrdererOrgs:
- Name: Orderer
Domin: flxdu.cn
Specs:
- Hostname: orderer
PeerOrgs:
- Name: Org1
Domain: org1.flxdu.cn
EnableNodeOUs: true
Template:
Count: 3
Users:
Count: 1
- Name: Org2
Domain: org2.flxdu.cn
EnableNodeOUs: true
Template:
Count: 2
Users:
Count: 1
修改完成后即可使用 cryptogen extend
命令生成新节点证书,注意,这里需要使用 --config
选项指定刚才修改的配置文件:
docker run --privileged --rm -v /root/fabric:/data hyperledger/fabric-tools:2.4 cryptogen extend --config=/data/crypto-config.yaml --input=/data/crypto-config
可以看到在/root/fabric/crypto-config/peerOrganizations/org1.flxdu.cn/peers
目录下多了一个peer2.org1.flxdu.cn
目录。
添加新节点配置信息
证书文件生成之后,需要在docker-compose.yaml 中添加新节点peer2.org1.flxdu.cn的配置信息,包括环境变量、映射的端口号、证书文件目录等信息。
修改后的 base/docker-compose.yaml 配置文件:
version: '3'
networks:
byfn:
services:
orderer.flxdu.cn:
container_name: orderer.flxdu.cn
image: hyperledger/fabric-orderer:2.4
restart: always
privileged: true
environment:
- ORDERER_GENERAL_LOGLEVEL=debug
- ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
- ORDERER_GENERAL_GENESISMETHOD=file
- ORDERER_GENERAL_GENESISFILE=/etc/hyperledger/configtx/genesis.block
- ORDERER_GENERAL_LOCALMSPID=OrdererMSP
- ORDERER_GENERAL_LOCALMSPDIR=/etc/hyperledger/msp/orderer/msp
volumes:
- ./configtx/genesis.block:/etc/hyperledger/configtx/genesis.block
- ./crypto-config/ordererOrganizations/orderers/orderer./msp:/etc/hyperledger/msp/orderer/msp
- ./var/orderer.flxdu.cn:/var/hyperledger/production/orderer
ports:
- "7050:7050"
command: orderer start
networks:
- byfn
cli:
container_name: cli
image: hyperledger/fabric-tools:2.4
tty: true
privileged: true
environment:
- GOPATH=/opt/gopath
- FABRIC_LOGGING_SPEC=DEBUG
- CORE_PEER_ID=cli
- CORE_CHAINCODE_KEEPALIVE=10
command: /bin/bash
volumes:
- ./chaincode:/opt/gopath/src/github.com
- ./crypto-config:/opt/crypto-config
- ./configtx:/opt/configtx
networks:
- byfn
peer0.org1.flxdu.cn:
container_name: peer0.org1.flxdu.cn
image: hyperledger/fabric-peer:2.4
privileged: true
environment:
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=${PROJECT_NAME}_byfn
- FABRIC_LOGGING_SPEC=INFO
- CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/peer/msp
- CORE_PEER_ID=peer0.org1.flxdu.cn
- CORE_PEER_ADDRESS=peer0.org1.flxdu.cn:7051
- CORE_PEER_LOCALMSPID=Org1MSP
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.flxdu.cn:7051
- CORE_PEER_GOSSIP_ORGLEADER=false
- CORE_PEER_GOSSIP_USELEADERELECTION=true
- CORE_PEER_GOSSIP_STATE_ENABLED=true
- CORE_CHAINCODE_NODE_RUNTIME=hyperledger/fabric-nodeenv:2.4
command: peer node start
volumes:
- /var/run/docker.sock:/host/var/run/docker.sock
- ./crypto-config/peerOrganizations/org1.flxdu.cn/peers/peer0.org1.flxdu.cn/msp:/etc/hyperledger/peer/msp
- ./var/peer0.org1.flxdu.cn:/var/hyperledger/production
ports:
- "7051:7051"
- "7053:7053"
networks:
- byfn
peer1.org1.flxdu.cn:
container_name: peer1.org1.flxdu.cn
image: hyperledger/fabric-peer:2.4
privileged: true
environment:
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=${PROJECT_NAME}_byfn
- FABRIC_LOGGING_SPEC=INFO
- CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/peer/msp
- CORE_PEER_ID=peer1.org1.flxdu.cn
- CORE_PEER_ADDRESS=peer1.org1.flxdu.cn:7051
- CORE_PEER_LOCALMSPID=Org1MSP
- CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org1.flxdu.cn:7051
- CORE_PEER_GOSSIP_ORGLEADER=false
- CORE_PEER_GOSSIP_USELEADERELECTION=true
- CORE_PEER_GOSSIP_STATE_ENABLED=true
- CORE_CHAINCODE_NODE_RUNTIME=hyperledger/fabric-nodeenv:2.4
command: peer node start
volumes:
- /var/run/docker.sock:/host/var/run/docker.sock
- ./crypto-config/peerOrganizations/org1.flxdu.cn/peers/peer1.org1.flxdu.cn/msp:/etc/hyperledger/peer/msp
- ./var/peer1.org1.flxdu.cn:/var/hyperledger/production
ports:
- "8051:7051"
- "8053:7053"
networks:
- byfn
peer2.org1.flxdu.cn:
container_name: peer2.org1.flxdu.cn
image: hyperledger/fabric-peer:2.4
privileged: true
environment:
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=${PROJECT_NAME}_byfn
- FABRIC_LOGGING_SPEC=INFO
- CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/peer/msp
- CORE_PEER_ID=peer2.org1.flxdu.cn
- CORE_PEER_ADDRESS=peer2.org1.flxdu.cn:7051
- CORE_PEER_LOCALMSPID=Org1MSP
- CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org1.flxdu.cn:7051
- CORE_PEER_GOSSIP_ORGLEADER=false
- CORE_PEER_GOSSIP_USELEADERELECTION=true
- CORE_PEER_GOSSIP_STATE_ENABLED=true
- CORE_CHAINCODE_NODE_RUNTIME=hyperledger/fabric-nodeenv:2.4
command: peer node start
volumes:
- /var/run/docker.sock:/host/var/run/docker.sock
- ./crypto-config/peerOrganizations/org1.flxdu.cn/peers/peer2.org1.flxdu.cn/msp:/etc/hyperledger/peer/msp
- ./var/peer2.org1.flxdu.cn:/var/hyperledger/production
ports:
- "11051:7051"
- "11053:7053"
networks:
- byfn
peer0.org2.flxdu.cn:
container_name: peer0.org2.flxdu.cn
image: hyperledger/fabric-peer:2.4
privileged: true
environment:
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=${PROJECT_NAME}_byfn
- FABRIC_LOGGING_SPEC=INFO
- CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/peer/msp
- CORE_PEER_ID=peer0.org2.flxdu.cn
- CORE_PEER_ADDRESS=peer0.org2.flxdu.cn:7051
- CORE_PEER_LOCALMSPID=Org2MSP
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org2.flxdu.cn:7051
- CORE_PEER_GOSSIP_ORGLEADER=false
- CORE_PEER_GOSSIP_USELEADERELECTION=true
- CORE_PEER_GOSSIP_STATE_ENABLED=true
- CORE_CHAINCODE_NODE_RUNTIME=hyperledger/fabric-nodeenv:2.4
command: peer node start
volumes:
- /var/run/docker.sock:/host/var/run/docker.sock
- ./crypto-config/peerOrganizations/org2.flxdu.cn/peers/peer0.org2.flxdu.cn/msp:/etc/hyperledger/peer/msp
- ./var/peer0.org2.flxdu.cn:/var/hyperledger/production
ports:
- "9051:7051"
- "9053:7053"
networks:
- byfn
peer1.org2.flxdu.cn:
container_name: peer1.org2.flxdu.cn
image: hyperledger/fabric-peer:2.4
privileged: true
environment:
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=${PROJECT_NAME}_byfn
- FABRIC_LOGGING_SPEC=INFO
- CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/peer/msp
- CORE_PEER_ID=peer1.org2.flxdu.cn
- CORE_PEER_ADDRESS=peer1.org2.flxdu.cn:7051
- CORE_PEER_LOCALMSPID=Org2MSP
- CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org2.flxdu.cn:7051
- CORE_PEER_GOSSIP_ORGLEADER=false
- CORE_PEER_GOSSIP_USELEADERELECTION=true
- CORE_PEER_GOSSIP_STATE_ENABLED=true
- CORE_CHAINCODE_NODE_RUNTIME=hyperledger/fabric-nodeenv:2.4
command: peer node start
volumes:
- /var/run/docker.sock:/host/var/run/docker.sock
- ./crypto-config/peerOrganizations/org2.flxdu.cn/peers/peer1.org2.flxdu.cn/msp:/etc/hyperledger/peer/msp
- ./var/peer1.org2.flxdu.cn:/var/hyperledger/production
ports:
- "10051:7051"
- "10053:7053"
networks:
- byfn
然后重新运行docker-compose.yaml文件
PROJECT_NAME=fabricdev docker-compose up -d
输出为
peer0.org2.flxdu.cn is up-to-date
peer1.org1.flxdu.cn is up-to-date
peer1.org2.flxdu.cn is up-to-date
cli is up-to-date
peer0.org1.flxdu.cn is up-to-date
orderer.flxdu.cn is up-to-date
Creating peer2.org1.flxdu.cn ... done
至此,新节点 peer2.org1.flxdu.cn 已经启动。
新节点加入通道
此时该节点并没有加入到任何一个通道中,需要使用cli容器执行添加操作。
从 orderer 上拉取通道的创世区块:
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/crypto-config/peerOrganizations/org1.flxdu.cn/users/Admin@org1.flxdu.cn/msp -e CORE_PEER_LOCALMSPID="Org1MSP" -e CORE_PEER_ADDRESS=peer2.org1.flxdu.cn:7051 cli peer channel fetch oldest hello.block -c hello -o orderer.flxdu.cn:7050
输出为
2022-01-15 19:16:07.645 UTC 001f INFO [cli.common] readBlock -> Received block: 0
加入通道:
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/crypto-config/peerOrganizations/org1.flxdu.cn/users/Admin@org1.flxdu.cn/msp -e CORE_PEER_LOCALMSPID="Org1MSP" -e CORE_PEER_ADDRESS=peer2.org1.flxdu.cn:7051 cli peer channel join -b hello.block -o orderer.flxdu.cn:7050
输出为
2022-01-15 19:19:00.131 UTC 001f INFO [channelCmd] executeJoin -> Successfully submitted proposal to join channel
安装链码
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/crypto-config/peerOrganizations/org1.flxdu.cn/users/Admin@org1.flxdu.cn/msp -e CORE_PEER_LOCALMSPID="Org1MSP" -e CORE_PEER_ADDRESS=peer2.org1.flxdu.cn:7051 cli peer lifecycle chaincode install /opt/gopath/src/github.com/sacc/sacc.tar.gz
同一个通道内所有节点只需要对同样的链码实例化一次即可,该链码已经在之前的旧有节点初始化一次,所以新节点安装完链码后并不需要再次实例化,直接可以对链码进行调用。
调用链码
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/crypto-config/peerOrganizations/org1.flxdu.cn/users/Admin@org1.flxdu.cn/msp -e CORE_PEER_LOCALMSPID="Org1MSP" -e CORE_PEER_ADDRESS=peer2.org1.flxdu.cn:7051 cli peer chaincode query -C hello -n sacc -c '{"Args":["query", "hello"]}'
可以看到输出成功即可,后续的设置/修改步骤也可以正常执行。