Using NodeJS to develop Hyperledger Fabric Note 2 - self-built test network

foreword

A supplement to the previous chapter: What if I don't want to test fabric in the root environment?

In fact, you only need to use the root account when creating and starting docker. Of course, because some files will be created when it is up, these files need to be delegated. First, transfer the files chownto ordinary users, or chmod -R 775, otherwise, follow-up non-root user operations Will be permission denied.

In addition, the previous chapter mainly refers to the official example of Hyperledger to try to start the network. Here I did some research, and tried to operate peer and channel through NodeJS API and fabric-client, but in the end I found it very inconvenient. Even if I use this API, I still need to use the official commands under the bin, for example You need to use cryptogen to create a node key configuration file. So after comprehensive consideration, I decided to hand over the network deployment and environment construction to the shell. Only the contract itself, and the logic to operate the contract are developed using typescript or javascript through nodejs.

general steps

Let's take a look at the steps required from docker startup to contract deployment in a regular Fabric network:
insert image description here

start

Create Organization and Orderer

Use cryptogen or ca to create organizations. If using cryptogen it is as follows:

Create an organization first, the organization node
is used here crypto-config-orgX.yamlto create an organization file, yaml please go to the official sample to find the file template

int=1
cryptogen generate --config=./organizations/cryptogen/crypto-config-org$int.yaml --output="organizations"

This can be flexible, int can be any integer, used to represent organizations 1, 2, 3, 4... you can create countless organizations

Create an order node

cryptogen generate --config=./organizations/cryptogen/crypto-config-orderer.yaml --output="organizations"

The org node and the order node have different responsibilities

  1. The orderer is called a sorting node, a network node that provides consensus services, for example, using Kafka or PBFT
  2. The peer maintains the network node of the ledger, and usually acts as an endorsement or bookkeeping role in Hyperledger Fabric.
  3. In addition, there is a comitter, which checks the legality of the transaction and finally submits the transaction to the blockchain.

start node

docker-compose docker-compose-test-net.yaml up -d

Docker configuration and startup needs to be handled by yourself. Here is a docker-compose template reference. fabric-sample/test-network/dockerThere are more detailed configuration files under the official

version: '2.4'

volumes:
  orderer.example.com:
  peer0.org1.example.com:

networks:
  test:
    name: fabric_test

services:

  orderer.example.com:
    container_name: orderer.example.com
    image: hyperledger/fabric-orderer:latest
    labels:
      service: hyperledger-fabric
    environment:
      - FABRIC_LOGGING_SPEC=INFO
      - ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
      - ORDERER_GENERAL_LISTENPORT=7050
      - 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
      - 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]
      - ORDERER_GENERAL_BOOTSTRAPMETHOD=none
      - ORDERER_CHANNELPARTICIPATION_ENABLED=true
      - ORDERER_ADMIN_TLS_ENABLED=true
      - ORDERER_ADMIN_TLS_CERTIFICATE=/var/hyperledger/orderer/tls/server.crt
      - ORDERER_ADMIN_TLS_PRIVATEKEY=/var/hyperledger/orderer/tls/server.key
      - ORDERER_ADMIN_TLS_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt]
      - ORDERER_ADMIN_TLS_CLIENTROOTCAS=[/var/hyperledger/orderer/tls/ca.crt]
      - ORDERER_ADMIN_LISTENADDRESS=0.0.0.0:16050
      - ORDERER_OPERATIONS_LISTENADDRESS=0.0.0.0:17050
    working_dir: /opt/gopath/src/github.com/hyperledger/fabric
    command: orderer
    volumes:
        - ../system-genesis-block/genesis.block:/var/hyperledger/orderer/orderer.genesis.block
        - ../organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp:/var/hyperledger/orderer/msp
        - ../organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/:/var/hyperledger/orderer/tls
        - orderer.example.com:/var/hyperledger/production/orderer
    ports:
      - 7050:7050
      - 16050:16050
      - 17050:17050
    networks:
      - test

  peer0.org1.example.com:
    container_name: peer0.org1.example.com
    image: hyperledger/fabric-peer:latest
    labels:
      service: hyperledger-fabric
    environment:
      #Generic peer variables
      - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
      - CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=fabric_test
      - FABRIC_LOGGING_SPEC=INFO
      #- FABRIC_LOGGING_SPEC=DEBUG
      - CORE_PEER_TLS_ENABLED=true
      - CORE_PEER_PROFILE_ENABLED=false
      - 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
      # Peer specific variables
      - 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
      - CORE_OPERATIONS_LISTENADDRESS=0.0.0.0:17051
    volumes:
        - ${
    
    DOCKER_SOCK}:/host/var/run/docker.sock
        - ../organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp:/etc/hyperledger/fabric/msp
        - ../organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls:/etc/hyperledger/fabric/tls
        - peer0.org1.example.com:/var/hyperledger/production
    working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
    command: peer node start
    ports:
      - 7051:7051
      - 17051:17051
    networks:
      - test

