PolarSPARC |
Setup Hyperledger Fabric 2.x Test Network (ARM64 Edition)
Bhaskar S | 09/18/2022 |
Overview
In the article Building Docker Images for Hyperledger Fabric 2.x, we demonstrated how one can build the docker images from the source.
In this article, we will use those same docker images to prove we can setup a test network on the 64-bit hex-core single board computer ODroid-N2 running Armbian 22.08 Jammy Linux OS.
Pre-requisites
Assuming that we are logged in as bswamina and the current working directory is the home directory /home/bswamina.
Also, we will assume that the host is using a static ip address and is set to 192.168.1.45 (one can pick their favorite).
We need to install the JSON processor cli jq by executing the following command:
$ sudo apt install jq -y
Next, it is time to clone the Hyperledger Fabric Samples source code that is distributed via the GIT repository - fabric-samples.
To clone the fabric-samples repository, execute the following command:
$ mkdir -p $HOME/hyperledger
$ cd $HOME/hyperledger
$ git clone https://github.com/hyperledger/fabric-samples.git
The following would be the typical output:
Cloning into 'fabric-samples'... remote: Enumerating objects: 10823, done. remote: Counting objects: 100% (164/164), done. remote: Compressing objects: 100% (132/132), done. remote: Total 10823 (delta 63), reused 102 (delta 29), pack-reused 10659 Receiving objects: 100% (10823/10823), 19.17 MiB | 14.35 MiB/s, done. Resolving deltas: 100% (5816/5816), done.
The test network setup is located under the directory $HOME/hyperledger/test-network.
The test network setup is coded in the main script network.sh, which invokes other scripts. We will IGNORE that script and instead invoke the various commands using just the docker images.
Ensure we have all the the Docker images by executing the following command:
$ docker images
The following would be the typical output:
REPOSITORY TAG IMAGE ID CREATED SIZE bswamina/fabric-tools 2.4.6 773fcf5b8132 6 minutes ago 469MB bswamina/fabric-peer 2.4.6 b9e6c7a86e29 11 minutes ago 50.2MB bswamina/fabric-orderer 2.4.6 25668ac89999 15 minutes ago 35.2MB bswamina/fabric-ccenv 2.4.6 7ade519a0116 19 minutes ago 530MB bswamina/fabric-baseos 2.4.6 d420699eef0d 20 minutes ago 6.56MB bswamina/fabric-ca 1.5.5 dc9e62641828 29 minutes ago 78.2MB
Setup
Now, it is time to setup the directory structure for our test network setup by executing the following commands:
$ cd $HOME
$ mkdir -p hlf_v2/config/peercfg
$ mkdir -p hlf_v2/docker
$ mkdir -p hlf_v2/channel-artifacts
Now, it is time to copy the appropriate configuration files by executing the following commands:
$ cd $HOME/hlf_v2
$ cp -R ../hyperledger/fabric-samples/test-network/organizations/ .
$ cp ../hyperledger/fabric-samples/test-network/compose/compose-test-net.yaml ./docker
$ cp ../hyperledger/fabric-samples/test-network/configtx/configtx.yaml ./config
$ cp ../hyperledger/fabric-samples/test-network/compose/docker/peercfg/core.yaml ./config/peercfg
The test network involves three participants - an Ordering entity (referred to as Orderer) and two Peer entities (referred to as Org1 and Org2 respectively).
Peers store the blockchain ledger and validate transactions before they are committed to the ledger. Peers run the smart contracts that contain the business logic that is used to manage the assets on the blockchain ledger.
The Ordering service allows peers to focus on validating transactions and committing them to the ledger. After ordering node(s) receive endorsed transactions from clients, they come to consensus on the order of transactions and then add them to blocks. The blocks are then distributed to the peer nodes, which add the blocks the blockchain ledger.
Hyperledger Fabric uses PKI to verify the actions of all the participants in the network. Every participant needs to have a public certificate and private key to verify their identity and has to be issued by an organization that is a member of the network.
In the directory $HOME/hlf_v2/organizations/cryptogen, we will find 3 configuration files crypto-config-orderer.yaml, crypto-config-org1.yaml, and crypto-config-org2.yaml for generating the crypto material for the 3 participants - orderer, org1, and org2.
We will need to modify the 3 yaml configurations files to fit our purpose.
The following is the modified crypto yaml file for the orderer:
# --------------------------------------------------------------------------- # "OrdererOrgs" - Definition of organizations managing orderer nodes # --------------------------------------------------------------------------- OrdererOrgs: - Name: Orderer Domain: example.com EnableNodeOUs: true Specs: - Hostname: orderer SANS: - "192.168.1.45"
The following is the modified crypto yaml file for the org1:
# --------------------------------------------------------------------------- # "PeerOrgs" - Definition of organizations managing peer nodes # --------------------------------------------------------------------------- PeerOrgs: - Name: Org1 Domain: org1.example.com EnableNodeOUs: true Template: Count: 1 SANS: - "192.168.1.45" # Start: 5 # Hostname: {{.Prefix}}{{.Index}} # default Users: Count: 1
The following is the modified crypto yaml file for the org2:
# --------------------------------------------------------------------------- # "PeerOrgs" - Definition of organizations managing peer nodes # --------------------------------------------------------------------------- PeerOrgs: - Name: Org2 Domain: org2.example.com EnableNodeOUs: true Template: Count: 1 SANS: - "192.168.1.45" # Start: 5 # Hostname: {{.Prefix}}{{.Index}} # default Users: Count: 1
To generate the crypto material for each of the 3 participants, we will need to use the cryptogen command from the bswamina/fabric-tools:2.4.6 docker image.
To generate the crypto material for the org1, execute the following command:
$ docker run --rm -u $(id -u ${USER}):$(id -g ${USER}) -v /home/bswamina/hlf_v2/organizations:/organizations bswamina/fabric-tools:2.4.6 /usr/local/bin/cryptogen generate --config=/organizations/cryptogen/crypto-config-org1.yaml --output="/organizations"
The following would be the typical output:
org1.example.com
Next, to generate the crypto material for the org2, execute the following command:
$ docker run --rm -u $(id -u ${USER}):$(id -g ${USER}) -v /home/bswamina/hlf_v2/organizations:/organizations bswamina/fabric-tools:2.4.6 /usr/local/bin/cryptogen generate --config=/organizations/cryptogen/crypto-config-org2.yaml --output="/organizations"
The following would be the typical output:
org2.example.com
Finally, to generate the crypto material for the orderer, execute the following command:
$ docker run --rm -u $(id -u ${USER}):$(id -g ${USER}) -v /home/bswamina/hlf_v2/organizations:/organizations bswamina/fabric-tools:2.4.6 /usr/local/bin/cryptogen generate --config=/organizations/cryptogen/crypto-config-orderer.yaml --output="/organizations"
There will be no output.
In the directory $HOME/hlf_v2/config/peercfg, is the shared configuration file called core.yaml used by the 2 peers - org1 and org2.
We will need to modify the peer yaml configuration file to fit our purpose.
The following is the modified peer yaml file for both org1 and org2:
############################################################################### # # Peer section # ############################################################################### peer: id: jdoe networkId: dev listenAddress: 0.0.0.0:7051 # The endpoint this peer uses to listen for inbound chaincode connections. # If this is commented-out, the listen address is selected to be # the peer's address (see below) with port 7052 # chaincodeListenAddress: 0.0.0.0:7052 # The endpoint the chaincode for this peer uses to connect to the peer. # If this is not specified, the chaincodeListenAddress address is selected. # And if chaincodeListenAddress is not specified, address is selected from # peer address (see below). If specified peer address is invalid then it # will fallback to the auto detected IP (local IP) regardless of the peer # addressAutoDetect value. # chaincodeAddress: 0.0.0.0:7052 address: 0.0.0.0:7051 addressAutoDetect: false gateway: enabled: true endorsementTimeout: 30s dialTimeout: 2m keepalive: interval: 7200s timeout: 20s minInterval: 60s client: interval: 60s timeout: 20s deliveryClient: interval: 60s timeout: 20s gossip: bootstrap: 127.0.0.1:7051 useLeaderElection: false orgLeader: true membershipTrackerInterval: 5s # Overrides the endpoint that the peer publishes to peers # in its organization. For peers in foreign organizations # see 'externalEndpoint' endpoint: maxBlockCountToStore: 10 maxPropagationBurstLatency: 10ms maxPropagationBurstSize: 10 propagateIterations: 1 propagatePeerNum: 3 pullInterval: 4s pullPeerNum: 3 requestStateInfoInterval: 4s publishStateInfoInterval: 4s stateInfoRetentionInterval: publishCertPeriod: 10s skipBlockVerification: false dialTimeout: 3s connTimeout: 2s recvBuffSize: 20 sendBuffSize: 200 digestWaitTime: 1s requestWaitTime: 1500ms responseWaitTime: 2s aliveTimeInterval: 5s aliveExpirationTimeout: 25s reconnectInterval: 25s maxConnectionAttempts: 120 msgExpirationFactor: 20 # This is an endpoint that is published to peers outside of the organization. # If this isn't set, the peer will not be known to other organizations. externalEndpoint: election: startupGracePeriod: 15s membershipSampleInterval: 1s leaderAliveThreshold: 10s leaderElectionDuration: 5s pvtData: pullRetryThreshold: 60s transientstoreMaxBlockRetention: 1000 pushAckTimeout: 3s btlPullMargin: 10 reconcileBatchSize: 10 reconcileSleepInterval: 1m reconciliationEnabled: true skipPullingInvalidTransactionsDuringCommit: false implicitCollectionDisseminationPolicy: requiredPeerCount: 0 maxPeerCount: 1 state: enabled: false checkInterval: 10s responseTimeout: 3s batchSize: 10 blockBufferSize: 20 maxRetries: 3 tls: enabled: false clientAuthRequired: false cert: file: tls/server.crt key: file: tls/server.key rootcert: file: tls/ca.crt clientRootCAs: files: - tls/ca.crt # Private key used for TLS when making client connections. # If not set, peer.tls.key.file will be used instead clientKey: file: # X.509 certificate used for TLS when making client connections. # If not set, peer.tls.cert.file will be used instead clientCert: file: authentication: timewindow: 15m fileSystemPath: /var/hyperledger/production BCCSP: Default: SW SW: Hash: SHA2 Security: 256 FileKeyStore: # If "", defaults to 'mspConfigPath'/keystore KeyStore: # Settings for the PKCS#11 crypto provider (i.e. when DEFAULT: PKCS11) PKCS11: # Location of the PKCS11 module library Library: # Token Label Label: # User PIN Pin: Hash: Security: # Path on the file system where peer will find MSP local configurations mspConfigPath: mspreally localMspId: SampleOrg client: # connection timeout connTimeout: 3s deliveryclient: blockGossipEnabled: true reconnectTotalTimeThreshold: 3600s connTimeout: 3s reConnectBackoffThreshold: 3600s # A list of orderer endpoint addresses which should be overridden # when found in channel configurations. addressOverrides: # - from: # to: # caCertsFile: # - from: # to: # caCertsFile: localMspType: bccsp profile: enabled: false listenAddress: 0.0.0.0:6060 handlers: authFilters: - name: DefaultAuth - name: ExpirationCheck # This filter checks identity x509 certificate expiration decorators: - name: DefaultDecorator endorsers: escc: name: DefaultEndorsement library: validators: vscc: name: DefaultValidation library: # library: /etc/hyperledger/fabric/plugin/escc.so # Number of goroutines that will execute transaction validation in parallel. # By default, the peer chooses the number of CPUs on the machine. Set this # variable to override that choice. # NOTE: overriding this value might negatively influence the performance of # the peer so please change this value only if you know what you're doing validatorPoolSize: discovery: enabled: true authCacheEnabled: true authCacheMaxSize: 1000 authCachePurgeRetentionRatio: 0.75 orgMembersAllowedAccess: false limits: concurrency: endorserService: 2500 deliverService: 2500 maxRecvMsgSize: 104857600 maxSendMsgSize: 104857600 vm: endpoint: unix:///var/run/docker.sock docker: tls: enabled: false ca: file: docker/ca.crt cert: file: docker/tls.crt key: file: docker/tls.key attachStdout: false hostConfig: NetworkMode: docker_default Dns: # - 192.168.0.1 LogConfig: Type: json-file Config: max-size: "50m" max-file: "5" Memory: 2147483648 chaincode: # The id is used by the Chaincode stub to register the executing Chaincode # ID with the Peer and is generally supplied through ENV variables # the `path` form of ID is provided when installing the chaincode. # The `name` is used for all other requests and can be any string. id: path: name: builder: bswamina/fabric-ccenv:2.4.6 pull: false golang: runtime: bswamina/fabric-baseos:2.4.6 dynamicLink: false externalBuilders: - name: ccaas_builder path: /opt/hyperledger/ccaas_builder propagateEnvironment: - CHAINCODE_AS_A_SERVICE_BUILDER_CONFIG installTimeout: 300s startuptimeout: 300s executetimeout: 30s mode: net keepalive: 0 system: _lifecycle: enable cscc: enable lscc: enable qscc: enable logging: level: info shim: info format: '%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}' ledger: blockchain: state: stateDatabase: goleveldb totalQueryLimit: 100000 couchDBConfig: couchDBAddress: 127.0.0.1:5984 # This username must have read and write authority on CouchDB username: # The password is recommended to pass as an environment variable password: maxRetries: 3 maxRetriesOnStartup: 10 requestTimeout: 35s internalQueryLimit: 1000 maxBatchUpdateSize: 1000 createGlobalChangesDB: false cacheSize: 64 history: enableHistoryDatabase: true pvtdataStore: collElgProcMaxDbBatchSize: 5000 collElgProcDbBatchesInterval: 1000 deprioritizedDataReconcilerInterval: 60m snapshots: rootDir: /var/hyperledger/production/snapshots operations: listenAddress: 127.0.0.1:9443 tls: enabled: false # path to PEM encoded server certificate for the operations server cert: file: # path to PEM encoded server key for the operations server key: file: clientAuthRequired: false # paths to PEM encoded ca certificates to trust for client authentication clientRootCAs: files: [] metrics: provider: disabled statsd: network: udp address: 127.0.0.1:8125 writeInterval: 10s # prefix is prepended to all emitted statsd metrics prefix:
Note that the NetworkMode: tag under vm: tag in the peer yaml file above MUST match the name of the docker network, which in our case is equal to docker_default.
The next step is to have the 3 participants (orderer, org1, and org2) up and running. For that we will modify and make use of the docker compose file compose-test-net.yaml located under the directory $HOME/hlf_v2/docker.
The following is the modified docker compose file:
version: '3.7' volumes: orderer.example.com: peer0.org1.example.com: peer0.org2.example.com: services: orderer.example.com: container_name: orderer.example.com image: bswamina/fabric-orderer:2.4.6 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 - 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_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:7053 - ORDERER_OPERATIONS_LISTENADDRESS=orderer.example.com:9443 - ORDERER_METRICS_PROVIDER=prometheus working_dir: /root command: orderer volumes: - /home/bswamina/hlf_v2/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp:/var/hyperledger/orderer/msp - /home/bswamina/hlf_v2/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/:/var/hyperledger/orderer/tls - orderer.example.com:/var/hyperledger/production/orderer ports: - "192.168.1.45:7050:7050" - "192.168.1.45:7053:7053" - "192.168.1.45:9443:9443" peer0.org1.example.com: container_name: peer0.org1.example.com image: bswamina/fabric-peer:2.4.6 labels: service: hyperledger-fabric environment: - FABRIC_CFG_PATH=/etc/hyperledger/peercfg - FABRIC_LOGGING_SPEC=INFO - 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 - 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_GOSSIP_BOOTSTRAP=peer0.org1.example.com:7051 - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051 - CORE_PEER_LOCALMSPID=Org1MSP - CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/msp - CORE_OPERATIONS_LISTENADDRESS=peer0.org1.example.com:9444 - CORE_METRICS_PROVIDER=prometheus - CORE_CHAINCODE_EXECUTETIMEOUT=300s - CORE_VM_ENDPOINT=unix:///var/run/docker.sock - CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=docker_default volumes: - /home/bswamina/hlf_v2/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com:/etc/hyperledger/fabric - /home/bswamina/hlf_v2/config/peercfg:/etc/hyperledger/peercfg - peer0.org1.example.com:/var/hyperledger/production - /var/run/docker.sock:/var/run/docker.sock working_dir: /root command: peer node start ports: - "192.168.1.45:7051:7051" - "192.168.1.45:9444:9444" peer0.org2.example.com: container_name: peer0.org2.example.com image: bswamina/fabric-peer:2.4.6 labels: service: hyperledger-fabric environment: - FABRIC_CFG_PATH=/etc/hyperledger/peercfg - FABRIC_LOGGING_SPEC=INFO - 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 - CORE_PEER_ID=peer0.org2.example.com - CORE_PEER_ADDRESS=peer0.org2.example.com:9051 - CORE_PEER_LISTENADDRESS=0.0.0.0:9051 - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org2.example.com:9051 - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org2.example.com:9051 - CORE_PEER_LOCALMSPID=Org2MSP - CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/msp - CORE_OPERATIONS_LISTENADDRESS=peer0.org2.example.com:9445 - CORE_METRICS_PROVIDER=prometheus - CORE_CHAINCODE_EXECUTETIMEOUT=300s - CORE_VM_ENDPOINT=unix:///var/run/docker.sock - CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=docker_default volumes: - /home/bswamina/hlf_v2/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com:/etc/hyperledger/fabric - /home/bswamina/hlf_v2/config/peercfg:/etc/hyperledger/peercfg - peer0.org2.example.com:/var/hyperledger/production - /var/run/docker.sock:/var/run/docker.sock working_dir: /root command: peer node start ports: - "192.168.1.45:9051:9051" - "192.168.1.45:9445:9445"
Note that the variables CORE_VM_ENDPOINT=unix:///var/run/docker.sock and CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=docker_default under the environment: tag as well as the volume mapping /var/run/docker.sock:/var/run/docker.sock under the volumes: tag (for the peer containers) in the docker compose file above are EXTREMELY IMPORTANT.
To bring up the 3 participants of the network (orderer, org1, and org2) using docker compose, execute the following command:
$ docker-compose -f docker/compose-test-net.yaml up
The following would be the typical output:
Creating peer0.org1.example.com ... done Creating orderer.example.com ... done Creating peer0.org2.example.com ... done Attaching to orderer.example.com, peer0.org2.example.com, peer0.org1.example.com orderer.example.com | 2022-09-17 19:59:13.902 UTC 0001 INFO [localconfig] completeInitialization -> Kafka.Version unset, setting to 0.10.2.0 orderer.example.com | 2022-09-17 19:59:13.903 UTC 0002 INFO [orderer.common.server] prettyPrintStruct -> Orderer config values: orderer.example.com | General.ListenAddress = "0.0.0.0" ------------ --- SNIP --- ------------ orderer.example.com | 2022-09-17 19:59:13.911 UTC 0003 INFO [orderer.common.server] initializeServerConfig -> Starting orderer with TLS enabled orderer.example.com | 2022-09-17 19:59:13.966 UTC 0004 INFO [orderer.commmon.multichannel] InitJoinBlockFileRepo -> Channel Participation API enabled, registrar initializing with file repo /var/hyperledger/production/orderer/pendingops orderer.example.com | 2022-09-17 19:59:13.973 UTC 0005 INFO [orderer.common.server] Main -> Starting without a system channel orderer.example.com | 2022-09-17 19:59:13.974 UTC 0006 INFO [orderer.common.server] Main -> Setting up cluster orderer.example.com | 2022-09-17 19:59:13.974 UTC 0007 INFO [orderer.common.server] reuseListener -> Cluster listener is not configured, defaulting to use the general listener on port 7050 orderer.example.com | 2022-09-17 19:59:13.974 UTC 0008 INFO [certmonitor] trackCertExpiration -> The enrollment certificate will expire on 2032-09-14 19:54:00 +0000 UTC orderer.example.com | 2022-09-17 19:59:13.974 UTC 0009 INFO [certmonitor] trackCertExpiration -> The server TLS certificate will expire on 2032-09-14 19:54:00 +0000 UTC orderer.example.com | 2022-09-17 19:59:13.975 UTC 000a INFO [certmonitor] trackCertExpiration -> The client TLS certificate will expire on 2032-09-14 19:54:00 +0000 UTC orderer.example.com | 2022-09-17 19:59:13.975 UTC 000b INFO [orderer.commmon.multichannel] InitJoinBlockFileRepo -> Channel Participation API enabled, registrar initializing with file repo /var/hyperledger/production/orderer/pendingops orderer.example.com | 2022-09-17 19:59:13.993 UTC 000c INFO [orderer.commmon.multichannel] startChannels -> Registrar initializing without a system channel, number of application channels: 0, with 0 consensus.Chain(s) and 0 follower.Chain(s) orderer.example.com | 2022-09-17 19:59:13.994 UTC 000d INFO [orderer.common.server] Main -> Starting orderer: orderer.example.com | Version: 2.4.6 orderer.example.com | Commit SHA: 8359607 orderer.example.com | Go version: go1.18.2 orderer.example.com | OS/Arch: linux/arm64 orderer.example.com | 2022-09-17 19:59:13.994 UTC 000e INFO [orderer.common.server] Main -> Beginning to serve requests peer0.org2.example.com | 2022-09-17 19:59:14.056 UTC 0001 INFO [nodeCmd] serve -> Starting peer: peer0.org2.example.com | Version: 2.4.6 peer0.org2.example.com | Commit SHA: 8359607 peer0.org2.example.com | Go version: go1.18.2 peer0.org2.example.com | OS/Arch: linux/arm64 peer0.org2.example.com | Chaincode: peer0.org2.example.com | Base Docker Label: org.hyperledger.fabric peer0.org2.example.com | Docker Namespace: hyperledger peer0.org2.example.com | 2022-09-17 19:59:14.056 UTC 0002 INFO [peer] getLocalAddress -> Auto-detected peer address: 172.19.0.4:9051 peer0.org2.example.com | 2022-09-17 19:59:14.057 UTC 0003 INFO [peer] getLocalAddress -> Returning peer0.org2.example.com:9051 peer0.org2.example.com | 2022-09-17 19:59:14.060 UTC 0004 INFO [nodeCmd] initGrpcSemaphores -> concurrency limit for endorser service is 2500 peer0.org2.example.com | 2022-09-17 19:59:14.061 UTC 0005 INFO [nodeCmd] initGrpcSemaphores -> concurrency limit for deliver service is 2500 peer0.org2.example.com | 2022-09-17 19:59:14.061 UTC 0006 INFO [nodeCmd] serve -> Starting peer with TLS enabled peer0.org1.example.com | 2022-09-17 19:59:14.078 UTC 0001 INFO [nodeCmd] serve -> Starting peer: peer0.org1.example.com | Version: 2.4.6 peer0.org1.example.com | Commit SHA: 8359607 peer0.org1.example.com | Go version: go1.18.2 peer0.org1.example.com | OS/Arch: linux/arm64 peer0.org1.example.com | Chaincode: peer0.org1.example.com | Base Docker Label: org.hyperledger.fabric peer0.org1.example.com | Docker Namespace: hyperledger peer0.org1.example.com | 2022-09-17 19:59:14.079 UTC 0002 INFO [peer] getLocalAddress -> Auto-detected peer address: 172.19.0.3:7051 peer0.org1.example.com | 2022-09-17 19:59:14.079 UTC 0003 INFO [peer] getLocalAddress -> Returning peer0.org1.example.com:7051 peer0.org1.example.com | 2022-09-17 19:59:14.082 UTC 0004 INFO [nodeCmd] initGrpcSemaphores -> concurrency limit for endorser service is 2500 peer0.org1.example.com | 2022-09-17 19:59:14.082 UTC 0005 INFO [nodeCmd] initGrpcSemaphores -> concurrency limit for deliver service is 2500 peer0.org1.example.com | 2022-09-17 19:59:14.082 UTC 0006 INFO [nodeCmd] serve -> Starting peer with TLS enabled peer0.org2.example.com | 2022-09-17 19:59:14.173 UTC 0007 INFO [certmonitor] trackCertExpiration -> The enrollment certificate will expire on 2032-09-14 19:54:00 +0000 UTC peer0.org2.example.com | 2022-09-17 19:59:14.173 UTC 0008 INFO [certmonitor] trackCertExpiration -> The server TLS certificate will expire on 2032-09-14 19:54:00 +0000 UTC peer0.org2.example.com | 2022-09-17 19:59:14.173 UTC 0009 INFO [ledgermgmt] NewLedgerMgr -> Initializing LedgerMgr peer0.org1.example.com | 2022-09-17 19:59:14.204 UTC 0007 INFO [certmonitor] trackCertExpiration -> The enrollment certificate will expire on 2032-09-14 19:54:00 +0000 UTC peer0.org1.example.com | 2022-09-17 19:59:14.204 UTC 0008 INFO [certmonitor] trackCertExpiration -> The server TLS certificate will expire on 2032-09-14 19:54:00 +0000 UTC peer0.org1.example.com | 2022-09-17 19:59:14.206 UTC 0009 INFO [ledgermgmt] NewLedgerMgr -> Initializing LedgerMgr peer0.org2.example.com | 2022-09-17 19:59:14.700 UTC 000a INFO [ledgermgmt] NewLedgerMgr -> Initialized LedgerMgr peer0.org2.example.com | 2022-09-17 19:59:14.703 UTC 000b INFO [gossip.service] New -> Initialize gossip with endpoint peer0.org2.example.com:9051 peer0.org2.example.com | 2022-09-17 19:59:14.705 UTC 000c INFO [gossip.gossip] New -> Creating gossip service with self membership of Endpoint: peer0.org2.example.com:9051, InternalEndpoint: peer0.org2.example.com:9051, PKI-ID: 1e9b9c3fe3222f84f92c45715d5ef7274e2f692ce52d2581e28bf57718820d0f, Metadata: peer0.org2.example.com | 2022-09-17 19:59:14.706 UTC 000d INFO [lifecycle] InitializeLocalChaincodes -> Initialized lifecycle cache with 0 already installed chaincodes peer0.org2.example.com | 2022-09-17 19:59:14.706 UTC 000e INFO [gossip.gossip] start -> Gossip instance peer0.org2.example.com:9051 started peer0.org2.example.com | 2022-09-17 19:59:14.707 UTC 000f INFO [nodeCmd] computeChaincodeEndpoint -> Entering computeChaincodeEndpoint with peerHostname: peer0.org2.example.com peer0.org2.example.com | 2022-09-17 19:59:14.707 UTC 0010 INFO [nodeCmd] computeChaincodeEndpoint -> Exit with ccEndpoint: peer0.org2.example.com:9052 peer0.org2.example.com | 2022-09-17 19:59:14.710 UTC 0011 INFO [sccapi] DeploySysCC -> deploying system chaincode 'lscc' peer0.org2.example.com | 2022-09-17 19:59:14.711 UTC 0012 INFO [sccapi] DeploySysCC -> deploying system chaincode 'cscc' peer0.org2.example.com | 2022-09-17 19:59:14.711 UTC 0013 INFO [sccapi] DeploySysCC -> deploying system chaincode 'qscc' peer0.org2.example.com | 2022-09-17 19:59:14.712 UTC 0014 INFO [sccapi] DeploySysCC -> deploying system chaincode '_lifecycle' peer0.org2.example.com | 2022-09-17 19:59:14.712 UTC 0015 INFO [nodeCmd] serve -> Deployed system chaincodes peer0.org2.example.com | 2022-09-17 19:59:14.713 UTC 0016 INFO [discovery] NewService -> Created with config TLS: true, authCacheMaxSize: 1000, authCachePurgeRatio: 0.750000 peer0.org2.example.com | 2022-09-17 19:59:14.714 UTC 0017 INFO [nodeCmd] serve -> Discovery service activated peer0.org2.example.com | 2022-09-17 19:59:14.714 UTC 0018 INFO [nodeCmd] serve -> Starting peer with Gateway enabled peer0.org2.example.com | 2022-09-17 19:59:14.714 UTC 0019 INFO [nodeCmd] serve -> Starting peer with ID=[peer0.org2.example.com], network ID=[dev], address=[peer0.org2.example.com:9051] peer0.org2.example.com | 2022-09-17 19:59:14.715 UTC 001a INFO [nodeCmd] serve -> Started peer with ID=[peer0.org2.example.com], network ID=[dev], address=[peer0.org2.example.com:9051] peer0.org2.example.com | 2022-09-17 19:59:14.715 UTC 001b INFO [kvledger] LoadPreResetHeight -> Loading prereset height from path [/var/hyperledger/production/ledgersData/chains] peer0.org2.example.com | 2022-09-17 19:59:14.715 UTC 001c INFO [blkstorage] preResetHtFiles -> No active channels passed peer0.org1.example.com | 2022-09-17 19:59:14.734 UTC 000a INFO [ledgermgmt] NewLedgerMgr -> Initialized LedgerMgr peer0.org1.example.com | 2022-09-17 19:59:14.736 UTC 000b INFO [gossip.service] New -> Initialize gossip with endpoint peer0.org1.example.com:7051 peer0.org1.example.com | 2022-09-17 19:59:14.738 UTC 000c INFO [gossip.gossip] New -> Creating gossip service with self membership of Endpoint: peer0.org1.example.com:7051, InternalEndpoint: peer0.org1.example.com:7051, PKI-ID: 7ff74306434339fbae00971a94f3242a8c2cc15aa3d9751cd459944f0c4e5d42, Metadata: peer0.org1.example.com | 2022-09-17 19:59:14.738 UTC 000d INFO [gossip.gossip] start -> Gossip instance peer0.org1.example.com:7051 started peer0.org1.example.com | 2022-09-17 19:59:14.738 UTC 000e INFO [lifecycle] InitializeLocalChaincodes -> Initialized lifecycle cache with 0 already installed chaincodes peer0.org1.example.com | 2022-09-17 19:59:14.740 UTC 000f INFO [nodeCmd] computeChaincodeEndpoint -> Entering computeChaincodeEndpoint with peerHostname: peer0.org1.example.com peer0.org1.example.com | 2022-09-17 19:59:14.740 UTC 0010 INFO [nodeCmd] computeChaincodeEndpoint -> Exit with ccEndpoint: peer0.org1.example.com:7052 peer0.org1.example.com | 2022-09-17 19:59:14.743 UTC 0011 INFO [sccapi] DeploySysCC -> deploying system chaincode 'lscc' peer0.org1.example.com | 2022-09-17 19:59:14.744 UTC 0012 INFO [sccapi] DeploySysCC -> deploying system chaincode 'cscc' peer0.org1.example.com | 2022-09-17 19:59:14.744 UTC 0013 INFO [sccapi] DeploySysCC -> deploying system chaincode 'qscc' peer0.org1.example.com | 2022-09-17 19:59:14.744 UTC 0014 INFO [sccapi] DeploySysCC -> deploying system chaincode '_lifecycle' peer0.org1.example.com | 2022-09-17 19:59:14.744 UTC 0015 INFO [nodeCmd] serve -> Deployed system chaincodes peer0.org1.example.com | 2022-09-17 19:59:14.744 UTC 0016 INFO [discovery] NewService -> Created with config TLS: true, authCacheMaxSize: 1000, authCachePurgeRatio: 0.750000 peer0.org1.example.com | 2022-09-17 19:59:14.745 UTC 0017 INFO [nodeCmd] serve -> Discovery service activated peer0.org1.example.com | 2022-09-17 19:59:14.745 UTC 0018 INFO [nodeCmd] serve -> Starting peer with Gateway enabled peer0.org1.example.com | 2022-09-17 19:59:14.745 UTC 0019 INFO [nodeCmd] serve -> Starting peer with ID=[peer0.org1.example.com], network ID=[dev], address=[peer0.org1.example.com:7051] peer0.org1.example.com | 2022-09-17 19:59:14.745 UTC 001a INFO [nodeCmd] serve -> Started peer with ID=[peer0.org1.example.com], network ID=[dev], address=[peer0.org1.example.com:7051] peer0.org1.example.com | 2022-09-17 19:59:14.745 UTC 001b INFO [kvledger] LoadPreResetHeight -> Loading prereset height from path [/var/hyperledger/production/ledgersData/chains] peer0.org1.example.com | 2022-09-17 19:59:14.745 UTC 001c INFO [blkstorage] preResetHtFiles -> No active channels passed
To list all the running Docker containers, execute the following command:
$ docker ps -a
The following would be the typical output:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8e7294be5f51 bswamina/fabric-peer:2.4.6 "peer node start" 44 seconds ago Up 42 seconds 192.168.1.45:7051->7051/tcp, 192.168.1.45:9444->9444/tcp peer0.org1.example.com a65cc4458fa7 bswamina/fabric-peer:2.4.6 "peer node start" 44 seconds ago Up 42 seconds 192.168.1.45:9051->9051/tcp, 7051/tcp, 192.168.1.45:9445->9445/tcp peer0.org2.example.com 7c331cdd627f bswamina/fabric-orderer:2.4.6 "orderer" 44 seconds ago Up 43 seconds 192.168.1.45:7050->7050/tcp, 192.168.1.45:7053->7053/tcp, 192.168.1.45:9443->9443/tcp orderer.example.com
The next step in the setup process is to create a Channel, which is a private layer for communication between participants in a network and is visible to only those members that have joined the channel.
In the directory $HOME/hlf_v2/config, we will find the yaml configuration file for a channel configtx.yaml.
We will need to modify the channel yaml configurations file to fit our purpose.
The following is the modified channel yaml file for our network:
################################################################################ # # Section: Organizations # # - This section defines the different organizational identities which will # be referenced later in the configuration. # ################################################################################ Organizations: - &OrdererOrg Name: OrdererOrg ID: OrdererMSP MSPDir: /hlf_v2/organizations/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: /hlf_v2/organizations/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')" - &Org2 Name: Org2MSP ID: Org2MSP MSPDir: /hlf_v2/organizations/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')" Capabilities: Channel: &ChannelCapabilities V2_0: true Orderer: &OrdererCapabilities V2_0: true Application: &ApplicationCapabilities V2_0: true Application: &ApplicationDefaults # Organizations is the list of orgs which are defined as participants on # the application side of the network 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: etcdraft Addresses: - orderer.example.com:7050 EtcdRaft: Consenters: - Host: orderer.example.com Port: 7050 ClientTLSCert: /hlf_v2/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt ServerTLSCert: /hlf_v2/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt BatchTimeout: 2s BatchSize: MaxMessageCount: 10 AbsoluteMaxBytes: 99 MB PreferredMaxBytes: 512 KB # Organizations is the list of orgs which are defined as participants on # the orderer side of the network 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: TwoOrgsApplicationGenesis: <<: *ChannelDefaults Orderer: <<: *OrdererDefaults Organizations: - *OrdererOrg Capabilities: *OrdererCapabilities Application: <<: *ApplicationDefaults Organizations: - *Org1 - *Org2 Capabilities: *ApplicationCapabilities
Before we can create the channel, we need to create a channel genesis block using the channel configuration.
To generate the channel genesis block, we will need to use the configtxgen command from the bswamina/fabric-tools:2.4.6 docker image.
To generate the channel genesis block for a channel called channel1, execute the following command:
$ docker run --rm -e FABRIC_CFG_PATH="/hlf_v2/config" -u $(id -u ${USER}):$(id -g ${USER}) -v /home/bswamina/hlf_v2:/hlf_v2 bswamina/fabric-tools:2.4.6 /usr/local/bin/configtxgen -profile TwoOrgsApplicationGenesis -outputBlock /hlf_v2/channel-artifacts/channel1.block -channelID channel1
The following would be the typical output:
2022-09-17 20:00:32.414 UTC 0001 INFO [common.tools.configtxgen] main -> Loading configuration 2022-09-17 20:00:32.444 UTC 0002 INFO [common.tools.configtxgen.localconfig] completeInitialization -> orderer type: etcdraft 2022-09-17 20:00:32.444 UTC 0003 INFO [common.tools.configtxgen.localconfig] completeInitialization -> Orderer.EtcdRaft.Options unset, setting to tick_interval:"500ms" election_tick:10 heartbeat_tick:1 max_inflight_blocks:5 snapshot_interval_size:16777216 2022-09-17 20:00:32.444 UTC 0004 INFO [common.tools.configtxgen.localconfig] Load -> Loaded configuration: /hlf_v2/config/configtx.yaml 2022-09-17 20:00:32.452 UTC 0005 INFO [common.tools.configtxgen] doOutputBlock -> Generating genesis block 2022-09-17 20:00:32.452 UTC 0006 INFO [common.tools.configtxgen] doOutputBlock -> Creating application channel genesis block 2022-09-17 20:00:32.453 UTC 0007 INFO [common.tools.configtxgen] doOutputBlock -> Writing genesis block
The next step in the setup of our network is to join the orderer to the channel channel1.
To join a participant to a channel, we will need to use the osnadmin command from the bswamina/fabric-tools:2.4.6 docker image.
To join the orderer to the channel channel1, execute the following command:
$ docker run --rm -u $(id -u ${USER}):$(id -g ${USER}) -v /home/bswamina/hlf_v2:/hlf_v2 bswamina/fabric-tools:2.4.6 /usr/local/bin/osnadmin channel join --channelID channel1 --config-block /hlf_v2/channel-artifacts/channel1.block -o 192.168.1.45:7053 --ca-file "/hlf_v2/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" --client-cert "/hlf_v2/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt" --client-key "/hlf_v2/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.key"
The following would be the typical output:
Status: 201 { "name": "channel1", "url": "/participation/v1/channels/channel1", "consensusRelation": "consenter", "status": "active", "height": 1 }
To list and verify the channels on the orderer, execute the following command:
$ docker run --rm -u $(id -u ${USER}):$(id -g ${USER}) -v /home/bswamina/hlf_v2:/hlf_v2 bswamina/fabric-tools:2.4.6 /usr/local/bin/osnadmin channel list -o 192.168.1.45:7053 --ca-file "/hlf_v2/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" --client-cert "/hlf_v2/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt" --client-key "/hlf_v2/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.key"
The following would be the typical output:
Status: 200 { "systemChannel": null, "channels": [ { "name": "channel1", "url": "/participation/v1/channels/channel1" } ] }
To join a peer to a channel, we will need to use the peer command from the bswamina/fabric-tools:2.4.6 docker image.
To join the peer org1 to the channel channel1, execute the following command:
$ docker run --rm -e FABRIC_CFG_PATH="/hlf_v2/config/peercfg" -e CORE_PEER_TLS_ENABLED=true -e CORE_PEER_LOCALMSPID="Org1MSP" -e CORE_PEER_TLS_ROOTCERT_FILE="/hlf_v2/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt" -e CORE_PEER_MSPCONFIGPATH="/hlf_v2/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp" -e CORE_PEER_ADDRESS="192.168.1.45:7051" -u $(id -u ${USER}):$(id -g ${USER}) -v /home/bswamina/hlf_v2:/hlf_v2 bswamina/fabric-peer:2.4.6 /usr/local/bin/peer channel join -b /hlf_v2/channel-artifacts/channel1.block
The following would be the typical output:
2022-09-17 22:40:56.624 UTC 0001 INFO [channelCmd] InitCmdFactory -> Endorser and orderer connections initialized 2022-09-17 22:40:56.726 UTC 0002 INFO [channelCmd] executeJoin -> Successfully submitted proposal to join channel
To join the peer org2 to the channel channel1, execute the following command:
$ docker run --rm -e FABRIC_CFG_PATH="/hlf_v2/config/peercfg" -e CORE_PEER_TLS_ENABLED=true -e CORE_PEER_LOCALMSPID="Org2MSP" -e CORE_PEER_TLS_ROOTCERT_FILE="/hlf_v2/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt" -e CORE_PEER_MSPCONFIGPATH="/hlf_v2/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp" -e CORE_PEER_ADDRESS="192.168.1.45:9051" -u $(id -u ${USER}):$(id -g ${USER}) -v /home/bswamina/hlf_v2:/hlf_v2 bswamina/fabric-peer:2.4.6 /usr/local/bin/peer channel join -b /hlf_v2/channel-artifacts/channel1.block
The following would be the typical output:
2022-09-17 22:45:03.655 UTC 0001 INFO [channelCmd] InitCmdFactory -> Endorser and orderer connections initialized 2022-09-17 22:45:03.753 UTC 0002 INFO [channelCmd] executeJoin -> Successfully submitted proposal to join channel
The next step in the setup of our network is to make both the peers org1 and org2 to become Anchor Peers, which ensure the different peers in the network know about each other.
We will have to go through a series of commands to achieve this goal.
To fetch the current channel configuration for peer org1, execute the following command:
$ docker run --rm -e FABRIC_CFG_PATH="/hlf_v2/config/peercfg" -e CORE_PEER_TLS_ENABLED=true -e CORE_PEER_LOCALMSPID="Org1MSP" -e CORE_PEER_TLS_ROOTCERT_FILE="/hlf_v2/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt" -e CORE_PEER_MSPCONFIGPATH="/hlf_v2/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp" -e CORE_PEER_ADDRESS="192.168.1.45:7051" -u $(id -u ${USER}):$(id -g ${USER}) -v /home/bswamina/hlf_v2:/hlf_v2 bswamina/fabric-peer:2.4.6 /usr/local/bin/peer channel fetch config /hlf_v2/channel-artifacts/channel1.block -o 192.168.1.45:7050 --ordererTLSHostnameOverride orderer.example.com -c channel1 --tls --cafile "/hlf_v2/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem"
The following would be the typical output:
2022-09-17 23:18:55.569 UTC 0001 INFO [channelCmd] InitCmdFactory -> Endorser and orderer connections initialized 2022-09-17 23:18:55.574 UTC 0002 INFO [cli.common] readBlock -> Received block: 0 2022-09-17 23:18:55.575 UTC 0003 INFO [channelCmd] fetch -> Retrieving last config block: 0 2022-09-17 23:18:55.578 UTC 0004 INFO [cli.common] readBlock -> Received block: 0
To update channel configuration to make peer org1 as an anchor peer, execute the following commands:
$ docker run --rm -u $(id -u ${USER}):$(id -g ${USER}) -v /home/bswamina/hlf_v2:/hlf_v2 bswamina/fabric-tools:2.4.6 /usr/local/bin/configtxlator proto_decode --input /hlf_v2/channel-artifacts/channel1.block --type common.Block --output /hlf_v2/channel-artifacts/config_block.json
$ jq .data.data[0].payload.data.config ./channel-artifacts/config_block.json > ./channel-artifacts/config.json
$ cp ./channel-artifacts/config.json ./channel-artifacts/config_copy.json
$ jq '.channel_group.groups.Application.groups.Org1MSP.values += {"AnchorPeers":{"mod_policy": "Admins","value":{"anchor_peers": [{"host": "peer0.org1.example.com","port": 7051}]},"version": "0"}}' ./channel-artifacts/config_copy.json > ./channel-artifacts/modified_config.json
$ docker run --rm -u $(id -u ${USER}):$(id -g ${USER}) -v /home/bswamina/hlf_v2:/hlf_v2 bswamina/fabric-tools:2.4.6 /usr/local/bin/configtxlator proto_encode --input /hlf_v2/channel-artifacts/config.json --type common.Config --output /hlf_v2/channel-artifacts/config.pb
$ docker run --rm -u $(id -u ${USER}):$(id -g ${USER}) -v /home/bswamina/hlf_v2:/hlf_v2 bswamina/fabric-tools:2.4.6 /usr/local/bin/configtxlator proto_encode --input /hlf_v2/channel-artifacts/modified_config.json --type common.Config --output /hlf_v2/channel-artifacts/modified_config.pb
$ docker run --rm -u $(id -u ${USER}):$(id -g ${USER}) -v /home/bswamina/hlf_v2:/hlf_v2 bswamina/fabric-tools:2.4.6 /usr/local/bin/configtxlator compute_update --channel_id channel1 --original /hlf_v2/channel-artifacts/config.pb --updated /hlf_v2/channel-artifacts/modified_config.pb --output /hlf_v2/channel-artifacts/config_update.pb
$ docker run --rm -u $(id -u ${USER}):$(id -g ${USER}) -v /home/bswamina/hlf_v2:/hlf_v2 bswamina/fabric-tools:2.4.6 /usr/local/bin/configtxlator proto_decode --input /hlf_v2/channel-artifacts/config_update.pb --type common.ConfigUpdate --output /hlf_v2/channel-artifacts/config_update.json
$ echo '{"payload":{"header":{"channel_header":{"channel_id":"channel1", "type":2}},"data":{"config_update":'$(cat ./channel-artifacts/config_update.json)'}}}' | jq . > ./channel-artifacts/config_update_in_envelope.json
$ docker run --rm -u $(id -u ${USER}):$(id -g ${USER}) -v /home/bswamina/hlf_v2:/hlf_v2 bswamina/fabric-tools:2.4.6 /usr/local/bin/configtxlator proto_encode --input /hlf_v2/channel-artifacts/config_update_in_envelope.json --type common.Envelope --output /hlf_v2/channel-artifacts/config_update_in_envelope.pb
$ docker run --rm -e FABRIC_CFG_PATH="/hlf_v2/config/peercfg" -e CORE_PEER_TLS_ENABLED=true -e CORE_PEER_LOCALMSPID="Org1MSP" -e CORE_PEER_TLS_ROOTCERT_FILE="/hlf_v2/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt" -e CORE_PEER_MSPCONFIGPATH="/hlf_v2/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp" -e CORE_PEER_ADDRESS="192.168.1.45:7051" -u $(id -u ${USER}):$(id -g ${USER}) -v /home/bswamina/hlf_v2:/hlf_v2 bswamina/fabric-peer:2.4.6 /usr/local/bin/peer channel update -f /hlf_v2/channel-artifacts/config_update_in_envelope.pb -c channel1 -o 192.168.1.45:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "/hlf_v2/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem"
A the end, the following would be the typical output:
2022-09-17 23:49:33.124 UTC 0001 INFO [channelCmd] InitCmdFactory -> Endorser and orderer connections initialized 2022-09-17 23:49:33.146 UTC 0002 INFO [channelCmd] update -> Successfully submitted channel update
Now To fetch the current channel configuration for peer org2, execute the following command:
$ docker run --rm -e FABRIC_CFG_PATH="/hlf_v2/config/peercfg" -e CORE_PEER_TLS_ENABLED=true -e CORE_PEER_LOCALMSPID="Org2MSP" -e CORE_PEER_TLS_ROOTCERT_FILE="/hlf_v2/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt" -e CORE_PEER_MSPCONFIGPATH="/hlf_v2/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp" -e CORE_PEER_ADDRESS="192.168.1.45:9051" -u $(id -u ${USER}):$(id -g ${USER}) -v /home/bswamina/hlf_v2:/hlf_v2 bswamina/fabric-peer:2.4.6 /usr/local/bin/peer channel fetch config /hlf_v2/channel-artifacts/channel1.block -o 192.168.1.45:7050 --ordererTLSHostnameOverride orderer.example.com -c channel1 --tls --cafile "/hlf_v2/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem"
The following would be the typical output:
2022-09-17 23:52:21.665 UTC 0001 INFO [channelCmd] InitCmdFactory -> Endorser and orderer connections initialized 2022-09-17 23:52:21.672 UTC 0002 INFO [cli.common] readBlock -> Received block: 1 2022-09-17 23:52:21.672 UTC 0003 INFO [channelCmd] fetch -> Retrieving last config block: 1 2022-09-17 23:52:21.675 UTC 0004 INFO [cli.common] readBlock -> Received block: 1
To update channel configuration to make peer org2 as an anchor peer, execute the following commands:
$ docker run --rm -u $(id -u ${USER}):$(id -g ${USER}) -v /home/bswamina/hlf_v2:/hlf_v2 bswamina/fabric-tools:2.4.6 /usr/local/bin/configtxlator proto_decode --input /hlf_v2/channel-artifacts/channel1.block --type common.Block --output /hlf_v2/channel-artifacts/config_block.json
$ jq .data.data[0].payload.data.config ./channel-artifacts/config_block.json > ./channel-artifacts/config.json
$ cp ./channel-artifacts/config.json ./channel-artifacts/config_copy.json
$ jq '.channel_group.groups.Application.groups.Org2MSP.values += {"AnchorPeers":{"mod_policy": "Admins","value":{"anchor_peers": [{"host": "peer0.org2.example.com","port": 9051}]},"version": "0"}}' ./channel-artifacts/config_copy.json > ./channel-artifacts/modified_config.json
$ docker run --rm -u $(id -u ${USER}):$(id -g ${USER}) -v /home/bswamina/hlf_v2:/hlf_v2 bswamina/fabric-tools:2.4.6 /usr/local/bin/configtxlator proto_encode --input /hlf_v2/channel-artifacts/config.json --type common.Config --output /hlf_v2/channel-artifacts/config.pb
$ docker run --rm -u $(id -u ${USER}):$(id -g ${USER}) -v /home/bswamina/hlf_v2:/hlf_v2 bswamina/fabric-tools:2.4.6 /usr/local/bin/configtxlator proto_encode --input /hlf_v2/channel-artifacts/modified_config.json --type common.Config --output /hlf_v2/channel-artifacts/modified_config.pb
$ docker run --rm -u $(id -u ${USER}):$(id -g ${USER}) -v /home/bswamina/hlf_v2:/hlf_v2 bswamina/fabric-tools:2.4.6 /usr/local/bin/configtxlator compute_update --channel_id channel1 --original /hlf_v2/channel-artifacts/config.pb --updated /hlf_v2/channel-artifacts/modified_config.pb --output /hlf_v2/channel-artifacts/config_update.pb
$ docker run --rm -u $(id -u ${USER}):$(id -g ${USER}) -v /home/bswamina/hlf_v2:/hlf_v2 bswamina/fabric-tools:2.4.6 /usr/local/bin/configtxlator proto_decode --input /hlf_v2/channel-artifacts/config_update.pb --type common.ConfigUpdate --output /hlf_v2/channel-artifacts/config_update.json
$ echo '{"payload":{"header":{"channel_header":{"channel_id":"channel1", "type":2}},"data":{"config_update":'$(cat ./channel-artifacts/config_update.json)'}}}' | jq . > ./channel-artifacts/config_update_in_envelope.json
$ docker run --rm -u $(id -u ${USER}):$(id -g ${USER}) -v /home/bswamina/hlf_v2:/hlf_v2 bswamina/fabric-tools:2.4.6 /usr/local/bin/configtxlator proto_encode --input /hlf_v2/channel-artifacts/config_update_in_envelope.json --type common.Envelope --output /hlf_v2/channel-artifacts/config_update_in_envelope.pb
$ docker run --rm -e FABRIC_CFG_PATH="/hlf_v2/config/peercfg" -e CORE_PEER_TLS_ENABLED=true -e CORE_PEER_LOCALMSPID="Org2MSP" -e CORE_PEER_TLS_ROOTCERT_FILE="/hlf_v2/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt" -e CORE_PEER_MSPCONFIGPATH="/hlf_v2/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp" -e CORE_PEER_ADDRESS="192.168.1.45:9051" -u $(id -u ${USER}):$(id -g ${USER}) -v /home/bswamina/hlf_v2:/hlf_v2 bswamina/fabric-peer:2.4.6 /usr/local/bin/peer channel update -f /hlf_v2/channel-artifacts/config_update_in_envelope.pb -c channel1 -o 192.168.1.45:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "/hlf_v2/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem"
A the end, the following would be the typical output:
2022-09-17 23:58:51.727 UTC 0001 INFO [channelCmd] InitCmdFactory -> Endorser and orderer connections initialized 2022-09-17 23:58:51.750 UTC 0002 INFO [channelCmd] update -> Successfully submitted channel update
Finally to verify the channel configuration has been updated, execute the following command:
$ docker run --rm -e FABRIC_CFG_PATH="/hlf_v2/config/peercfg" -e CORE_PEER_TLS_ENABLED=true -e CORE_PEER_LOCALMSPID="Org1MSP" -e CORE_PEER_TLS_ROOTCERT_FILE="/hlf_v2/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt" -e CORE_PEER_MSPCONFIGPATH="/hlf_v2/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp" -e CORE_PEER_ADDRESS="192.168.1.45:7051" -u $(id -u ${USER}):$(id -g ${USER}) -v /home/bswamina/hlf_v2:/hlf_v2 bswamina/fabric-peer:2.4.6 /usr/local/bin/peer channel getinfo -c channel1
The following would be the typical output:
2022-09-18 00:01:36.759 UTC 0001 INFO [channelCmd] InitCmdFactory -> Endorser and orderer connections initialized Blockchain info: {"height":3,"currentBlockHash":"YoOB6VhXpLEGggejUYcEgMP9tdIxeVx3AFT1YFZ+wbM=","previousBlockHash":"CQgisfZHcDoH7GcSCKGlbEBBOfMVGp3fDFtgTtYbcQ8="}
BINGO !!! We have successfully demonstrated the setup of the test network using our custom build Hyperledger Fabric docker images for the arm64 platform.
References