- Published on
Working with Hyperledger Fabric Chaincode
- Authors
- Name
- Yair Mark
- @yairmark
Today we got to the point where we could start deploying chaincode (the Fabric equivalent of smart contracts) to Hyperledger Fabric. This experience demonstrated to me more clearly how the Fabric peer and orderer interact with one another.
A client would communicate with the peer and the orderer. The client would likely be in the form of an application communicating with the Fabric components using one of the Fabric SDKs or the Fabric peer cli tool.
The general chaincode life cycle is as follows:
- Install the chaincode on peers that will interact with the code (validators)
- Instantiate (deploy) the chaincode
- Reading data from the blockchain via the chaincode
- Writing data to the blockchain via the chaincode
Installing the Chaincode
This involves:
- The client sending the code they want to eventually end up on the chain to endorsing peers (these are peers that will validate code execution)
- These peers are specified in the endorsement policy which is needed as part of the chaincode instantiation process (which is detailed below)
- The peer validates the code:
- A success code is returned if successful
- Otherwise an error response is returned
A small snippet of the parts of the API that would do this is:
await client.installChaincode(chainCodeRequest)
This outputs the following in the logs:
2018-10-02 15:04:29.731 UTC [lscc] executeInstall -> INFO 0b9 Installed Chaincode [your-chain-code] Version [v1] to peer
2018-10-02 15:04:31.485 UTC [golang-platform] GenerateDockerBuild -> INFO 0ba building chaincode with ldflagsOpt: '-ldflags "-linkmode external -extldflags '-static'"'
2018-10-02 15:04:31.485 UTC [golang-platform] GenerateDockerBuild -> INFO 0bb building chaincode with tags:
This can be represented by the following sequence diagram:
sequenceDiagram
Client ->> Peer: Chain code sent
Peer ->> Peer: Chain code validated
alt is valid
Peer ->> Peer: Chain code installed on validating peers
Peer ->> Client: Success code
else is invalid
Peer ->> Client: Error
end
Installing is basically validating that the code is correct. The code is not put onto the chain at this point. But is installed onto peers that will be responsible for validating code (known as endorsing peers).
Associated links
Instantiating or Writing to Chaincode
This involves:
- The client sending a proposal to instantiate code to the peer/s which includes a number of parameters including the endorsement policy
- If this is an invocation request (i.e. writing to the chain) then a function name needs to be provided together with 0 or more args to this function
- The peer/s validating this proposal:
- If valid then send on to the orderer
- If invalid then return an error response to the client
- The orderer ordering the transactions based on the context of the current channel
- The orderer returning the blocks to committing peers
- Committing peers validating the chaincode against the endorsement policy (which was specified during when the code proposal was submitted in step 1)
- The peer then adding a block to its ledger as described here
- If there was an error validating the code then a reason code is included with this block
- A response message with the details of the execution being returned to the client
A small snippet of the parts of the API that would do this is:
/* Instantiate chaincode */
results = await channel.sendInstantiateProposal(request, 600000)
//if results status is a 200 then proceed
await channel.sendTransaction(ordererReq, 60000)
This outputs the following in the logs:
2018-10-02 15:04:29.731 UTC [lscc] executeInstall -> INFO 0b9 Installed Chaincode [your-chain-code] Version [v1] to peer
2018-10-02 15:04:31.485 UTC [golang-platform] GenerateDockerBuild -> INFO 0ba building chaincode with ldflagsOpt: '-ldflags "-linkmode external -extldflags '-static'"'
2018-10-02 15:04:31.485 UTC [golang-platform] GenerateDockerBuild -> INFO 0bb building chaincode with tags:
...
2018-10-02 15:13:33.509 UTC [kvledger] CommitWithPvtData -> INFO 0bf Channel [your-channel]: Committed block [29] with 1 transaction(s)
This can be represented by the following sequence diagram:
sequenceDiagram
Client ->> Peer: code instantiate proposal
Peer ->> Peer: proposal validated by all endorsing peers
alt is valid
Peer ->> Peer: Code signed
Peer ->> Orderer: Signed code
Orderer ->> Orderer: Confirm code signed by peer and other checks
Orderer ->> Orderer: Order transactions based on the current channel
Orderer ->> Peer: Ordered transactions
Peer ->> Peer: Validate chaincode against endorsement policy
Peer ->> Orderer: Transaction based on proposal
Peer ->> Peer: Add block to ledger (include error reason code if there was an error)
Peer ->> Client: Message with details of the transaction
else is invalid
Peer ->> Client: Error
end
The client can then use the chainID they assigned to their code to interact with it.
Associated links
- NodeJS SDK API - sendInstantiateProposal
- NodeJS SDK API - sendTransaction
- Instantiation Example Code
- Writing/Invoking Example Code
Reading data from the blockchain via the chaincode
This involves:
- The client sending a request to the peer containing:
- The target peer
- The name of the chaincode
- The name of the function they want to invoke on the chaincode
- The arguments that go to the chaincode function
- The peer runs executes the target function and returns the associated data or an error
A small snippet of the parts of the API that would do this is:
await channel.queryByChaincode(request)
This can be represented by the following sequence diagram:
sequenceDiagram
Client ->> Peer: readRequest(fnName, args)
Peer ->> Peer: Execute function with given arguments and name
alt is valid
Peer ->> Client: Result of executing function against chain
else is invalid
Peer ->> Client: Error
end