| 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