In this chapter we start with fabric v1.0 Of e2e_cli The example starts to analyze the whole startup process and some configuration files in the process

First of all , Or make sure your basic environment is set up ,v1.0 Source code and image are also downloaded

fabric Related script file parsing during startup

network_setup.sh Script files

In the source directory network_setup.sh The file is an automated script for the official rapid deployment test , Next, let's look at what we did when we started this file :  Insert picture description here In the figure above, we just intercepted the startup function , It can be clearly seen in this function that it was called in startup generateArtifacts.sh and docker-compose-cli.yaml Two documents , The functions of these two documents are respectively :

generateArtifacts.sh: Generate the required certificate (crypto-config Folder ) Channel related configuration files (channel-artifacts Folder )
docker-compose-cli.yaml: Describes the topology of this example network 

generateArtifacts.sh Script files

Let's continue to analyze in network_setup.sh Call in generateArtifacts.sh What does the document do stay generateArtifacts.sh There's a total of 3 A function :replacePrivateKey()、generateCerts() and generateChannelArtifacts() generateCerts():  Insert picture description here As you can see in the figure above, this function uses the tool cryptogen and crypto-config.yaml File to generate the required certificate file and public private key . We can have a look crypto-config.yaml file : Name and Domain Means the org Your name and domain name ,Template.Count Means the org Number of nodes in ,Users.Count Means the org It contains user Number .

OrdererOrgs:
  - Name: Orderer
    Domain: example.com
    Specs:
      - Hostname: orderer
# ---------------------------------------------------------------------------
PeerOrgs:
  - Name: Org1
    Domain: org1.example.com
    Template:
      Count: 2
    Users:
      Count: 1
  # ---------------------------------------------------------------------------
  - Name: Org2
    Domain: org2.example.com
    Template:
      Count: 2
    Users:
      Count: 1

generateChannelArtifacts():  Insert picture description here As you can see in the figure above, this function uses the tool configtxgen and configtx.yaml File to generate the genesis block and channel related configuration files . and configtx.yaml The file is mainly about org Configuration item information for , Such as ID、Host、Port etc. , In addition, it also points out that orderer The way to reach a consensus is solo And other basic configuration information .

docker-compose-cli.yaml Script files

docker-compose-cli.yaml The file describes the topology of the sample network , as follows , contain :

  • orderer:1 individual
  • org1:peer0( Anchor node ),peer1
  • org2:peer0( Anchor node ),peer1
  • cli: Manage the container nodes above
  • Why? cli It can manage the containers above ? because cli It is authorized by other nodes in the network , And the recognized certificate is the public and private key

#command: /bin/bash -c './scripts/script.sh ${CHANNEL_NAME}; sleep $TIMEOUT' The above line in the document was intentionally commented out by the author , send docker-compose-cli.yaml The file is not automatically executed when it is started script.sh Script , And this script is created automatically 、 Add automated scripts for channel and chain code related operations , And below , We're going to do it ourselves step by step , So as to deepen the understanding of fabric Understanding of the startup process .

version: '2'
services:
  orderer.example.com:
    extends:
      file:   base/docker-compose-base.yaml
      service: orderer.example.com
    container_name: orderer.example.com
  peer0.org1.example.com:
    container_name: peer0.org1.example.com
    extends:
      file:  base/docker-compose-base.yaml
      service: peer0.org1.example.com
  peer1.org1.example.com:
    container_name: peer1.org1.example.com
    extends:
      file:  base/docker-compose-base.yaml
      service: peer1.org1.example.com
  peer0.org2.example.com:
    container_name: peer0.org2.example.com
    extends:
      file:  base/docker-compose-base.yaml
      service: peer0.org2.example.com
  peer1.org2.example.com:
    container_name: peer1.org2.example.com
    extends:
      file:  base/docker-compose-base.yaml
      service: peer1.org2.example.com
  cli:
    container_name: cli
    image: hyperledger/fabric-tools
    tty: true
    environment:
      - GOPATH=/opt/gopath
      - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
      - CORE_LOGGING_LEVEL=DEBUG
      - CORE_PEER_ID=cli
      - CORE_PEER_ADDRESS=peer0.org1.example.com:7051
      - CORE_PEER_LOCALMSPID=Org1MSP
      - CORE_PEER_TLS_ENABLED=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 -c './scripts/script.sh ${CHANNEL_NAME}; sleep $TIMEOUT'
    volumes:
        - /var/run/:/host/var/run/
        - ../chaincode/go/:/opt/gopath/src/github.com/hyperledger/fabric/examples/chaincode/go
        - ./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

start-up e2e Example

Next, we'll actually start the official example :

Generate certificates and keys

First of all, let's go to the download fabric Source directory /root/go/src/github.com/hyperledger/fabric, perform make cryptogen command , Generate cryptogen Executable program , If there is an error , In the last part of the article, there are some mistakes that the author encountered , You can check it by yourself ;  Insert picture description here Next into cd examples/e2e_cli/ Directory execution ../../build/bin/cryptogen generate --config=./crypto-config.yaml, Will be generated in this directory crypto-config Folder , Store and generate public and private keys and certificates .  Insert picture description here

Generate Genesis blocks and channel related configuration files

Back to fabric Catalog , perform make configtxgen command , Generate configtxgen Executable program  Insert picture description here The next step is to enter cd examples/e2e_cli/ Catalog Generate Genesis block :

../../build/bin/configtxgen -profile TwoOrgsOrdererGenesis -outputBlock ./channel-artifacts/genesis.block

Generate channel related configuration files :

../../build/bin/configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID mychannel

Generate org1 and org2 Configuration file required by anchor node :

../../build/bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID mychannel -asOrg Org1MSP
../../build/bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID mychannel -asOrg Org2MSP

