Once the necessary prerequisites have been installed and the fabric-samples folder has been downloaded navigate into the fabcar directory within it and ls
Terminal window
1
cdfabric-samples/fabcar
2
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
From the fabcar/javascript directory install the dependencies and start fabric from the fabcar folder
Terminal window
1
npminstall
2
cd..
3
./startFabric.sh
Enroll the Admin User
Open a new terminal and run the following command to stream Docker logs
Terminal window
1
dockerlogs-fca.example.com
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
Terminal window
1
nodeenrollAdmin.js
If this works you should see the following output
1
Successfully enrolled admin user "admin" and imported it into the wallet
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
Terminal window
1
noderegisterUser.js
This will yield the following output if it works
1
Successfully registered and enrolled admin user "user1" and imported it into the wallet
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
1
fabric_client.getUserContext('user1',true)
To run the query, from the fabcar/javascript folder, run the following command
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:
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
1
constgateway=newGateway()
2
awaitgateway.connect(ccp,{
3
wallet,
4
identity:'user1',
5
discovery:{ enabled:false},
6
})
7
8
// Get the network (channel) our contract is deployed to.
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
Terminal window
1
./byfn.shgenerate
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:
Terminal window
1
./byfn.shup-lnode
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
Terminal window
1
./byfn.shup-cmychannel-scouchdb-lnode
When the network is up and transacting you will see the following
1
Starting with channel 'mychannel' and CLI timeout of '10'
2
Continue? [Y/n]
3
proceeding ...
4
Creating network "net_byfn" with the default driver
5
Creating peer0.org1.example.com
6
Creating peer1.org1.example.com
7
Creating peer0.org2.example.com
8
Creating orderer.example.com
9
Creating peer1.org2.example.com
10
Creating cli
11
12
13
____ _____ _ ____ _____
14
/ ___| |_ _| / \ | _ \ |_ _|
15
\___ \ | | / _ \ | |_) | | |
16
___) | | | / ___ \ | _ < | |
17
|____/ |_| /_/ \_\ |_| \_\ |_|
18
19
Channel name : mychannel
20
Creating channel...
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
1
Query Result: 90
2
2017-05-16 17:08:15.158 UTC [main] main -> INFO 008 Exiting.....
3
===================== Query successful on peer1.org2 on channel 'mychannel' =====================
4
5
===================== All GOOD, BYFN execution completed =====================
6
7
8
_____ _ _ ____
9
| ____| | \ | | | _ \
10
| _| | \| | | | | |
11
| |___ | |\ | | |_| |
12
|_____| |_| \_| |____/
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
Terminal window
1
./byfn.shdown
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
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
Terminal window
1
./byfn.shdown
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
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
Terminal window
1
docker-compose-fdocker-compose-cli.yamlup-d
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
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
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:
Terminal window
1
exportCHANNEL_NAME=mychannel
2
3
# the channel.tx file is mounted in the channel-artifacts directory within your CLI container
4
# as a result, we pass the full path for the file
5
# we also pass the path for the orderer ca-cert in order to verify the TLS handshake
6
# be sure to export or replace the $CHANNEL_NAME variable appropriately
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
Terminal window
1
peerchanneljoin-bmychannel.block
Thereafter join peer0.org2 by prefacing it with the appropriate environment variables and joining the channel on behalf of peer0.org2
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
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
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
Terminal window
1
dockerlogs-fcli
Furhtermore we can see the chaincode logs by looking at the logs for each respective peer
Terminal window
1
dockerlogsdev-peer0.org2.example.com-mycc-1.0
2
dokcerlogsdev-peer0.org1.example.com-mycc-1.0
3
dockerlogsdev-peer1.org2.example.com-mycc-1.0
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