In previous article, we showed you the network topology and the function of each network component. In this step of application deployment, we will set up this topology using Fabric based tools and commands. We will cover the whole network setup with the following steps
- Generating crypto keys and certificates
- Generating transaction configuration
- Starting the network
- Creating channel
- Joining peers to the channel
- Installing the chaincode
- Instantiating the chaincode
- Invoking the chaincode
- Querying the ledger
Generating Crypto Keys And Certificates
The first step will be to generate keys and certificates for every organization and its associated entities like peers and orderer so that it can be used to sign/verify as they communicate over the network. For this use case, as mentioned earlier, we will use ‘cryptogen’ tool to generate the necessary certificates. The following command generates the x.509 based crypto files.
OrdererOrgs:
- Name: Orderer
Domain: fte.com
Specs:
- Hostname: orderer
PeerOrgs:
- Name: Org1
Domain: app.fte.com
Template:
Count: 2
Users:
Count: 2
- Name: Org2
Domain: bnk.com
Template:
Count: 2
Users:
Count: 2
- Name: Org3
Domain: shp.com
Template:
Count: 2
Users:
Count: 1
cryptogen generate –config=./crypto-config.yaml
The above command uses the ‘cryptogen’ tool that reads the ‘crypto-config.yaml.’ file to generate the certificates. The ‘crypto-config.yaml’ file depicts our network topology in a declarative way. The following configuration shows the ‘crypto-config.yaml.’ file that has our orderer and three organizations with peers and users.
Peers and users are denoted by numbers (using Count field) where you can specify how many users and peers you would like to setup per organization.
Generating Transaction Configuration
Moving ahead, we will create transaction configuration artifacts. These are stated as below:
- Genesis block
- Channel transaction configuration
We will use ‘configtxgen’ tool to generate the above artifacts. The said tool will read the ‘configtx.yaml.’ file. The below configuration shows the ‘configtx.yaml.’ file.
Profiles:
TradeFinanceOrdererGenesis:
Orderer:
<<: *OrdererDefaults
Organizations:
- *OrdererOrg
Consortiums:
TradeConsortium:
Organizations:
- *Org1
- *Org2
- *Org3
TradeFinanceOrgsChannel:
Consortium: TradeConsortium
Application:
<<: *ApplicationDefaults
Organizations:
- *Org1
- *Org2
- *Org3
Organizations:
- &OrdererOrg
Name: OrdererOrg
ID: OrdererMSP
MSPDir: crypto-config/ordererOrganizations/fte.com/msp
- &Org1
Name: Org1FTE
ID: Org1FTE
MSPDir: crypto-config/peerOrganizations/app.fte.com/msp
AnchorPeers:
- Host: peer0.app.fte.com
Port: 7051
- &Org2
Name: Org2BNK
ID: Org2BNK
MSPDir: crypto-config/peerOrganizations/bnk.com/msp
AnchorPeers:
- Host: peer0.bnk.com
Port: 7051
- &Org3
Name: Org3SHP
ID: Org3SHP
MSPDir: crypto-config/peerOrganizations/shp.com/msp
AnchorPeers:
- Host: peer0.shp.com
Port: 7051
Orderer: &OrdererDefaults
OrdererType: solo
Addresses:
- orderer.fte.com:7050
BatchTimeout: 5s
BatchSize:
MaxMessageCount: 5
AbsoluteMaxBytes: 10 MB
PreferredMaxBytes: 512 KB
Kafka:
Brokers:
- 127.0.0.1:9092
Organizations:
Application: &ApplicationDefaults
Organizations:
The ‘configtx.yaml’ file consists of profiles for ordering service and channel. The orderer profile named ‘TradeFinanceOrdererGenesis’ will define a consortium of our three organizations. The channel profile ‘TradeFinanceOrgsChannel’ will have a reference to this consortium and will also imply that all the three organization’s signature will be required to create that channel.
The ‘configtx.yaml’ file also contains information like the path to root certificates for our three organizations, the endorsing peer with endpoint details and orderer default settings.
Genesis Block
As a first step, we will create a genesis block or the first block of the transaction. It is also called a configuration block, which will describe our three peer organizations and an orderer stating their root certificates and access policies. This block will initialize the blockchain network or channel. The following command generates the genesis block
configtxgen -profile TradeFinanceOrdererGenesis -outputBlock ./channel-artifacts/genesis.block
The above command uses ordering service profile named ‘TradeFinanceOrdererGenesis’ to generate ‘genesis.block’ file and place it in the ‘channel-artifacts’ folder. The ‘genesis.block’ file will be used to bootstrap the ordering service.
Channel Transaction Configuration
Next, we will generate channel transaction configuration file. This will be used to create the channel for our network. The following command generates the channel transaction configuration file.
configtxgen -profile TradeFinanceOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID tradechannel
The above command uses channel profile named ‘TradeFinanceOrgsChannel’ to generate ‘channel.tx’ configuration file and places it in the channel-artifacts folder. The said file will be used to create the channel.
Starting The Network
We will start the network by spinning up our nodes. To start these nodes, we will use docker images provided by Fabric runtime. Docker provides a consistent environment to work with different platforms like OS/Mac/Windows. Moreover, with Docker, you could also port your application on the cloud. We will spin up the following nodes:
Note: We will only show few docker code snippets here. To view the entire code, you can download it from the GitHub at https://github.com/enterprise-blockchain-book/first-edition/blob/master/hyperledger-fabric/base/docker-trade-finance-base.yaml
image: hyperledger/fabric-orderer
environment:
- ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.genesis.block
command: orderer
volumes:
- ../channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block
ports:
- 7050:7050
Node: Orderer (orderer.fte.com)
Below is the short docker snippet:
The above docker image will spin up the orderer container on port 7050. The important thing to observe is that we have bootstrapped our orderer service with the genesis block we created earlier. It means the configuration block will be created on the orderer service startup. We also specify the path to root certificates and key here.
Node: Peer0 of Org1FTE(peer0.app.fte.com)
Below is the short docker snippet:
image: hyperledger/fabric-peer
environment:
- 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
command: peer node start
ports:
- 7051:7051
The above docker image will spin up peer node container for the first organization. It will use 7051 as a host and container port. It also specifies path to crypto credentials used for signing and verification. The rest of the peer nodes will also use the same above docker image and environment, but each will use different host port. The below are the details of other peer nodes:
- Org1 MSP id: Org1FTE – peer1.app.fte.com – 8051:7051
- Org2 MSP id: Org2BNK – peer0.bnk.com – 9051:7051
- Org2 MSP id: Org2BNK – peer1.bnk.com – 10051:7051
- Org3 MSP id: Org3SHP – peer0.bnk.com – 11051:7051
- Org3 MSP id: Org3SHP – peer1.bnk.com – 12051:7051
Once all the nodes are up and running, we will go ahead and create the channel.
Creating Channel
The channel creation process reads our previously generated channel transaction configuration artifact to create the channel. The following command creates the channel:
peer channel create -o orderer.fte.com:7050 -c tradechannel -f ./channel-artifacts/channel.tx
The above command reads our previously configured artifact ‘channel.tx’ and creates the channel with the channel name as ‘tradechannel.’ The ‘-c’ flag is used to specify the channel name. The channel name can be any name of your choice. The ‘-f’ flag is used to specify the configuration file, in this case, it is ‘channel.tx’ we generated using ‘configtxgen’ tool. The command returns the genesis block named ‘tradechannel.block.’ This block file is then used to make our peer nodes join the ‘tradechannel’ channel.
Joining Peers To The Channel
Once the channel is created, the peer nodes should formally join the channel to participate in the transactions on that channel. The following command is used to onboard peers to the channel ‘tradechannel’.
peer channel join -b tradechannel.block
The above command is supplied with the channel block file ‘tradefinance.block’ we created in the previous (create channel) command. The -b’ option is used to specify the channel block file. You could be wondering where the name of the peer node is provided for joining the ‘tradechannel’? The answer lies in the CORE_PEER_ADDRESS environment variable. You have to set this environment variable with the value of peer node address that you wish to join. Since we have 6 peer nodes, we must run this command six times and change the value of the CORE_PEER_ADDRESS environment to point to the correct peer node address each time we run the command. So, to join the first peer node from Org1, set the CORE_PEER_ADDRESS variable to the value ‘peer0.app.fte.com:7051′ and run the above command. You then update the environment variable to point to the second peer node of the Org1, i.e., peer1.app.fte.com:7051’ and run the command. Similarly, you do this for all the peer nodes in Org2 and Org3. This way you will have all the peers now becoming part of the ‘tradechannel’ channel. In the next step, we will install the chaincode (smart contract) on all the peer nodes.
Installing The Chaincode
We will now install our trade finance chaincode file ‘tradefinancecontract.go’ on every peer nodes. Peer node endorses and verifies transactions invoked using the chaincode. The following command installs the chaincode in the peer node file system:
peer chaincode install -n tradefinancecc -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/tradecontract
The above command will install the chaincode which is located in the path ‘github.com/hyperledger/fabric/examples/chaincode/go/tradecontract’ and give it a name as ‘tradefinancecc’. The path denoted is mapped to volume path on the docker container. It points to ‘hyperledger-fabric/chaincode/tradecontract’ folder that contains our chaincode file. The chaincode will be installed in the file system of the peer node. Peer node address can be specified by setting the CORE_PEER_ADDRESS environment variable as stated in the previous step. Since we have six peer nodes, you must run this command six times with each time updating the said environment variable to point to correct peer address. The ‘-n’ option is used to provide a name to chaincode, and ‘-p’ option is used to specify the source path of our chaincode file. In the next step, we will instantiate this chaincode.
Instantiating The Chaincode
Now, the chaincode ‘tradefinancecc’ is installed on each peer, we will instantiate the same. Instantiating the chaincode means initializing the chaincode by invoking its init() method. The following command instantiates the chaincode:
peer chaincode instantiate -o orderer.fte.com:7050 -C tradechannel -n tradefinancecc -v 1.0 -c ‘{“Args”:[“init”,”FTE_2″,”FTE_B_1″,”FTE_S_1″,”SKU001″,”10000″,”1000″]}’ -P “OR (‘Org1FTE.member’,’Org2BNK.member’,’Org3SHP.member’)”
The above command instantiates the chaincode on the target peer (as mentioned in the CORE_PEER_ADDRESS environment variable) and launches its own isolated docker container. The command uses Args key field to pass the function name ‘Init’ and various other parameters to initialize our trade finance smart contract. It also sets the endorsing policy by specifying which organization peers will do the endorsement. The policy is specified using ‘-P’ option.
Invoking The Chaincode
With the chaincode instantiated in earlier step, we can now invoke business methods. Invoking means calling the ‘Invoke’ method of the chaincode, which then calls the appropriate business method based on the method name passed as a parameter to the command. The following command invokes the ‘createLOC’ method of the chaincode.
peer chaincode invoke -o orderer.fte.com:7050 -C tradechannel -n tradefinancecc -c ‘{“Args”:[“createLOC”,”FTE_2″]}’
The above command invokes the ‘createLOC’ method on the target peer (as mentioned in the CORE_PEER_ADDRESS environment variable). You can point to any peer as transactions are invoked on all peers. If you recall, every peer maintains a copy of the ledger, and therefore, all peer will execute the transaction. Once the chaincode is instantiated or any business method is invoked, it starts the chaincode containers for all the peers. The above command executes ‘createLOC’ method by passing the trade id. The trade status is then updated to the ledger. In the next step, we will query the state of the ledger.
Querying The Ledger
Now, since we have executed one business method named ‘createLOC’, we will check if it indeed updated the trade status. You can check the state of the ledger by giving the following command:
peer chaincode query -C tradechannel -n mycc -c ‘{“Args”:[“query”,”FTE_2″]}’
The above command queries the channel by passing the trade id. The query is executed on the target peer and returns the current state of the ledger. If you view the log file of the container, you will see the trade status changed to ‘LOC created.’
This ends our fourth stage of design and implementation approach. In the next stage, we will demonstrate the complete end-to-end flow, fulfilling our trade finance smart contract as test cases by running a single script file.