The development of Hyperledger begins with understanding the concept of Chaincode, followed by an introduction to how to develop Chaincode, how to deploy Chaincode to Fabric, and how to use Chaincode.
Chaincode, generally referred to as "链码" in Chinese, is a smart contract in Hyperledger, essentially a program implemented in a computer language. Chaincode is an important component of Hyperledger, typically written in Go, but also supports writing in Java, JavaScript, and other programming languages. The Chaincode in this book is written in Go.
So how does Chaincode run? After Chaincode is written, it needs to be compiled and deployed to Hyperledger. Once deployed, Chaincode runs in a protected Docker container, isolated from the endorsement nodes. Hyperledger uses Chaincode to read and modify ledger data, while also saving operation logs to the Hyperledger database. The state created by one Chaincode is only accessible to that Chaincode, and cannot be directly accessed by another Chaincode. However, within the same Hyperledger, given appropriate permissions, one Chaincode can call another Chaincode to access its created state.
The lifecycle of Chaincode includes four stages: packaging, installation, instantiation, and upgrading, which will be explained in the examples below.
Developing Chaincode involves implementing a specific interface, which includes two methods—Init() and Invoke(). The functions of these two methods are as follows: when Chaincode receives an instantiate or upgrade transaction, the Init() method is called so that Chaincode can perform any necessary initialization, including initializing application state; the Invoke() method is meant to respond to received invocation transactions to process transaction proposals.
Below is the implementation of the simplest Chaincode, which serves to demonstrate how to develop Chaincode and the execution flow of Chaincode. In this Chaincode, no data processing is performed; after calling the method, it simply returns, so returning a null value is sufficient when writing the main functionality of the Init() and Invoke() methods. The code is as follows:
The main function is the entry point for the Go program. When deploying Chaincode on a node, the contents of the main function will be executed. The first line in the main function, Err := shim.Start(new(SampleChaincode)), will start the sample Chaincode, outputting a failure message if an error occurs, or a success message if it runs successfully.
In the above example, three methods of Chaincode are implemented: Init, Query, and Invoke. Let's understand the functions of these three methods in turn.
● Init() method. The Init() method is called by each node when Chaincode is first deployed to the blockchain. This method can be used to implement any tasks related to initialization, bootstrapping, or setup.
● Query() method. The Query() method is called whenever any query operation is executed on the blockchain. The Query() method does not modify the state of the blockchain, so it does not run within a transaction context. If an attempt is made to modify the state of the blockchain within the Query() method, an error will occur. Additionally, since this method is only used to read the state of the blockchain, calls to it will not be recorded on the blockchain.
● Invoke() method. The Invoke() method is called whenever the state of the blockchain is modified, so all updates or deletions to the blockchain should be encapsulated within the Invoke method. Because this method will modify the state of the blockchain, Hyperledger will automatically create a transaction context for this method to execute within. All calls to this method will be recorded on the blockchain as transactions, which will eventually be written into blocks.
After implementing the above code, this Chaincode can be operated. Fabric provides four commands to manage Chaincode: package, install, instantiate, and upgrade. First, package the Chaincode using the package command, then install the Chaincode using the install command, and finally instantiate the Chaincode using instantiate. If you need to upgrade the Chaincode, you must first install the new version of the Chaincode and then upgrade it using the upgrade command.
In future versions, the official team is also considering adding stop and start commands to disable and re-enable Chaincode without having to uninstall it. After successfully installing and instantiating a Chaincode, the Chaincode is active (running). After installation, the Chaincode can be upgraded at any time, as shown in the figure.
There are two ways to install Chaincode: one is to install the source code directly, and the other is to package and sign the Chaincode using the package command to generate a package file, which is then installed using the install command.
This concludes the process of developing and using Chaincode. Finally, let's take a moment to explain the packaging process of Chaincode.
To facilitate management and signature verification of Chaincode, it is usually necessary to perform a packaging operation on Chaincode. Therefore, this section will detail the packaging process of Chaincode.
A Chaincode package consists of three parts: the Chaincode code itself, an optional instantiation policy, and a set of signatures from the entities owning the Chaincode. When the Chaincode is instantiated on the blockchain for transactions, it can be verified by the corresponding instantiation policy of the Chaincode.
The signatures serve the following purposes:
● Establish ownership of the Chaincode.
● Verify the contents of the package.
● Detect tampering of the package.
There are two ways to package Chaincode. The first method is when the Chaincode has multiple owners, requiring the Chaincode package to be signed by multiple owners. In this case, a Chaincode package requiring signatures needs to be created, which is signed sequentially by each owner. The second method is simpler, where the install command is used on a signed node to perform the packaging operation.
This concludes the content about Chaincode, and now we will begin the actual development of Hyperledger.
The first example is to build a local Fabric network. Through this case, you can learn how to build a simple blockchain network based on Hyperledger and perform basic interaction operations with this network, such as querying and updating blockchain data in Hyperledger.
In the section on installing the local environment for Hyperledger, the code for Fabric Samples has already been downloaded. In these sample codes, there is a folder named "first-network," which is a complete example of a Fabric project that implements a Fabric network containing multiple nodes and a command-line tool. Below, we will use this example to build the first Fabric network.
Entering the subdirectory first-network of fabric-network, you can see a script file named byfn.sh. This script file contains comprehensive comments. Executing “./byfn.sh -h” will display the usage instructions for this script file, including commands for starting and stopping the Fabric network, as shown in the figure.
Now, let's start building this simple Fabric network. Use the command “./byfn.sh -m generate” to generate the certificates and genesis block required for the network. During the execution of the command, some configurations need to be made; here, we will use the default configuration and simply enter “Y” in the command line tool to confirm, as shown in the figure.
You can see that during this process, the cryptogen tool is first used to generate certificates and keys for various network entities (cryptogen is a tool provided in the Fabric project to generate the required certificates). These certificates represent identities, allowing for signing/verifying identities when communicating and transacting within the network. Then, a genesis block is generated to guide the orderer node for ordering services. Finally, transaction configuration information required for the Channel is generated and saved to a file.
To shut down this network, you can use the command ./byfn.sh -m down, as shown in the figure.
After starting this Fabric network, we can interact with it. The interactions include managing channels (which refer to the channels in the Fabric network that connect nodes and isolate unrelated nodes) and operating Chaincode, thereby gaining a deeper understanding of the Fabric network. The way to interact with the Fabric network is through the command-line tool (CLI) calling the Fabric API.
To use the CLI, you first need to enter the CLI container (a Docker container containing the command-line tool CLI, which can be understood as an independent environment for running CLI). The command to enter the container is “docker exec -it cli bash,” as shown in the figure.
Once inside the CLI container, you can view the contents of the container and perform query and update operations on the Fabric network. The commands used in the CLI are mainly divided into two types: those related to channels and those related to Chaincode.
(1) Commands related to channels
The commands related to channels are as follows.
● Create channel.
Inside the CLI container, you can create a channel using the following command:
peer channel create -o orderer.example.com:7050 -c mychannel -f ./channel-artifacts/channel.tx --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
The meanings of the parameters are as follows.
● -o orderer.example.com:7050: Specifies the orderer service definition to be used for ordering services.
● -c mychannel: The name of the channel to be created.
● -f ./channel-artifacts/channel.tx: Specifies the configuration transaction file generated by tools like configtxgen to be submitted to the orderer node.
● --tls true: Whether to enable TLS for communication with the orderer.
--cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem: Specifies the TLS certificate of the orderer node, which is in PEM format.
● Join channel.
The command to join a channel is peer channel join -b mychannel.block, where -b is the block path, pointing to the file path containing the genesis block.
● List all channels.
The command to list all channels is peer channel list.
● Update channel.
The command to update a channel is peer channel update -o orderer.example.com:7050 -c mychannel -f ./channel-artifacts/Org1MSPanchors.tx --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem, with parameters similar to those for creating a channel.
(2) Commands related to Chaincode
The commands related to Chaincode are as follows.
● Install Chaincode: peer chaincode install [flags].
● Instantiate Chaincode: peer chaincode instantiate [flags].
● Invoke Chaincode: peer chaincode invoke.
● Package Chaincode: peer chaincode package.
● Query Chaincode: peer chaincode query.
● Sign Chaincode: peer chaincode signpackage.
● Upgrade Chaincode: peer chaincode upgrade.
The main parameters that can be used are as follows.
● -C: Channel ID.
● -c: JSON string of the chaincode constructor message (default "{}").
● -h: Help.
● -l: Language used to write Chaincode, default "golang".
● -n: Chaincode name.
● -p: Chaincode path.
● -v: Chaincode version.
● -o: Orderer node.
Now, let's query and update the Hyperledger using Chaincode.
Query and Update Hyperledger#
Inside the CLI container, first use query to check the balances of a and b (where a and b are two accounts automatically created when starting the network with the byfn.sh -m up command). You can see that a has 90 and b has 210, as shown in the figure.
Then transfer 80 from account b to account a. This transaction will create a new block and update the blockchain. The operation command is shown in the figure.
As seen in the figure, the operation was successful. Now, querying accounts a and b should show that account a has 170 and account b has 130, as shown in the figure.
This is how to query and update the Hyperledger using Chaincode.