FAB-7086 outlines a proposal in which the Init function is removed from the chaincode API in order to support different instantiation mechanics. This proposal, developed in coordination with muralisr, preserves the benefits of the config tree in FAB-6042, while also preserving the existing lifecycle characteristics of atomic instantiation and enforcement of instantiation policy.
The proposed workflow for deploying a chaincode is as follows.
- The channel is initialized, and in the genesis block, a resources config tree contains a Chaincodes group with a mod_policy, defaulted to /Channel/Application/Admins
- A chaincode is installed via LSCC, or an installed chaincode is queried using the LSCC to retrieve the metadata for the chaincode.
- The client retrieves the current resources tree, and adds a new chaincode group to the resources tree, as described in
FAB-6042, this modification must satisfy the mod_policy of the chaincodes group, and the chaincode is defined with the metadata from (2) and the desired endorsement policy.
- The client submits the resource update to the orderer, it is propagated through the blockchain, and committed at the peer. When it commits successfully, the chaincode is now defined.
- The client crafts a traditional LSCC transaction containing the name, version, and arguments for instantiation. The LSCC checks that the chaincode is defined for the channel in the resources tree, checks the locally defined instantiation policy in the chaincode package, and does a chaincode-to-chaincode invocation of Init (as it does today). The resulting read/write set includes an 'instantiated' bit in the LSCC table, as well as some representation of the chaincode metadata it was instantiated with.
- The client sends the LSCC transaction to peers, collecting enough endorsements to satisfy the endorsement policy as specified in the chaincode metadata in the resources tree.
- The client sends the LSCC transaction to ordering, which propagates to the peers through the blockchain. This LSCC transaction is validated that the metadata in the resource tree is at the same level, and the usual MVCC checks prevent double Init invocations.
- The client performs a normal invoke. The peer checks that the chaincode is defined, and that the chaincode has been instantiated at the current level of metadata in the resources tree.
This proposal leaves the majority of the existing v1.0 lifecycle characterstics in place, including the atomic instantiation and Init call. It does inject an additional 'configure' step which defines chaincodes for a channel after they have been installed, but before they are instantiated. This additional configuration step is what allows us to break the chicken and egg problem which caused problems in the v1.0 lifecycle.
1) Installation of the chaincode bytes is an administrative action performed on individual peers.
2) While chaincode must be installed on a peer in order for it to endorse transactions, peers do not need to have chaincode installed in order to validate and commit transactions for a given chaincode. This is due to the fact that what gets sent through the orderer is actually the read-write set and not that actual chaincode invocation. Because of this, you cannot "include" configuration about a chaincode (i.e. endorsement policy) as part of installation. You also cannot use the chaincode endorsement model alone to bootstrap the initial endorsement policy for a chaincode (the chicken and egg problem which Jason Yellick refers to in the description). Endorsement is also not an approval workflow model - it is an agreement protocol on output given a set of inputs. This is why the "resource configuration" is required (note that this will go to all peers in a channel not just the ones with chaincode installed).