Hyperledger Fabric is an open-source distributed blockchain implementation. An important piece of its architecture is chaincode.
The core of any blockchain platform is the ledger, a shared, tamper-proof history of the universe. Specifically, it’s a record of all transactions within its scope. Chaincode is the term for programs that run on top of the blockchain to implement the business logic of how applications interact with the ledger. When a transaction is proposed, it triggers chaincode that decides what state change should be applied to the ledger. For example, chaincode for the sale of bitcoin would check that the seller actually has bitcoin to sell.
Since chaincode implements logic agreed on by members of the blockchain network, it is sometimes called smart contracts. However, chaincode can be used to implement functionality beyond smart contracts. The only constraint is that all chaincodes are controlled by a Peer according to the sameinterface — which is flexible enough that Hyperledger Fabric actually uses chaincodes to implement some system-level features.
What chaincode looks like
Each chaincode is implemented as an isolated program that maintains its own private state on the ledger. (Note: A chaincode may allow other chaincodes to query its private state.) Chaincodes are essentially arbitrary code, but they conform to a common interface that the Peer uses to control them.
Each chaincode implements an
Init method and an
Invoke method. The first is used for setup, and the second is used to do the main work of the chaincode. Both methods accept a
ChaincodeStubInterface parameter, which carries a client for interacting with the ledger and for querying other chaincodes.
ChaincodeStubInterface also holds a list of arguments passed to the chaincode, which allows the chaincode to implement different behaviors for different scenarios. For example, a single chaincode may implement multiple functions. A client can pass arguments to select which specific chaincode function it wants to invoke — just like passing subcommands to a command-line utility (e.g. the
In some scenarios, multiple entities must agree on a chaincode before it can be used. Each entity must be able to review the source code of the chaincode and sign it to prevent tampering. The package format used to pass around the chaincode implementation is called
ChaincodeDeploymentSpec, which includes the source code, the policies for instantiating (setting up and running) the chaincode application, and the list of entities that have agreed on the chaincode.
Once a chaincode has been properly endorsed, it can be installed and instantiated on Peers in the network. During the instantiation process, the Peer uses Docker to run a container with the chaincode inside. The Peer is responsible for managing the chaincode container’s lifecycle and networking.
This detail is the source of some contention, as it gets in the way of running Hyperledger Fabric on Kubernetes (jira.hyperledger.org/browse/FAB-7406). Specifically, Kubernetes is designed around Pods, which have their own networking model — different from plain Docker containers. Furthermore, since chaincode containers are managed directly using Docker, they are invisible to Kubernetes. It’s likely that a small change to this part of the architecture would help Hyperledger Fabric be compatible with more platforms.
There’s a special kind of chaincode that follows a different lifecycle. System chaincode runs as part of the Peer process, not in a separate container. It’s used to implement low-level ledger features like the endorser system, query system, and validation system. Because these features are so fundamental, the system chaincodes that implement them are deployed when the Peer starts (instead of being dynamically added later like other chaincodes).
Chaincode implements higher-level functionality on top of the blockchain ledger. There are two kinds of chaincode, both running under a Peer’s control. System chaincode is part of the Peer process. Normal chaincode is a separate container managed by the Peer. This arrangement works with plain Docker, but not in Kubernetes (without a messy workaround).