Once the necessary prerequisites have been installed and the fabric-samples folder has been downloaded navigate into the fabcar directory within it and ls
Note the startFabric.sh file, as this will be needed in future
In this folder you should see a few choices for javascript/typescript, navigate in to the javascript directory
This should then contain the following files
Next, clear any active docker containers
If this tutorial has been done before, also remove the chaincode image with the following
Installing Clients and Launching the Network
From the fabcar/javascript directory install the dependencies and start fabric from the fabcar folder
Enroll the Admin User
Open a new terminal and run the following command to stream Docker logs
When the network was launched, an admin user was registered as the Certificate Authority, the admin object will then be used to register and enroll new users
We now need to send an enrollment call and retrieve the Enrollment Certificate for the admin user. Switch back to the fabcar/javascript directory and run the following
If this works you should see the following output
Enroll a new User
We can now register a new user using the admin eCert to communicate with the CA server. This user1 identity will be used when querying and updating the ledger
Still in the fabcar/javascript directory, run the following
This will yield the following output if it works
Querying the Ledger
Queries are how you read data from the ledger, data is stored as key-value pairs and we can query for the value of a single key or multiple keys, if the ledger is written in a format like JSON we can perform more complex search operations
We can query the ledger to return all cars on it with the user1 identity. The query.js file contains the following line that specifies the signer
To run the query, from the fabcar/javascript folder, run the following command
Which should return something like this
The query in the query.js file is constructed with the following code
When the query was run, it invoked the fabcar chaincode on the peer and ran the queryAllCars function within it, we can lok at the fabric-samples/chaincode/fabcar/javascript/lib/fabcar.js file to see the function that was evoked, which is the following
The above pattern of using an application to interface with a smart contract which in turn interacts with the ledger is how transactions are done on the blockchain
If we want to modify our query to only search for CAR4 we can change the following line:
To be as follows:
Running the query again from the terminal
Should return the following
Using the queryCar function we can query any cat in the ledger
Updating the Ledger
The invoke.js file will update the ledger by creating a car. The application will propose an update, and receive the endorsed update which it will then send to be written to every peer’s ledger
The request in the invoke.js file can be seen below
We can run the transaction with
Which will result in the following ouput
We can now modify the transaction to update CAR10 by changing
To
And run invoke.js again
If we run query.js for CAR10 this time, we should see the following
Cleanup
Clear any active docker containers
If this tutorial has been done before, also remove the chaincode image with the following
This tutorial needs to be run from the fabric-samples/first-network directory
Network Builder Script
We can look at the help information for the byfn.sh script as follows
The default channel name will be mychannel, the default timeout will be 10s
Generate Network Artifacts
To generate network artifacts we can run the following command
Which will have a description of what it will do and an option to continue
The first step generates all of the certificates and keys for our network entities, the genesis block used to bootstrap the ordering service, and a collection of configuration transactions required to configure the Channel
Bring Up the Network
You can bring up the network with the ./byfn.sh up command, which will by default use GoLang for the chaincode. If we want to use Node (which I do), use the following command instead
To bring up the network with Node as the Language, use the following command:
Furthermore if we want to use by defining a language channel name, and DB type, we can use look at the documentation for more commands on the script. For example if we wanted to use Node, and CouchDB with our channel called mychannel we can do that with the following
When the network is up and transacting you will see the following
The above command will launch all the containers and run through a complete end-to-end application scenario, scrolling through these logs will allow you to see al the transactions
When complete you will see the following output
If we want to use a different language we need to bring down and restart the network
Bringing Down the Network
You can bring down the network with the following command
Crypto Generator
We use the cryptogen tool to generate cryptographic material for network entities. These certificates are representative of identities and allow for sign/verify authentication between entities
Cryptogen consumes a file crypto-config.yaml which contains the network topology and allows us to generate certificates and keys for Organizations and the Certificates belinging to them
Each organization is provisioned a unique ca-cert that binds certain peers and orderers to it. By assigning each Org a unique CA we mimic the way a typical network would work
Transactions are signed by a private key (keystore) and verified with a private key (signcerts)
The crypto-config.yaml file contains the following
The naming convention for a network entity is <HOSTNAME>.<DOMAIN>, so for the ordering node we have orderer.example.com
After running the cryptogen tool, the generated certificates and keys will be saved to a folder called crypto-config
Configuration Transaction Generator
The configtxgen tool is used to generate four configuration artifacts
Orderer genisis block
Channel configuation transaction
Two anchor peer transactions - One for each Peer Org
The genesis block is the configuration block that initializes the ordering service and serves as the first block on a chain
Configtxgen works by consuming a configtx.yaml file which contains definitions for the network
In the configtx.yaml file we define the following
One Orderer Org OrdererOrg
Two Peer Orgs Org1 and Org2
A Consortium SampleConsortium
The file also has two unique headers
One for the Orderer Genesis Block TwoOrgsOrdererGenesis
One for the Channel TwoOrgsChannel
Which can be seen in the file below
Run the Tools
We can make use of the configtxgen and cryptogen commands to do what we need, alternatively we can also adapt the byfn.sh script’s generateCerts function to meet our requirements
Before running the remainder of the tools, make sure the previous network is down by running the following
If you run into an error that says cannot remove .... Permission denied run the command as sudo
Manually Generate the Artifacts
We can refer to the generateCerts function to see how we would go about doing this, but we can also do this using the binaries manually as follows
Which should have the following output
Which will output the certs and keys into a cypto-config directory
Next we need to use the cofigtxgen tool as follows
Which should have an output like
Create Channel Configuration
Create the CHANNEL_NAME environment variable
And create the Channel Transaction Artifact
Then define the Anchor Peer for Org1 and Org2 as follows
Start the Network
We make use of the docker compose files to bring up the fabric containers and bootstrap the Orderer with the genesis.block
There are a few different steps as follows
Start the network from your terminal with the following command, the -d flag disables container logs, if you want to view the logs, run the following command in a new terminal
Environment Variables
We need to configure some environment variables. The variables for peer0.org1.example.com are coded into the CLI container via the docker-compose-cli.yaml file, however if we want to send calls to other peers or Orderers, we need to modify the following values in the cli.environment object in the yaml file before starting the network
Create and Join a Channel
We created the channel configuraion transaction using the configtxgen tool, that process can be repeated to create additional channel configurations with the configtx.yaml file by using the same or different profiles
We enter the CLI container next with docker exec
If successful you will see the following
Now we need to set previously mentioned variables in the cli container as they are different to what we had previously set in the docker-compose-cli.yaml file. From the Container’s terminal run the following
Next we specify the channel name with the -c flag, and the channel transaction with the -f flag, we will create the channel with the following from our terminal:
If you run into an error at this stage, such as the one below
It likely indicatesthat the previous network was not taken down correctly, run sudo ./byfn. down and ensure that you have no running containers with docker container ls
Note the --cafile is the Certificate file for the Orderer allowing us to verify the TLS handshake
The command we just executed generated a proto called mychannel.block which we can see by running ls from within the container
We can now join peer0.org1.example.com to the channel we just created with the following
Thereafter join peer0.org2 by prefacing it with the appropriate environment variables and joining the channel on behalf of peer0.org2
Update the Anchor Peers
Nexty we will perform channel updates which will propogate to the definition of the channel, essentially adding configuration deltas for the channel’s genesis block to define the anchor peers
We can define the anchor peer for Org1 as peer.0org1.example.com, as our environment variables still hold the values for
And for Org2 as peer0.org2.example.com by updating
Install and Instantiate Chaincode
Applications interact with the ledger through chaincode, we need to install chaincode on every peer that will need to execute and endorse out interactions. Chaincode can be written in Go, Java, and Javascript and runs on the peer in the context of a chaincode container with a specific name and version and exists on the peer’s filesystem
We can install chaincode on a peer with the following command, the -l flag allows us to specify the language
The -p argument is the path to the file and the -n is the name of the chaincode
Next we can instantiate the Chaincode on the peer, the -P flag indicates the endorsement policy needed, in the following case it is -P "AND ('Org1MSP.peer','Org2MSP.peer')"
Next, modify the environment variables and install the chaincode on peer 2
We can instantiate the chaincode with the following
Note that the above command may take a while to execute for Node and Java as it is also installing a shim and container respectively
Verify Chaincode
We can make some queries and transactions to verify that the chaincode was correctly installed
Query
we can query the value od a to make sure the state DB was populated as follows
The queey should return 100
Invoke
Next, move 10 from a to b
Query
Thereafter, query the value again to verify that the transfer succeeded
We should now see 90
Install on New Peer
Now, Install the chaincode on a third peer peer1.org2, first set the folowing environment variables
Then install the chaincode
Join Channel
Next the new peer needs to join the channel before it can respond to queries
Query
After a few seconds when the peer has joined the channel, we can submit the query
We should see the same output as before of 90
Take Down the Network
Lastly, we can take down the network with
The process we just covered is the same as what happens when we run ./byfn.sh up, we can run this again and look at the logs in order to see the above with some neat output which I will not put here
Important Points
Chaincode must be installed on a peer for it to successfully read and write
Chaincode is not instantiated until an init or read/write transaction is performed against the chaincode
An intial transaction causes a container to start
All peers on a channel maintain the same copy of the ledger, even those without the chaincode installed on them
Viewing Transactions
We can see transactions by looking at the logs for the CLI container
Furhtermore we can see the chaincode logs by looking at the logs for each respective peer
CouchDB
We can switch the database from GloveDB to CouchDB in order to allow us to make more complex queries additional to the standard chaincode functionality, to use CouchDB we simply compose with the docker-compose-couch.yaml file as follows
While running a development environment we can map CouchDB to a port in order to allow us to use the REST API and visualize the Db with the Web UI, however port mapping is not recommended for Production environments
If we want to look at a tutorial for doing the above with CouchDB we can find that here
CouchDB allows us to store more complex JSON data in a fully queryable format, as well as enhancing security for compliance and allows us to do field-level security such as calue masking and filtering
Troubleshooting
If you need to shoot some trouble you can find some information in the Fabric Docs