Add a Peer to an Organization in Test Network (Hyperledger Fabric v2.2)


Test Network comes as a sample network since Fabric v2.0, and in v2.2 we see a more comprehensive set of scripts for flexible channel creation and chaincode deployment. Test Network architecture is very simple, a three-organization network setup, one for ordering service and two for peer organizations. Inside each peer organization we have one peer and an optional CA.

Test Network

While it is good and basic enough for testing channel and chaincode, it does not give us some network architectures for learning or testing purposes. For example, if we wish to take a look at the high availability behaviour inside an organization, we need one more peer. Thanks to the CA option, we can easily add additional peers on the existing network and join it to an existing channel.

Our goal is to add a peer in Org1 in this article.

In this article we will show the steps needed to bring up a new peer for an organization and join it to an existing channel. We will explore what happens when this peer joins a network and when chaincode is installed in this peer.

Examine the Flow in Test Network Script

Test Network script provides a simple and logical process for bringing up a network, creation of channel and deployment of chaincode. We will examine this script.

Process of Adding a New Peer

Assuming the network is running and application chaincode is deployed for use. We are going to add a to Org1. The objective is that this new peer will be part of the channel, and able to process chaincode query and endorsement when needed.

The steps we need to walk through are

  • Step 2: generate crypto material for
  • Step 4: create a docker compose file containing this peer
  • Step 5c: join this new peer to the existing channel
  • Step 6b: install chaincode to that peer

There are two ways to generate crypto material in Test Network: cryptogen and Fabric CA. As we are generating additional material, it is more desirable to use Fabric CA. This is a more standard and operable way to generate new components or new users for an organization. As a result we are using -ca option when bringing up the network, in which Fabric CA servers are brought up.

Besides, step 6c and 6d are not needed. Approving and committing chaincode are done at organization level, not peer level.


Step 0: Preparation