Note here that the organization encrypted file just cryptogencreated is mapped to the volumes of each node by docker, which is the identity file of each node. There are two examples here, one is order and the other is org.

Create channels

To create a channel, first create the genesis block of the channel. In fact, a channel of the fabric is a chain. However, I still feel that this step is too cumbersome. Can IBM provide the function of automatically creating the creation block?

Alright, let's create the genesis block:

CHANNEL_NAME=mychannel
configtxgen -profile ApplicationGenesis -outputBlock ./channel-artifacts/${CHANNEL_NAME}.block -channelID $CHANNEL_NAME

Then, let's create the channel:

export ORDERER_CA=${
    
    PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
export ORDERER_ADMIN_TLS_SIGN_CERT=${
    
    PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt
export ORDERER_ADMIN_TLS_PRIVATE_KEY=${
    
    PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.key
osnadmin channel join --channelID $CHANNEL_NAME --config-block ./channel-artifacts/${CHANNEL_NAME}.block -o localhost:16050 --ca-file "$ORDERER_CA" --client-cert "$ORDERER_ADMIN_TLS_SIGN_CERT" --client-key "$ORDERER_ADMIN_TLS_PRIVATE_KEY"

Creating a channel is actually adding the orderer node to the channel first, according to the channel creation block just created. This step is more interesting. Why is the orderer added to the channel first, and why is the command used osnadmin? The official did not find a reasonable explanation, so we put it aside for now.

join the channel

ORG=1
export CORE_PEER_LOCALMSPID="Org${ORG}MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${
    
    PWD}/organizations/peerOrganizations/org${ORG}.example.com/peers/peer0.org${ORG}.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${
    
    PWD}/organizations/peerOrganizations/org${ORG}.example.com/users/Admin@org${ORG}.example.com/msp
P0PORT=`expr 7049 + $ORG \* 2`
export CORE_PEER_ADDRESS=localhost:$P0PORT
BLOCKFILE="./channel-artifacts/${CHANNEL_NAME}.block"
peer channel join -b $BLOCKFILE

The above shell is to add org1 to the channel. Joining is the last line of script, but before that, you must set the ring variable to verify the identity of the node, which is actually "signing" to join.

set anchor node

Since the nodes themselves do not communicate with each other, to set other nodes anchored to the node, a function called setAnchorPeer is officially used to set the anchor node. I won’t go into details here, and the code is relatively long. Please refer to the scripts directory of the official sample. down setAnchorPeer.sh.

I personally think this step is very cumbersome. Why do you need to manually set the anchor node after setting the channel? Can the channel not provide a way for each node to communicate? I don't quite understand the operation of hyperledg.

The above is the minimum fabric network built, and the next chapter will talk about the deployment contract.

Guess you like

Origin blog.csdn.net/u014466109/article/details/119446294