By Matt Zand and Navil Rodrigues
The architecture of Hyperledger Fabric, by design, comes with essential components that are vital to the operation of enterprise blockchain applications. Indeed, the power of Hyperledger Fabric is best understood and appreciated as a large project starts scaling up to manage massive transactions securely and in real-time. As such, unlike public blockchain platforms like Ethereum, Hyperledger Fabric has a relatively steeper learning curve; yet your patience will be rewarded when your application goes to production and you will be tasked with scaling its operation.
Smart contracts, or chaincodes, in Hyperledger Fabric play a more vital role than other components. Indeed, as a professional Hyperledger Fabric developer, you should gradually master all aspects of chaincodes from logical design to development, testing and deployment. Unlike Ethereum, inside a chaincode you can have multiple smart contracts running simultaneously. Indeed, in a consortium model, each member can have its own smart contract in its node, a smart contract that is communicating inside a private channel with other members and the system smart contract that is connected to the Orderer and system admin node. Due to the importance of chaincode, in this article we will briefly review its key parts.
- Contract class
- Contract Structure
- The ChaincodeStub Interface
- Distributed Ledger Data Representation
- Logging in Chaincode
In the next sections, we briefly introduce you to these concepts and show you how and where to use them.
I- Contract Class in Chaincode
In Hyperledger Fabric, a smart contract needs to inherit all the methods from the contract class which is provided in the fabric-contract-api npm package. These different methods are called in response to transactions that are invoked on the blockchain. Here is an example of a contract class that is inherited from contract API, followed by a brief explanation of its key methods:
The constructor in the contract class accepts a name as an optional input parameter which is used to give a name to your smart contract. If the name is not provided then class name is used.
This function is used to identify if the object passed as an input is of type contract. It returns true on successful checks.
This function is called before any transaction functions in the smart contract are invoked. You can override the default method and use your own logic instead.
This function is invoked after a particular transaction function is invoked. You can override the default method and use your own logic instead.
This function is invoked when a requested transaction function does not exist in the written smart contract. You can override the default method and use your own logic instead.
This function is used to create your own custom transaction object which can be accessed for additional processing when transaction functions are invoked.
This is a simple getter function which returns the contract name.
II- Contract Structure in Chaincode
Tha fabric-contract-api and fabric-shim are the two important dependencies that are required to write the chaincode in Hyperledger fabric. When we start the development of the chaincodes in node.js, we add dependencies in package.json file as follows:
The start command fabric-chaincode-node start is used by peers in the network for starting the chaincode which is exported in the index.js file which is the main entrypoint.
The lib directory can contain one or more smart contracts derived from the Contract class. Additionally we can also have a test directory which will include test cases to test the contracts. The chaincode folder structure is as follows:
III- The ChaincodeStub Interface in Chaincode
In Hyperledger Fabric, every chaincode implements the chaincode interface defined in the Shim package and defines two important methods which are called when a transaction is requested:
As you can see, the interface implements two methods: Init and Invoke. The Init is called to initialize the internal data of the chaincode when it is first deployed in the Docker container. However, the Invoke method is used by subsequent transactions for modifying or reading the ledger; note that the modified state variables as a result of transaction operation are committed to the ledger only when the transaction is committed.
Both methods accept a single parameter named stub of type chaincodeStubInterface. In chaincode, every function has a ctx field which is a context object that contains chaincodeStubInterface implementation which provides essential APIs to interact with world state, private collection, emit events, Cross-Chaincode Invocation, etc.
IV- Distributed Ledger Data Representation in Chaincode
In Hyperledger Fabric, Ledger is an integral component in which data is added and modified through consensus of the nodes participating in the network. It has two different but related parts – World State and Blockchain.
World State – A type of database that holds current and latest values. A world state helps chaincode in fetching the current value of data quickly rather than traversing an entire transaction log and then calculating it. The data or states recorded in the ledger are represented as key value pairs. There are two database options available – Leveldb and Couchdb.
Blockchain – All the changes that take place on the current world state are recorded as a transaction log. The transactions formed are collected inside the block and appended to the blockchain which allows anyone to view the history of the state of the asset stored. A blockchain data structure is immutable; meaning once changes are made they cannot be modified; if the modification is made it will represent a new state.
Simple Interaction with Ledger Data- putState, getState and delState
As we know, ledger states are represented as key value pairs. The simplest way of interacting with them is by using APIs provided by chaincodeStub Interface. We will look into the most important and basic APIs for querying, modifying and deleting the states of the ledger.
putState – The API requires a key (string) and a value (byte array). It is used to form a data write proposal to be committed on the ledger; note that the ledger is affected only after the transaction is validated and successfully committed by peers in the network. The key should not be empty and not start with an empty character.
getState – The API requires a key (string). It returns the corresponding value to the key from the ledger. If the key does not exist in the state database, it returns the empty array.
delState – The API requires a key (string). It forms a proposal to delete the record from the ledger state. After the operation is successful the key and its corresponding value is marked as deleted from the world state. However, the record will still be available in the Blockchain and can be retrieved.
V- Logging in Chaincode
Logging is the most important part in the software development process. It helps you in making important decisions by analyzing the data, resolving errors and detecting problems early. Chaincode logging is the ultimate responsibility of a chaincode developer.
Any logging utilities that print messages to stdout or stderr can be examined in the relevant Docker container by writing the below command:
In this article, we learned the importance of chaincode in building private blockchain applications with Hyperledger Fabric. We also reviewed all essential aspects of chaincode including its contract class, structure, and more.
If you are preparing for the Certified Hyperledger Fabric Developer (CHFD) exam, this article is a great starting point. As a follow-up of this article you need to explore the chaincode lifecycle as well as running simple to complex queries on ledger data. Also, it is good to explore the chaincode external launcher feature which was introduced in Hyperledger Fabric V2 via Node.JS SDK. A relevant training course would be Hyperledger Fabric for Developers (LFD272).
About Matt Zand
Matt is a serial entrepreneur and the founder of five tech startups: RealBig, DC Web Makers, HashFlow, Coding Bootcamps and High School Technology Services. He is a leading author of Hands-on Smart Contract Development with Hyperledger Fabric book by O’Reilly Media. He has written more than 100 technical articles and tutorials on blockchain development for Hyperledger, Ethereum and Corda R3 platforms at sites such as IBM, SAP, Alibaba Cloud, Hyperledger, The Linux Foundation, and more. At RealBig, he leads a team of blockchain experts for building a virtual league that integrates NFT with DeFi while raising funds via ICO . You can connect with him on Linkedin: https://www.linkedin.com/in/matt-zand-64047871
About Navil Rodrigues
Navil is a Certified Hyperledger Fabric Developer (CHFD) from the Linux Foundation. Currently, he is working as a Blockchain Developer at Mckinley Rice, where he works on writing and implementing smart contracts for Ethereum and Sidechains like Binance Smart Chain, Polygon, and more. He also dabbles in developing and designing ICO contracts and Bridging solutions to connect different chains. In addition, he has experience in building Full Stack and Decentralized Applications from start to finish. You can connect with him on LinkedIn:https://www.linkedin.com/in/navil-rodrigues-295784a4/