After executing the above order , Re execution tree channel-artifacts/( To be installed tree command yum install tree), You can see the directory structure of the file generated as shown in the figure below :  Insert picture description here

start-up

Everything you need to start up is ready , So let's start fabric The Internet

docker-compose -f docker-compose-cli.yaml up

Another terminal , perform docker ps, You can see the following figure , Launched the 1 individual orderer,4 individual peer( Belong to 2 individual org),1 individual cli  Insert picture description here

Create channels

Get into cli Containers :docker exec -it cli bash In order to facilitate our next operation , First set some environment variables :

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 CHANNEL_NAME=mychannel

Create channels :

peer channel create -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/channel.tx --tls true --cafile $ORDERER_CA

After executing the command, the system will print out the following figure , And will be in cli In the middle of 1 individual mychannel.block file , In the follow-up , Other nodes want to join the channel we created , You have to use this file .  Insert picture description here

Add node to channel

  • stay docker-compose-cli.yaml In fact, the file indicates that the default connection at startup is org1.peer0 node , So just add it to the channel
peer channel join -b $CHANNEL_NAME.block

The results are as follows :  Insert picture description here

  • Here we're just going to org1.peer0 The node has joined mychannel This passage , Again, we will org1.peer1 Nodes also join the channel , But here you need to modify the environment variables , Make it point to the node that we need to join the channel , Then add the node to the channel .
export CORE_PEER_LOCALMSPID="Org1MSP"
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_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin\@org1.example.com/msp
export CORE_PEER_ADDRESS=peer1.org1.example.com:7051
peer channel join -b $CHANNEL_NAME.block

The results are as follows :  Insert picture description here

  • take org2.peer0 Node join channel :
export CORE_PEER_LOCALMSPID="Org2MSP"
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_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin\@org2.example.com/msp
export CORE_PEER_ADDRESS=peer0.org2.example.com:7051
peer channel join -b $CHANNEL_NAME.block

The results are as follows :  Insert picture description here

  • take org2.peer1 Node join channel :
export CORE_PEER_LOCALMSPID="Org2MSP"
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_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin\@org2.example.com/msp
export CORE_PEER_ADDRESS=peer1.org2.example.com:7051
peer channel join -b $CHANNEL_NAME.block

The results are as follows :  Insert picture description here

Update anchor node

The function of anchor node is to facilitate organization (org) Communication between ,1 Organizations (org) You can have 1 One or more anchor nodes are responsible for communicating with other organizations , Then synchronize the results to other nodes . to update org1 The anchor node of org1.peer0, First connect to org1.peer0 Then perform the update

export CORE_PEER_LOCALMSPID="Org1MSP"
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_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin\@org1.example.com/msp
export CORE_PEER_ADDRESS=peer0.org1.example.com:7051
peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/Org1MSPanchors.tx --tls true --cafile $ORDERER_CA

to update org2 The anchor node of org2.peer0, First connect to org2.peer0 Then perform the update

export CORE_PEER_LOCALMSPID="Org2MSP"
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_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin\@org2.example.com/msp
export CORE_PEER_ADDRESS=peer0.org2.example.com:7051
peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/Org2MSPanchors.tx --tls true --cafile $ORDERER_CA

Deploy test chain code

In the last step, we have org1 and org2 Of 4 individual peer All of them are called mychannel This passage of the road , Next, we start to install the chain code , At this point, we are still connected after the last command is executed org2.pee1 node , Because the chain code installation did not generate transactions , Therefore, it will not affect other nodes in the channel , It can be said that chain code installation is actually a localized operation , therefore , If we want to call chain code in different nodes, , You need to install 4 Subchain code ( Because we only have 4 Nodes )

  • Installation chain code :
peer chaincode install -n mycc -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02

The results are as follows :  Insert picture description here

  • Instantiation chain code (-o: Appoint orderer The address of ) Chain code instantiation can be regarded as a special transaction , Chain code after a node is instantiated , Its information will be broadcast to all nodes in the channel , If there is another 1 If a node instantiates the chain code again, it will conflict .
peer chaincode instantiate -o orderer.example.com:7050 --tls true --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -v 1.0 -c '{"Args":["init", "a", "100", "b", "200"]}' -P "OR ('Org1MSP.member', 'Org2MSP.member')"

  • Call chain code In the above step, our chain code instantiation has been completed , At the beginning a Account 100 element ,b Account 200 element , Let's check a Balance of , Check it out
peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query", "a"]}'

The results are as follows :  Insert picture description here Next we call the chain code to make a to b Transfer accounts 50 element

peer chaincode invoke -o orderer.example.com:7050 --tls true --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -c '{"Args":["invoke", "a","b","50"]}'

The results are as follows :  Insert picture description here Now we need to be in another 1 Nodes org1.peer0 Query on org2.peer1 Whether the transaction on the node is successful You need to connect to org1.peer0 On , You need to install the chain code again , But there's no need to instantiate

export CORE_PEER_LOCALMSPID="Org1MSP"
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_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin\@org1.example.com/msp
export CORE_PEER_ADDRESS=peer0.org1.example.com:7051
peer chaincode install -n mycc -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02

After installing the chain code again, we call chain code query a Balance of

peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query", "a"]}'

The results are as follows :  Insert picture description here Finally, let's look at the running container , You can see the following :  Insert picture description here

<span id=" error "> error </span>

  1. perform make cryptogen If there is an error in the command  Insert picture description here Solution :yum install libtool-ltdl-devel  Insert picture description here

<br>

Finally , Explain , The author is also Xiaobai who just entered the pit , This article is to share my personal understanding , Easy to check later . If it helps you , With pleasure , If there's something wrong , Comments are welcome !