In each cc module we basically send value from cc inputs to cc outputs.
Cc value lifecycle usually begins when we create cc outputs from normal inputs, then transfer cc value from cc inputs to cc outputs, then cc value can be sent to normal outputs.
It is critical that cc value transfers always go in a controlled way.
It is said very well about this in CCcustom.cpp source file:
IMPORTANT: make sure that all CC inputs and CC outputs are properly accounted for and reconcile to the satoshi. The built in utxo management will enforce overall vin/vout constraints but it wont know anything about the CC constraints. That is what your Validate function needs to do.
Generally speaking, there will be normal coins that change into CC outputs, CC outputs that go back to being normal coins, CC outputs that are spent to new CC outputs.
Make sure both the CC coins and normal coins are preserved and follow the rules that make sense. It is a good idea to define specific roles for specific vins and vouts to reduce the complexity of validation.
So like the built in komodod utxo management ensures tx value flow from inputs to outputs we should provide the same for each cc module. We cannot allow to lose or inject not a satoshi because each cc satoshi might mean a precious resource (if cc tx is a non-fungible token spending for example).
In addition we should remember, that in Antara (cc) modules tx data is usually segregated by an id (aka plan-id or funding-id or also token-id or other kind of id, all of which are usually the txid of the first cc transaction). So we should not allow to accidentally mix cc value from different ids (unless it is done by design).
I would like to propose a basic algorithm to ensure cc value flow in cc txns.
CAmount IsMyCCVout(tx, nvout, evalcode, planid). 'Is my cc vout?'
This function is for calling when a cc module needs to add cc inputs to a new transaction.
IsMyCCVout checks if this nvout in the tx is a valid cc vout, ensuring the following:
* was the tx validated by the cc module? check if it has a cc vin with this evalcode
* does the tx belong to the planid? check the planid in the tx opreturn
* or is this a first-time creation cc tx? compare its txid with the planid
IsMyCCVout should return the vout amount if it is a valid cc vout, 0 if this is not a cc vout or -1 if it is not my planid.
CAmount CalcCCExactAmount(tx, evalcode, planid). 'Calculate tx cc value balance'
This function should be called inside the cc validation code. Its task is to calculate total cc inputs value (for cc vins) and total cc output value (for cc vouts) and return the difference to the caller. Good thing is that for checking whether it is my cc input or output this function might call
CalcCCExactAmount returns the balance and the validation code should verify that balance to ensure it to the satoshi. For example, if all cc value should go only to cc outputs the returned balance must be checked as 0.
IsMyCCVout returns '-1' this tx should be rejected as it tries to mix different planids.
This approach allows to handle basic cc value management and could be a core code for all Antara modules. Like the basic komodod code ensures total value flow from inputs to outputs for each transaction, this two functions would allow to do the same for the cc value.