Rework: A Companion Guide to Fabric CA Operation Guides for Fabric v2.2
Introduction
This is another rework on my recent article. The source is a tutorial of Fabric CA in Hyperledger Fabric documentation. The tutorial was done with version 1.4, and my first work done early this July was also made on the same version. Since then I keep receiving queries to make it running in v2.0, as there are many changes from v1.4 to v2.0 and the commands are not used directly in v2.0. As a result I rewrite this companion guide to make it workable in v2.2.
We follow the same network design and setup. Unlike the previous work, we consolidate the four scripts in our previous work into one, bringing up all the CA and registering all the entities. No CLI containers are needed as we are using binary peer
directly in the localhost. Meanwhile, all material is now in this repository.
Here in this article I just highlight the difference from the previous one, and most of the explanation is omitted. You can always refer to my previous work for more detailed explanation.
Network Design and Setup
Here is a quick summary of the network design and setup in this tutorial.
Fabric network looks like this
Each organization comes with an identity CA (organization root CA), which issues the certificates for every component and user in that organization. In addition, one TLS CA is responsible for issuing TLS server certificates for network components (orderer and peer) of ALL organizations. As a result, there are four CAs in this tutorial.
Demonstration
Step 1: Preparation
Clone the repository if not done before
All material is now in the repository. We will refer to these files later. Meanwhile, for sake of consistency, change the directory name to guide/
.
cd fabric-samples
git clone https://github.com/kctam/fabric-ca-tutorial-v2.git// without changing the document we rename the folder
mv fabric-ca-tutorial-v2 guide
Set path for fabric binaries if not done before
In the script we will directly use fabric-ca-client
, which is inside fabric-samples/bin/
. Set the PATH
environment variable if not done yet
cd fabric-samples
export PATH=$PATH:${PWD}/bin/// use this to see if we can reach fabric-ca-client
which fabric-ca-client
Tear down everything
We just make sure we have a clean environment. Also, as all crypto material generated is kept in /tmp/hyperledger/
, we empty this directory as well.
cd fabric-samples/guide/
docker-compose down
docker rm $(docker ps -aq)
docker rmi $(docker images dev-* -q)// remove any material of previous deployment
mkdir -p /tmp/hyperledger
cd /tmp/hyperledger
rm -rf *
Bring up two terminals, Org1 and Org2
As we will use two terminals accessing each peer, two files are prepared for all the environment variables needed. Open two terminals and include those variables.
// terminal for Org1 (blue background colour)
source terminalorg1// terminal for Org2 (green background colour)
source terminalorg2
Step 2: Bring Up the four CAs
In the main terminal,
cd fabric-samples/guide/docker-compose up -d ca-tls rca-org0 rca-org1 rca-org2
Note: in case you have permission problems, change owner of the /tmp/hyperledger/
. For example,
sudo chown -R ubuntu:ubuntu /tmp/hyperledger/*
Step 3: Execute Registration and Enrollment scripts
As mentioned before, we have prepared two scripts to process all the registration and enrollment for the network.
Enrol registrar of each CA and register all entities
For each CA, we first enrol a registrar. After that, let this registrar register each entity into the CA database. Note the id.type
of each entity. Besides, we have put an attribute abac-init
to admin-org2 as we are going to test attribute-based access control (ABAC) later in Step 7 when we deploy chaincode.
./allCAnReg.sh
Enrol entities one by one for each organization
For each organization, we now enrol each entity (network component and user) from the CAs. In the repository we have prepared three configuration files (orgx-config.yaml
) for node OU, one for each organization. They are copied to the organizations respectively.
./enrollAllOrg.sh
Step 4: Prepare channel artifacts
We are preparing the three artifacts: one consortium genesis block, one channel transaction and one anchor peer update. We keep them in /tmp/hyperledger/org0/orderer/
directory.
In the main terminal,
configtxgen -profile OrgsOrdererGenesis -outputBlock /tmp/hyperledger/org0/orderer/genesis.block -channelID syschannelconfigtxgen -profile OrgsChannel -outputCreateChannelTx /tmp/hyperledger/org0/orderer/channel.tx -channelID mychannelconfigtxgen -profile OrgsChannel -outputAnchorPeersUpdate /tmp/hyperledger/org0/orderer/org1MSPanchors.tx -channelID mychannel -asOrg org1MSP
Step 5: Bring up the whole network
In the main terminal,
docker-compose up -d
all the components (four peers and one orderer) are up and running
Step 6: Create and Join Channel
Create channel genesis block
Terminal for Org1
peer channel create -c mychannel -f /tmp/hyperledger/org0/orderer/channel.tx -o localhost:7050 --ordererTLSHostnameOverride orderer1-org0 --outputBlock /tmp/hyperledger/org1/peer1/assets/mychannel.block --tls --cafile /tmp/hyperledger/org1/peer1/tls-msp/tlscacerts/tls-0-0-0-0-7052.pem
Join peers of Org1 to mychannel
Note that the default environment variable is set for peer1-org1. For peer2-org1, we specify the correct CORE_PEER_ADDRESS
.
Terminal for Org1
peer channel join -b /tmp/hyperledger/org1/peer1/assets/mychannel.blockCORE_PEER_ADDRESS=localhost:8051 peer channel join -b /tmp/hyperledger/org1/peer1/assets/mychannel.block
Join peers of Org2 to mychannel
Similar, the default environment variable is set for peer1-org2. For peer2-org2, we specify the correct CORE_PEER_ADDRESS
.
Terminal for Org2
peer channel join -b /tmp/hyperledger/org1/peer1/assets/mychannel.blockCORE_PEER_ADDRESS=localhost:10051 peer channel join -b /tmp/hyperledger/org1/peer1/assets/mychannel.block
Update anchor peer for Org1
Terminal for Org1
peer channel update -c mychannel -f /tmp/hyperledger/org0/orderer/org1MSPanchors.tx -o localhost:7050 --ordererTLSHostnameOverride orderer1-org0 --tls --cafile /tmp/hyperledger/org1/peer1/tls-msp/tlscacerts/tls-0-0-0-0-7052.pem
Check if all the four peers having the same ledger
After all peers have joined the same channel, they will have the same ledger. We use peer channel getinfo
to check both the blockchain height and current block hash are identical for all peers.
Terminal for Org1
peer channel getinfo -c mychannelCORE_PEER_ADDRESS=localhost:8051 peer channel getinfo -c mychannel
Terminal for Org2
peer channel getinfo -c mychannelCORE_PEER_ADDRESS=localhost:10051 peer channel getinfo -c mychannel
Step 7: Deploy chaincode abac
Note since Fabric v2.0, chaincode is deployed through lifecycle chaincode. You can get more ideas about the difference between v1.4 and v2.0 here.
Package chaincode abac
Terminal for Org1
// if not done before
cd fabric-samples/chaincode/abac/go/
GO111MODULE=on go mod vendor
cd fabric-samples/guidepeer lifecycle chaincode package abac.tar.gz --path ../chaincode/abac/go/ --label abac_1
Install chaincode to peer1-org1 and peer1-org2
Terminal for Org1 and Org2
peer lifecycle chaincode install abac.tar.gz
Approve chaincode for Org1 and Org2
Use the package ID obtained from installation.
Terminal for Org1 and Org2
peer lifecycle chaincode approveformyorg --tls --cafile /tmp/hyperledger/org1/peer1/tls-msp/tlscacerts/tls-0-0-0-0-7052.pem -o localhost:7050 --ordererTLSHostnameOverride orderer1-org0 --channelID mychannel --name mycc --version 1 --sequence 1 --waitForEvent --init-required --package-id abac_1:fd3168223d23448531a02d6f52e33c5e8ea3a63cbf6e53a0093aa3a60bd70a87
Commit chaincode
Terminal for Org1
peer lifecycle chaincode commit -o localhost:7050 --ordererTLSHostnameOverride orderer1-org0 --tls --cafile /tmp/hyperledger/org1/peer1/tls-msp/tlscacerts/tls-0-0-0-0-7052.pem --peerAddresses localhost:7051 --tlsRootCertFiles /tmp/hyperledger/org1/peer1/tls-msp/tlscacerts/tls-0-0-0-0-7052.pem --peerAddresses localhost:9051 --tlsRootCertFiles /tmp/hyperledger/org1/peer1/tls-msp/tlscacerts/tls-0-0-0-0-7052.pem --channelID mychannel --name mycc --init-required --version 1 --sequence 1
Step 8: Test chaincode abac
Invoke chaincode function Init()
The chaincode abac is the same as abstore. The major difference is that the init() can only be invoked by a user with abac.init attribute set. In our setup, only admin-org2 has this attribute (see Step 3). Environment variable for terminal 1 is set to admin-org1, for terminal 2 is set to admin-org2.
We will invoke this init() in both terminal 1 and terminal 2, and we can see invocation in terminal 1 fails while that in terminal 2 is successful.
On both terminals,
peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer1-org0 --tls true --cafile /tmp/hyperledger/org1/peer1/tls-msp/tlscacerts/tls-0-0-0-0-7052.pem -C mychannel -n mycc --peerAddresses localhost:7051 --tlsRootCertFiles /tmp/hyperledger/org1/peer1/tls-msp/tlscacerts/tls-0-0-0-0-7052.pem --peerAddresses localhost:9051 --tlsRootCertFiles /tmp/hyperledger/org1/peer1/tls-msp/tlscacerts/tls-0-0-0-0-7052.pem --isInit -c '{"Args":["init","a","100","b","200"]}'
Query values from both peers
peer chaincode query -C mychannel -n mycc -c '{"Args":["query","a"]}'
Invoke chaincode function invoke()
The “restriction” on admin-org2 is only applicable in init(). We will invoke invoke() in the code using terminal 1. And the invocation is successful.
peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer1-org0 --tls true --cafile /tmp/hyperledger/org1/peer1/tls-msp/tlscacerts/tls-0-0-0-0-7052.pem -C mychannel -n mycc --peerAddresses localhost:7051 --tlsRootCertFiles /tmp/hyperledger/org1/peer1/tls-msp/tlscacerts/tls-0-0-0-0-7052.pem --peerAddresses localhost:9051 --tlsRootCertFiles /tmp/hyperledger/org1/peer1/tls-msp/tlscacerts/tls-0-0-0-0-7052.pem -c '{"Args":["invoke","a","b","10"]}'
Query values from both peers
The ledger is updated correctly.
This is the end of demonstration.