We need a fabric host with Fabric v2.2 installed. For demonstration we also prepare two terminals, one with setting for Org1 ( and one with setting for Org2 (

Terminal for Org1
Terminal for Org2

Step 1: Bring up Test Network

We use script to bring up the Test Network and mychannel (steps 1–5 in the previous session).

cd fabric-samples/test-network/
./ up createChannel -ca

Total six containers are running:

  • 3 CAs, one for each organization
  • 1 orderer
  • 2 peers, one for Org1 and one for Org2

Step 2: Deploy chaincode SACC

We also use to deploy sacc (step 6 in previous session).

cd fabric-samples/test-network/
./ up deployCC -ccn mycc -ccp ../chaincode/sacc

After deployment, we take a look on the output of service discovery about endorsement. We see endorsing policy requires both organizations, and each organization has one peer currently. We will see this again after we complete the addition of

Output of service discovery after Test Network script is executed.

Step 3: Test chaincode

After deployment we perform an invoke and query from both peers.

peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride --tls true --cafile $ORDERER_CA -C mychannel -n mycc --peerAddresses localhost:7051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/ --peerAddresses localhost:9051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/ -c '{"Args":["set","name","Alice"]}'peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'

Invoke from Org1

Query from both Org1 and Org2. And we see the same state value for asset name. The network is running well.

Terminal for Org1
Terminal for Org2

Step 4: Generate crypto material for new peer

Use CA of Org1 to generate crypto material for (step 2 in previous session). Here we largely follow the script ./organizations/fabric-ca/ For a detailed description you can refer to the script file, and read my previous article (second part).

export PATH=$PATH:${PWD}/../bin
export FABRIC_CA_CLIENT_HOME=${PWD}/organizations/peerOrganizations/
fabric-ca-client register --caname ca-org1 peer1 --id.secret peer1pw --id.type peer --tls.certfiles ${PWD}/organizations/fabric-ca/org1/tls-cert.pemmkdir -p organizations/peerOrganizations/ enroll -u https://peer1:peer1pw@localhost:7054 --caname ca-org1 -M ${PWD}/organizations/peerOrganizations/ --csr.hosts --tls.certfiles ${PWD}/organizations/fabric-ca/org1/tls-cert.pemcp ${PWD}/organizations/peerOrganizations/ ${PWD}/organizations/peerOrganizations/ enroll -u https://peer1:peer1pw@localhost:7054 --caname ca-org1 -M ${PWD}/organizations/peerOrganizations/ --enrollment.profile tls --csr.hosts --csr.hosts localhost --tls.certfiles ${PWD}/organizations/fabric-ca/org1/tls-cert.pemcp ${PWD}/organizations/peerOrganizations/* ${PWD}/organizations/peerOrganizations/
cp ${PWD}/organizations/peerOrganizations/* ${PWD}/organizations/peerOrganizations/
cp ${PWD}/organizations/peerOrganizations/* ${PWD}/organizations/peerOrganizations/

Let’s check the directory structure for We see the msp/ directory structure, and the three files required in tls/, that is, ca.crt, server.crt and server.key.

Step 5: Create configuration for the new peer and bring up the container

Here is step 4 in the previous session. We keep the docker-compose file inside docker/ directory. The file is adopted from docker-compose-test-net.yaml, with proper host, directory and port modified for

docker-compose -f docker/docker-compose-peer1org1.yaml up -d

Step 6: Join the new peer to the existing channel

The container for is running. It is not part of the channel yet. Here we perform the 5c in the previous session, joining this new peer to mychannel.

We are accessing both and with the same terminal for Org1. To specify, we set the variable CORE_PEER_ADDRESS=localhost:8051 before any peer commands.

First, let’s check the channel both peers of Org1 have joined.

peer channel listCORE_PEER_ADDRESS=localhost:8051 peer channel list
Terminal for Org1 (showing and

We see has not joined any channel yet.

To join the channel, we need the channel genesis block. It was generated during channel creation when we first executed the ./ script, and the block file is kept in channel-artifacts/mychannel.block.

CORE_PEER_ADDRESS=localhost:8051 peer channel join -b channel-artifacts/mychannel.block

Now we see has joined mychannel now joined mychannel

As we know, peer joining the same channel is holding a copy of ledger. And we see they have the same ledger (same blockchain height and hash). The “missing” blocks have been collected from other peers in the channel. now has the same ledger as

And for sake of completeness, we see the same ledger in as well.

Same ledger is seen in

Now all the three peers are in the same channel, and have a common ledger.

Step 7: Install chaincode to that peer

We first check if we can use in chaincode query.

peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'CORE_PEER_ADDRESS=localhost:8051 peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'
chaincode query fails in as it is not installed yet.

We see that, even though the ledger is already there, we cannot query The reason is that a chaincode is not installed on this peer and a chaincode container is not there yet.

Before installing chaincode on the new peer, we first take a look at the chaincode containers. We see two, one for each peer.

And these two chaincode containers are instantiated by two images, one for each peer.

Now we install the chaincode package on According to the script, the chaincode package mycc.tar.gz is created and kept in the test-network/ directory.

CORE_PEER_ADDRESS=localhost:8051 peer lifecycle chaincode install mycc.tar.gz

After installation completes, we see a new chaincode container running for this peer, instantiated from a new image.

Chaincode container for on mycc
Chaincode container image for on mycc

If we take a look on the service discovery on endorsement, now we have two peers for Org1. Either one is good enough to handle the endorsement for Org1. We will test this in the next step.

Output of service discovery after is added.

Step 8: Test chaincode using new peer

First we query the state of an existing asset. Now we get back the result from

peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'CORE_PEER_ADDRESS=localhost:8051 peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'

Then we invoke chaincode function, with as one endorser for Org1. Remember that the default chaincode endorsement policy is majority, which means one endorsement is needed from both organizations. In this chaincode invocation we specify for Org1, and for Org2.

peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride --tls true --cafile $ORDERER_CA -C mychannel -n mycc --peerAddresses localhost:8051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/ --peerAddresses localhost:9051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/ -c '{"Args":["set","name","Bob"]}'

The chaincode invocation is successful. Now we query the result from all peers.


Through this exercise we know the steps required to add new peers to a peer organization. It is not complicated once we understand the overall flow. As First Network is no longer in v2.2+, we can use this simple process to set up a multiple-peer environment when needed.

Written by

Happy to share what I learn on blockchain. Visit for my works. or reach me on

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store