Fabric 2.0 lifecycle based chaincode mangement
Chaincode as an external service
Fabric v2.0 supports chaincode deployment and execution outside of Fabric that enables users to manage a chaincode runtime independently of the peer.
In this case, chaincode doesn’t have to be deployed on every peer. Instead it couldbe deplyed as a service for all peers. Therefore, it’s lifecycle can be managed outside the peer.
Using this chaincode as an external service model, installing the chaincode on each peer is no longer required.
New format of CC package
As part of the new lifecycle introduced with Fabric 2.0, the chaincode package format changed from serialized protocol buffer messages to a gzip compressed POSIX tape archive. Chaincode packages created with peer lifecycle chaincode package use this new format.
With the Fabric v2.0 chaincode lifecycle, chaincode is packaged and installed in a .tar.gz format. The following myccpackage.tgz archive demonstrates the required structure:
$ tar xvfz myccpackage.tgz
metadata.json
code.tar.gz
New CLI for fabric 2.0 lifecycle
peer lifecycle chaincode
Usage:
peer lifecycle chaincode [command]
Available Commands:
approveformyorg Approve the chaincode definition for my org.
checkcommitreadiness Check whether a chaincode definition is ready to be committed on a channel.
commit Commit the chaincode definition on the channel.
getinstalledpackage Get an installed chaincode package from a peer.
install Install a chaincode.
package Package a chaincode
querycommitted Query the committed chaincode definitions by channel on a peer.
queryinstalled Query the installed chaincodes on a peer.
peer lifecycle chaincode package
peer lifecycle chaincode package abc.tar.gz -p github.com/hyperledger/fabric-samples/chaincode/fabcar/go --label label1
Build the chaincode tar ball, which contains the source code and the meta file.
metadata.json
code.tar.gz
peer lifecycle chaincode install
peer lifecycle chaincode install abc.tar.gz
Install the chaincode. It will build a docker image like before if the external builder is not there.
lifecycle InstallChaincode() will be invoked.
Call stack
github.com/hyperledger/fabric/core/chaincode/lifecycle.(*ExternalFunctions).InstallChaincode at lifecycle.go:554
github.com/hyperledger/fabric/core/chaincode/lifecycle.(*Invocation).InstallChaincode at scc.go:258
runtime.call64 at asm_amd64.s:540
reflect.Value.call at value.go:460
reflect.Value.Call at value.go:321
github.com/hyperledger/fabric/core/dispatcher.(*Dispatcher).Dispatch at dispatcher.go:66
github.com/hyperledger/fabric/core/chaincode/lifecycle.(*SCC).Invoke at scc.go:207
github.com/hyperledger/fabric/vendor/github.com/hyperledger/fabric-chaincode-go/shim.(*Handler).handleTransaction at handler.go:209
github.com/hyperledger/fabric/vendor/github.com/hyperledger/fabric-chaincode-go/shim.(*Handler).handleTransaction-fm at handler.go:195
github.com/hyperledger/fabric/vendor/github.com/hyperledger/fabric-chaincode-go/shim.(*Handler).handleStubInteraction at handler.go:159
runtime.goexit at asm_amd64.s:1357
- Async stack trace
github.com/hyperledger/fabric/vendor/github.com/hyperledger/fabric-chaincode-go/shim.(*Handler).handleReady at handler.go:620
peer lifecycle getinstalledpackage
peer lifecycle chaincode getinstalledpackage --package-id cc:93866b6738964b04107b889fdf7c093bb7312cedd77eab4cc07430455e72c2da output
GetInstalledChaincodePackage() will be invoked.
peer lifecycle chaincode queryinstalled
You can find the package ID of a chaincode by using the peer lifecycle chaincode queryinstalled command to query your peer.
peer lifecycle chaincode queryinstalled
Package ID: 93866b6738964b04107b889fdf7c093bb7312cedd77eab4cc07430455e72c2da, Label: cc
QueryInstalledChaincodes() will be invoked.
peer lifecycle chaincode approveformyorg
After you install the chaincode package, you need to approve a chaincode definition for your organization. The definition includes the important parameters of chaincode governance such as the name, version, and the chaincode endorsement policy.
peer lifecycle chaincode approveformyorg -o localhost:7050 --channelID test1 --name ccname --package-id cc:93866b6738964b04107b889fdf7c093bb7312cedd77eab4cc07430455e72c2da --version 1.0 --sequence 1
lifecycle ApproveChaincodeDefinitionForMyOrg() will be invoked to do the approval.
Note: --package-id has to be included. Also we can specify a name for the chaincode here.
Call stack
github.com/hyperledger/fabric/core/chaincode/lifecycle.(*ExternalFunctions).ApproveChaincodeDefinitionForOrg at lifecycle.go:488
github.com/hyperledger/fabric/core/chaincode/lifecycle.(*Invocation).ApproveChaincodeDefinitionForMyOrg at scc.go:396
runtime.call64 at asm_amd64.s:540
reflect.Value.call at value.go:460
reflect.Value.Call at value.go:321
github.com/hyperledger/fabric/core/dispatcher.(*Dispatcher).Dispatch at dispatcher.go:66
github.com/hyperledger/fabric/core/chaincode/lifecycle.(*SCC).Invoke at scc.go:207
github.com/hyperledger/fabric/vendor/github.com/hyperledger/fabric-chaincode-go/shim.(*Handler).handleTransaction at handler.go:209
github.com/hyperledger/fabric/vendor/github.com/hyperledger/fabric-chaincode-go/shim.(*Handler).handleTransaction-fm at handler.go:195
github.com/hyperledger/fabric/vendor/github.com/hyperledger/fabric-chaincode-go/shim.(*Handler).handleStubInteraction at handler.go:159
runtime.goexit at asm_amd64.s:1357
- Async stack trace
github.com/hyperledger/fabric/vendor/github.com/hyperledger/fabric-chaincode-go/shim.(*Handler).handleReady at handler.go:620
peer lifecycle chaincode checkcommitreadiness
This command can check whether channel members have approved the same chaincode definition.
peer lifecycle chaincode checkcommitreadiness --channelID test1 -n cc -v 1.0
Chaincode definition for chaincode 'cc', version '1.0', sequence '1' on channel 'test1' approval status by org:
SampleOrg: true
Internally, it will invoke lifecycle CheckCommitReadiness() for querying DB for readiness.
Call stack
github.com/hyperledger/fabric/core/chaincode/lifecycle.(*ExternalFunctions).QueryOrgApprovals at lifecycle.go:547
github.com/hyperledger/fabric/core/chaincode/lifecycle.(*ExternalFunctions).CheckCommitReadiness at lifecycle.go:315
github.com/hyperledger/fabric/core/chaincode/lifecycle.(*Invocation).CheckCommitReadiness at scc.go:439
runtime.call64 at asm_amd64.s:540
reflect.Value.call at value.go:460
reflect.Value.Call at value.go:321
github.com/hyperledger/fabric/core/dispatcher.(*Dispatcher).Dispatch at dispatcher.go:66
github.com/hyperledger/fabric/core/chaincode/lifecycle.(*SCC).Invoke at scc.go:207
github.com/hyperledger/fabric/vendor/github.com/hyperledger/fabric-chaincode-go/shim.(*Handler).handleTransaction at handler.go:209
github.com/hyperledger/fabric/vendor/github.com/hyperledger/fabric-chaincode-go/shim.(*Handler).handleTransaction-fm at handler.go:195
github.com/hyperledger/fabric/vendor/github.com/hyperledger/fabric-chaincode-go/shim.(*Handler).handleStubInteraction at handler.go:159
runtime.goexit at asm_amd64.s:1357
- Async stack trace
github.com/hyperledger/fabric/vendor/github.com/hyperledger/fabric-chaincode-go/shim.(*Handler).handleReady at handler.go:620
peer lifecycle chaincode commit
After a sufficient number of organizations have approved a chaincode definition, one organization can commit the chaincode definition to the channel. If a majority of channel members have approved the definition, the commit transaction will be successful and the parameters agreed to in the chaincode definition will be implemented on the channel.
peer lifecycle chaincode commit -C test1 -n lll -v 1.0
CommitChaincodeDefinition() will be invoked to commit the chaincode. Before commting, lifecycle will check for chaincode approval for the organization.
A docker container will be launched to execute the chaincode.
Call stack
github.com/hyperledger/fabric/core/chaincode/lifecycle.(*ExternalFunctions).CommitChaincodeDefinition at lifecycle.go:331
github.com/hyperledger/fabric/core/chaincode/lifecycle.(*Invocation).CommitChaincodeDefinition at scc.go:502
runtime.call64 at asm_amd64.s:540
reflect.Value.call at value.go:460
reflect.Value.Call at value.go:321
github.com/hyperledger/fabric/core/dispatcher.(*Dispatcher).Dispatch at dispatcher.go:66
github.com/hyperledger/fabric/core/chaincode/lifecycle.(*SCC).Invoke at scc.go:207
github.com/hyperledger/fabric/vendor/github.com/hyperledger/fabric-chaincode-go/shim.(*Handler).handleTransaction at handler.go:209
github.com/hyperledger/fabric/vendor/github.com/hyperledger/fabric-chaincode-go/shim.(*Handler).handleTransaction-fm at handler.go:195
github.com/hyperledger/fabric/vendor/github.com/hyperledger/fabric-chaincode-go/shim.(*Handler).handleStubInteraction at handler.go:159
runtime.goexit at asm_amd64.s:1357
- Async stack trace
github.com/hyperledger/fabric/vendor/github.com/hyperledger/fabric-chaincode-go/shim.(*Handler).handleReady at handler.go:620
Test chaincode invocation
peer chaincode invoke -o localhost:7050 -C test1 -n ccname -c {\"function\":\"InitLedger\",\"Args\":[]}
Chaincode invoke successful. result: status:200
// Invoke will invoke chaincode and return the message containing the response.
// The chaincode will be launched if it is not already running.
func (cs *ChaincodeSupport) Invoke(txParams *ccprovider.TransactionParams, chaincodeName string, input *pb.ChaincodeInput) (*pb.ChaincodeMessage, error) {
ccid, cctype, err := cs.CheckInvocation(txParams, chaincodeName, input)
if err != nil {
return nil, errors.WithMessage(err, "invalid invocation")
}
h, err := cs.Launch(ccid)
if err != nil {
return nil, err
}
return cs.execute(cctype, txParams, chaincodeName, input, h)
}
Call stack
github.com/hyperledger/fabric/core/chaincode.(*Handler).serialSendAsync at handler.go:306
github.com/hyperledger/fabric/core/chaincode.(*Handler).Execute at handler.go:1207
github.com/hyperledger/fabric/core/chaincode.(*ChaincodeSupport).execute at chaincode_support.go:272
github.com/hyperledger/fabric/core/chaincode.(*ChaincodeSupport).Invoke at chaincode_support.go:202
github.com/hyperledger/fabric/core/chaincode.(*ChaincodeSupport).Execute at chaincode_support.go:155
github.com/hyperledger/fabric/core/endorser.(*SupportImpl).Execute at support.go:126
github.com/hyperledger/fabric/core/endorser.(*Endorser).callChaincode at endorser.go:119
github.com/hyperledger/fabric/core/endorser.(*Endorser).SimulateProposal at endorser.go:187
github.com/hyperledger/fabric/core/endorser.(*Endorser).ProcessProposalSuccessfullyOrError at endorser.go:397
github.com/hyperledger/fabric/core/endorser.(*Endorser).ProcessProposal at endorser.go:340
github.com/hyperledger/fabric/core/handlers/auth/filter.(*expirationCheckFilter).ProcessProposal at expiration.go:61
github.com/hyperledger/fabric/core/handlers/auth/filter.(*filter).ProcessProposal at filter.go:32
github.com/hyperledger/fabric/vendor/github.com/hyperledger/fabric-protos-go/peer._Endorser_ProcessProposal_Handler.func1 at peer.pb.go:107
github.com/hyperledger/fabric/internal/peer/node.unaryGrpcLimiter.func1 at grpc_limiters.go:51
github.com/hyperledger/fabric/vendor/github.com/grpc-ecosystem/go-grpc-middleware.ChainUnaryServer.func1.1.1 at chain.go:25
github.com/hyperledger/fabric/common/grpclogging.UnaryServerInterceptor.func1 at server.go:92
github.com/hyperledger/fabric/vendor/github.com/grpc-ecosystem/go-grpc-middleware.ChainUnaryServer.func1.1.1 at chain.go:25
github.com/hyperledger/fabric/common/grpcmetrics.UnaryServerInterceptor.func1 at interceptor.go:31
github.com/hyperledger/fabric/vendor/github.com/grpc-ecosystem/go-grpc-middleware.ChainUnaryServer.func1.1.1 at chain.go:25
github.com/hyperledger/fabric/vendor/github.com/grpc-ecosystem/go-grpc-middleware.ChainUnaryServer.func1 at chain.go:34
github.com/hyperledger/fabric/vendor/github.com/hyperledger/fabric-protos-go/peer._Endorser_ProcessProposal_Handler at peer.pb.go:109
github.com/hyperledger/fabric/vendor/google.golang.org/grpc.(*Server).processUnaryRPC at server.go:995
github.com/hyperledger/fabric/vendor/google.golang.org/grpc.(*Server).handleStream at server.go:1275
github.com/hyperledger/fabric/vendor/google.golang.org/grpc.(*Server).serveStreams.func1.1 at server.go:710
runtime.goexit at asm_amd64.s:1357
- Async stack trace
github.com/hyperledger/fabric/vendor/google.golang.org/grpc.(*Server).serveStreams.func1 at server.go:708
\