Cross-Chaincode Invocation
The fabric-shim API provides a possibility for a chaincode to invoke another chaincode even if it is instantiated in a different channel. This can be helpful in case of data dependencies between chaincodes or channels. For example, we can have a dashboard of goods in a common channel visible to everyone in the network and a number of bilateral channels to record private deals on those goods between certain participants. In this scenario, it is necessary to track the goods status in the common channel to avoid double-spending and ensure goods are sold only once.
The ChaincodeStub interface implements cross-chaincode invocations using the invokeChaincode function:
invokeChaincode(chaincodeName: string, args: string[], channel: string): Promise<ChaincodeResponse>
invokeChaincode calls the specified chaincode method using the same, already existing transaction. In other words, a chaincode calling another chaincode does not create a new transactional context. This fact implies some limitations for cross-chaincode calls.
Let A and B be the calling and the called chaincodes respectively. Then, the following statements about cross-chaincode invocations are true.
If A = B, i.e., A tries to call itself using invokeChaincode, then an error will occur.
When a chaincode is running, it is assigned a unique identifier in the network. Therefore, a chaincode trying to invoke itself will result in an error, because the unique ID is already taken.
Though the case above is artificial (you can simply replace invokeChaincode by a direct function call in A), the statement can be generalized to become useful. __
_If_ **A** _calls_ **B.foo**_, which internally, via a sequence of the_ **invokeChaincode\(\)** _method, calls and invokes_ **A.bar**_, then an error will occur._
If A and B are in the same channel, and A invokes B.foo, then all the changes made in B.foo will be applied to B’s state.
Because A and B are in the same channel, the read-write sets of B can be added to the transactional context initiated in A without violation of any trust assumptions (as long as all endorsement policies of involved chaincodes are satisfied).
This feature helps us to effectively split the codebase into separate reusable modules instead of having a single monolithic chaincode per channel.
If A and B are in different channels, and A invokes B.foo, then no changes made in B.foo will be applied to B’s state.
In this scenario, changes made by B will not become part of the transaction initiated by A, because A and B reside in different channels. Nevertheless, the response from B.foo will be returned to A, which allows A to process and use any data returned from B. Therefore, in case the chaincodes reside in different channels, the cross-channel invocation is a query invocation from the caller to the callee.
You can experiment with cross-chaincode invocations using the ChaincodeInteractionContract implementation available in the Resources tab in the Menu.
Last updated
Was this helpful?