Novices are new to hyperledger fabric, so record the environment configuration process and step on a lot of pitfalls, so it is only a record rather than a tutorial ~
Reference tutorial Hyperledger Fabric multi-machine construction- Hyperledger Fabric
System environment: ubuntu64-bit virtual machine (virtual machine 1, virtual machine 2), raspio64-bit (raspberry pie)
It is planned to build three organizations, each with a node, and the specific allocation is as follows:
name | IP | hosts | organizational structure | the host |
orderer | 192.168.50.120 | orderer.example.com | orderer | virtual machine 1 |
org1peer0 | 192.168.50.232 | peer0.org1.example.com | org1 | virtual machine 2 |
org2peer0 | 192.168.50.46 | peer0.org2.example.com | org2 | raspberry pie |
Preparation
1. Configure hosts:
Add the host IP to host mapping at the end of the /etc/hosts file (each host IP needs to be in the same network segment, you must pay attention to the modification when switching wifi, sometimes the response of the Raspberry Pi system is slower, refresh several times to ensure the IP No problem, make sure the hosts can ping each other).
192.168.50.120 orderer.example.com
192.168.50.232 peer0.org1.example.com
192.168.50.46 peer0.0rg2.example.com
2. ssh configuration
In the process of building multiple machines, we will use scp
commands. Linux scp
commands are used to copy files and directories between Linux.
scp
It is the abbreviation secure copy
of , scp
which is a secure remote file copy command based on ssh login under Linux system. The three hosts need to install the ssh command in advance.
Generate Fabric certificate
1. Write a certificate
First, create project directories in the three hosts (it can be different, just remember), copy the template file crypto-config.yaml of fabric-samples to the project directory, and modify it to the following content:
OrdererOrgs:
- Name: Orderer
Domain: example.com
EnableNodeOUs: true
Specs:
- Hostname: orderer
PeerOrgs:
- Name: org1
Domain: org1.example.com
EnableNodeOUs: true
Template:
Count: 1
Users:
Count: 1
- Name: org2
Domain: org2.example.com
EnableNodeOUs: true
Template:
Count: 1
Users:
Count: 1
2. Generate a certificate file
Terminal enters the project directory and generates it using the following command:
cryptogen generate --config=crypto-config.yaml
Then the crypto-config folder appears in the directory, which stores all the certificate files of the above three nodes. Copy the file to the other two hosts through the scp command:
scp -r ./crypto-config [email protected]:[该主机项目目录的绝对路径]
scp -r ./crypto-config [email protected]:[该主机项目目录的绝对路径]
Generate channel file
1. Write the genesis file block
Enter virtual machine 1, copy the configtx.yaml in the official sample test-network to the project directory, and modify it as follows:
---
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')"
OrdererEndpoints:
- orderer.example.com:7050
- &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')"
Endorsement:
Type: Signature
Rule: "OR('Org1MSP.peer')"
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')"
Endorsement:
Type: Signature
Rule: "OR('Org2MSP.peer')"
AnchorPeers:
- Host: peer0.org2.example.com
Port: 9051
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
Orderer: &OrdererDefaults
OrdererType: solo
Addresses:
- orderer.example.com:7050
EtcdRaft:
Consenters:
- Host: orderer.example.com
Port: 7050
ClientTLSCert: ../organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt
ServerTLSCert: ../organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt
BatchTimeout: 2s
BatchSize:
MaxMessageCount: 10
AbsoluteMaxBytes: 99 MB
PreferredMaxBytes: 512 KB
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
<<: *ChannelDefaults
Application:
<<: *ApplicationDefaults
Organizations:
- *Org1
- *Org2
Capabilities:
<<: *ApplicationCapabilities
2. Generate genesis block file and channel file
Generate the genesis block with the following command:
configtxgen -profile TwoOrgsOrdererGenesis -channelID fabric-channel -outputBlock ./channel-artifacts/genesis.block
Generate channel files:
configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID mychannel
Define anchor nodes for org1 and org2 respectively:
configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID mychannel -asOrg Org1MSP
configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID mychannel -asOrg Org2MSP
Copy the generated file to the other two hosts using the following command:
scp -r ./channel-artifacts [email protected]:[项目绝对路径]
scp -r ./channel-artifacts [email protected]:[项目绝对路径]
Write docker-compose file
1.orderer
Create a docker-compose.yaml file in the virtual machine 1 project directory and modify it to the following content:
version: '2'
services:
orderer.example.com:
container_name: orderer.example.com
image: hyperledger/fabric-orderer:latest
environment:
- FABRIC_LOGGING_SPEC=INFO
- ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
- ORDERER_GENERAL_LISTENPORT=7050
- 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=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
- ORDERER_GENERAL_CLUSTER_CLIENTCERTIFICATE=/var/hyperledger/orderer/tls/server.crt
- ORDERER_GENERAL_CLUSTER_CLIENTPRIVATEKEY=/var/hyperledger/orderer/tls/server.key
- ORDERER_GENERAL_CLUSTER_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt]
working_dir: /opt/gopath/src/github.com/hyperledger/fabric
command: orderer
volumes:
- ./channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block
- ./crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/msp:/var/hyperledger/orderer/msp
- ./crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/:/var/hyperledger/orderer/tls
ports:
- 7050:7050
extra_hosts:
- "orderer.example.com:192.168.50.120"
- "peer0.org1.example.com:192.168.50.232"
- "peer0.org2.example.com:192.168.50.46"
Extra_hosts can be modified to the mapping of the actual experimental environment.
2.org1
Create the same as above, the file content is as follows:
version: '2'
services:
couchdb0.org1.example.com:
container_name: couchdb0.org1.example.com
image: couchdb:3.1
environment:
- COUCHDB_USER=admin
- COUCHDB_PASSWORD=adminpw
ports:
- 5984:5984
peer0.org1.example.com:
container_name: peer0.org1.example.com
image: hyperledger/fabric-peer:latest
environment:
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_PEER_ID=peer0.org1.example.com
- CORE_PEER_ADDRESS=peer0.org1.example.com:7051
- CORE_PEER_LISTENADDRESS=0.0.0.0:7051
- CORE_PEER_CHAINCODEADDRESS=peer0.org1.example.com:7052
- CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052
- CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org1.example.com:7051
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051
- CORE_PEER_LOCALMSPID=Org1MSP
- FABRIC_LOGGING_SPEC=INFO
- 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_CHAINCODE_EXECUTETIMEOUT=300s
- CORE_LEDGER_STATE_STATEDATABASE=CouchDB
- CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb0.org1.example.com:5984
- CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=admin
- CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=adminpw
depends_on:
- couchdb0.org1.example.com
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
ports:
- 7051:7051
- 7052:7052
- 7053:7053
extra_hosts:
- "orderer.example.com:192.168.50.120"
- "peer0.org1.example.com:192.168.50.232"
- "peer0.org2.example.com:192.168.50.46"
cli:
container_name: cli
image: hyperledger/fabric-tools:latest
tty: true
stdin_open: true
environment:
- GOPATH=/opt/gopath
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- 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/go/:/opt/gopath/src/github.com/hyperledger/fabric-cluster/chaincode/go
- ./crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
- ./channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts
extra_hosts:
- "orderer.example.com:192.168.50.120"
- "peer0.org1.example.com:192.168.50.232"
- "peer0.org2.example.com:192.168.50.46"
3.org2
Since the org2 node is located in the Raspberry Pi system, raspios is an arm64 architecture, and the docker images used by peer, cli, and couchdb in the configuration file of the org1 node do not support the arm64 architecture, and the following error will appear in the server window during actual operation:
Therefore, it is necessary to pull an image that supports the arm64 architecture. My docker-compose file is written as follows:
version: '2'
services:
couchdb0.org2.example.com:
container_name: couchdb0.org2.example.com
image: busan15/fabric-couchdb
environment:
- COUCHDB_USER=admin
- COUCHDB_PASSWORD=adminpw
ports:
- 5984:5984
peer0.org2.example.com:
container_name: peer0.org2.example.com
image: busan15/fabric-peer
environment:
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_PEER_ID=peer0.org2.example.com
- CORE_PEER_ADDRESS=peer0.org2.example.com:7051
- CORE_PEER_LISTENADDRESS=0.0.0.0:7051
- CORE_PEER_CHAINCODEADDRESS=peer0.org2.example.com:7052
- CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052
- CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org2.example.com:7051
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org2.example.com:7051
- CORE_PEER_LOCALMSPID=Org2MSP
- FABRIC_LOGGING_SPEC=INFO
- 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_CHAINCODE_EXECUTETIMEOUT=300s
- CORE_LEDGER_STATE_STATEDATABASE=CouchDB
- CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb0.org2.example.com:5984
- CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=admin
- CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=adminpw
depends_on:
- couchdb0.org2.example.com
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
ports:
- 7051:7051
- 7052:7052
- 7053:7053
extra_hosts:
- "orderer.example.com:192.168.50.120"
- "peer0.org1.example.com:192.168.50.232"
- "peer0.org2.example.com:192.168.50.46"
cli:
container_name: cli
image: busan15/fabric-tools
tty: true
stdin_open: true
environment:
- GOPATH=/opt/gopath
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- FABRIC_LOGGING_SPEC=INFO
- CORE_PEER_ID=cli
- CORE_PEER_ADDRESS=peer0.org2.example.com:7051
- CORE_PEER_LOCALMSPID=Org2MSP
- CORE_PEER_TLS_ENABLED=true
- CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/server.crt
- CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/server.key
- 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
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: /bin/bash
volumes:
- /var/run/:/host/var/run/
- ./chaincode/go/:/opt/gopath/src/github.com/hyperledger/fabric-cluster/chaincode/go
- ./crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
- ./channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts
extra_hosts:
- "orderer.example.com:192.168.50.120"
- "peer0.org1.example.com:192.168.50.232"
- "peer0.org2.example.com:192.168.50.46"
After the above operations are completed, use the docker-compose up command to start the service in the project directory of the three hosts.
channel operation
1. Create a channel
Enter virtual machine 2, docker exec -it cli bash to enter the container, use the following command to create a channel:
peer channel create -o orderer.example.com:7050 -c mychannel -f ./channel-artifacts/channel.tx --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/msp/tlscacerts/tlsca.example.com-cert.pem
This step may report an error:
It may be an IP mapping problem. Check whether the IP has been modified, and then regenerate the certificate and channel file.
Copy the channel file to the virtual machine 2 host:
docker cp cli:/opt/gopath/src/github.com/hyperledger/fabric/peer/mychannel.block ./
Copy to Raspberry Pi:
scp mychannel.block [email protected]:[项目目录绝对路径]
Copy to cli on Raspberry Pi:
docker cp mychannel.block cli:/opt/gopath/src/github.com/hyperledger/fabric/peer/
2. Join the channel
On virtual machine 2 and Raspberry Pi, add peer0 to the channel through the following command:
peer channel join -b mychannel.block
When the org2 of the Raspberry Pi joins the channel, an error may be reported:
The reason is that there is a problem with the couchdb image, which may not be suitable for the arm64 architecture, which can be resolved by replacing the image source in docker-compose.
Update the anchor nodes org1 and org2:
peer channel update -o orderer.example.com:7050 -c mychannel -f ./channel-artifacts/Org1MSPanchors.tx --tls --cafile /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 update -o orderer.example.com:7050 -c mychannel -f ./channel-artifacts/Org2MSPanchors.tx --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
This step may result in the following error:
I checked for a long time. . Finally, it was found that the network connection method of the virtual machine was wrong, and it should be changed to bridge mode. . After the change is completed, you need to re-modify the IP mapping, reconfirm that the three hosts can ping their respective hosts, and then start the configuration from scratch.
Install and call the smart contract
I originally used the official sample chain code sacc, but it failed to run in the end, and then I tried fabcar to run without any problem, but I will record it first.
Copy the smart contract sacc to the chaincode/go/ folder and enter the container:
docker exec -it cli bash
Enter the directory where the chaincode is located:
cd /opt/gopath/src/github.com/hyperledger/fabric-cluster/chaincode/go/sacc
Set the go language dependency package (otherwise an error may be reported and timed out):
go env -w GOPROXY=https://goproxy.cn,direct
go mod vendor
Back to the peer directory:
cd /opt/gopath/src/github.com/hyperledger/fabric/peer
Life cycle command packaging chain code:
peer lifecycle chaincode package sacc.tar.gz --path [链码目录的绝对路径] --label sacc_1
Note that --path is followed by an absolute path, so that it is not easy to report errors.
Exit the container and copy the packaged chaincode to the virtual machine 2 host:
docker cp cli:/opt/gopath/src/github.com/hyperledger/fabric/peer/sacc.tar.gz [项目目录绝对路径]
Copy scp to the Raspberry Pi host:
scp sacc.tar.gz [email protected]:[项目目录绝对路径]
Copy the chaincode to the container on the Raspberry Pi
docker cp [链码所在的本地绝对路径] cli:/opt/gopath/src/github.com/hyperledger/fabric/peer
Install the chain code on the two hosts separately:
peer lifecycle chaincode install sacc.tar.gz
Another error:
It is speculated that it is a problem with the chaincode sacc itself. The arm64 version of the ccenv image was pulled, but it is not yet known how to specify the chaincode install command to run under the new ccenv image, and then use the chaincode fabcar to experiment first.
Install fabcar:
peer lifecycle chaincode install fabcar.tar.gz
Query (two hosts):
peer lifecycle chaincode queryinstalled
Approve chaincode (both hosts):
peer lifecycle chaincode approveformyorg --channelID mychannel --name fabcar --version 1.0 --init-required --package-id sacc_1:1d9838e6893e068a94f055e807b18289559af748e5196a79a640b66305a74428 --sequence 1 --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
Check if ready (two hosts):
peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name fabcar --version 1.0 --init-required --sequence 1 --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 --output json
It is ok to show that both organizations are "true"!
Submit chaincode (one host):
peer lifecycle chaincode commit -o orderer.example.com:7050 --channelID mychannel --name fabcar --version 1.0 --sequence 1 --init-required --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 --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
Initialize the chaincode fabcar:
peer chaincode invoke -o orderer.example.com:7050 --isInit --ordererTLSHostnameOverride orderer.example.com --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 fabcar --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 '{"function":"initLedger","Args":[]}'
There was an error:
I looked at the server window and found that the container of the chaincode fabcar exited automatically while submitting the chaincode? ? After re-creating the channel and reconfiguring it, the container will automatically exit at this step. After working all night, I don’t know where the problem is. Finally, I changed the wifi and modified the IPs of the three hosts. This problem has never occurred again since I started the configuration from the beginning. . . . Anyway, I still don't understand where the problem is. . .
Call "queryAllCars":
peer chaincode query -C mychannel -n fabcar -c '{"Args":["queryAllCars"]}'
org1 result:
org2 result:
Debugging succeeded!