It is desirable to have a chaincode calls other chaincodes during simulation. Other chaincodes (callees) may be in the same channel or different channels with the caller. The call may be read-only (query) or write.
This feature can be very complex, especially when involving writes, which is quite similar to multi-phase commit in relational databases.
We will divide the work into 3 phases:
2) Write on same channel
3) Write on different channels
A chaincode may call other chaincodes on any channels in the same transaction context, where each callee may return a [Response](https://github.com/hyperledger/fabric/blob/master/protos/peer/proposal_response.proto) object. The caller is responsible for interpreting the object in the chaincode logic, and this object is not part of the MVCC unless the caller chaincode writes it to the ledger (ie using putState). Since the call is within the same transaction context, the security check will be based on the transactor but against the callee's channel. So if the transactor doesn't have reader access to the callee's channel, the call will fail.
The callees establish their own individual rw-sets within the caller's transaction context, so committing this transaction will involve multiple chaincode's rw-sets on 1 MVCC check; that is, if exists any key-version check failure from any involved chaincodes, the whole transaction will fail.
In this case, we can't use the same transaction context since the w-sets are on different channels (ledgers). The caller has to create sub-transactions (aka child or nested transactions) on behalf of the transactor to record the rw-sets on each associated channel. However, since there are potentially multiple sub-transactions, we need a transaction monitor to atomically coordinate the commit – either all fail or all succeed.
|Chaincode calling chaincode read-only||Closed|
|Chaincode calling chaincode on same channel with writes||Closed|
|Prevent called chaincode on a different channel to write states||Closed||Unassigned|