private static BigInteger _calculateBooleanOrPayment(PbEntity.ConditionalPay _pay, byte[][] _preimages)
        {
            int  j = 0;
            bool hasContractCond     = false;
            bool hasTrueContractCond = false;

            PbEntity.ConditionType ConditionType = PbEntity.getConditionType();
            PbEntity.Condition[]   conditions    = _pay.conditions;
            for (var i = 0; i < conditions.Length; i++)
            {
                PbEntity.Condition cond = _pay.conditions[i];
                if (cond.conditionType == ConditionType.HASH_LOCK)
                {
                    BasicMethods.assert(SmartContract.Sha256(_preimages[j]) == cond.hashLock, "wrong preimage");
                    j++;
                }
                else if (
                    cond.conditionType == ConditionType.DEPLOYED_CONTRACT ||
                    cond.conditionType == ConditionType.VIRTUAL_CONTRACT
                    )
                {
                    byte[] booleanCondHash      = _getCondAddress(cond);
                    DynamicCallContract dyncall = (DynamicCallContract)booleanCondHash.ToDelegate();
                    BasicMethods.assert((bool)dyncall("isFinalized", new object[] { cond.argsQueryFinalization }), "Condition is not finalized");
                    hasContractCond = true;

                    bool outcome = (bool)dyncall("getOutcome", new object[] { cond.argsQueryOutcome });
                    if (outcome)
                    {
                        hasTrueContractCond = true;
                    }
                }
                else
                {
                    BasicMethods.assert(false, "condition type error");
                }
            }
            if (!hasContractCond || hasTrueContractCond)
            {
                PbEntity.TransferFunction transferFunction = _pay.transferFunc;
                PbEntity.TokenTransfer    tokenTransfer    = transferFunction.maxTransfer;
                PbEntity.AccountAmtPair   accountAmtPair   = tokenTransfer.receiver;
                return(accountAmtPair.amt);
            }
            else
            {
                return(0);
            }
        }
 private static byte[] _getCondAddress(PbEntity.Condition _cond)
 {
     PbEntity.ConditionType ConditionType = PbEntity.getConditionType();
     if (_cond.conditionType == ConditionType.DEPLOYED_CONTRACT)
     {
         return(_cond.deployedContractAddress);
     }
     else if (_cond.conditionType == ConditionType.VIRTUAL_CONTRACT)
     {
         byte[] virtResolverHash     = Storage.Get(Storage.CurrentContext, VirtResolverHashKey);
         DynamicCallContract dyncall = (DynamicCallContract)virtResolverHash.ToDelegate();
         return((byte[])dyncall("resolve", new object[] { _cond.virtualContractAddress }));
     }
     BasicMethods.assert(false, "conditiontype error");
     return(new byte[] { 0x00 });
 }
        private static BigInteger _calculateNumericLogicPayment(PbEntity.ConditionalPay _pay, byte[][] _preimages, byte _funcType)
        {
            int        j              = 0;
            BigInteger amount         = 0;
            bool       hasContracCond = false;

            PbEntity.ConditionType        ConditionType        = PbEntity.getConditionType();
            PbEntity.TransferFunctionType TransferFunctionType = PbEntity.getTransferFunctionType();
            PbEntity.Condition[]          conditions           = _pay.conditions;
            for (var i = 0; i < conditions.Length; i++)
            {
                PbEntity.Condition cond = _pay.conditions[i];
                if (cond.conditionType == ConditionType.HASH_LOCK)
                {
                    BasicMethods.assert(SmartContract.Sha256(_preimages[j]) == cond.hashLock, "wrong preimage");
                    j++;
                }
                else if (
                    cond.conditionType == ConditionType.DEPLOYED_CONTRACT ||
                    cond.conditionType == ConditionType.VIRTUAL_CONTRACT
                    )
                {
                    byte[] numericCondHash      = _getCondAddress(cond);
                    DynamicCallContract dyncall = (DynamicCallContract)numericCondHash.ToDelegate();
                    BasicMethods.assert((bool)dyncall("isFinalized", new object[] { cond.argsQueryFinalization }), "Condition is not finalized");

                    BigInteger outcome = (BigInteger)dyncall("getOutcome", new object[] { cond.argsQueryOutcome });

                    if (_funcType == TransferFunctionType.NUMERIC_ADD)
                    {
                        amount = amount + outcome;
                    }
                    else if (_funcType == TransferFunctionType.NUMERIC_MAX)
                    {
                        amount = max(amount, outcome);
                    }
                    else if (_funcType == TransferFunctionType.NUMERIC_MIN)
                    {
                        if (hasContracCond)
                        {
                            amount = min(amount, outcome);
                        }
                        else
                        {
                            amount = outcome;
                        }
                    }
                    else
                    {
                        BasicMethods.assert(false, "error");
                    }
                    hasContracCond = true;
                }
                else
                {
                    BasicMethods.assert(false, "condition type error");
                }
            }
            PbEntity.TransferFunction transferFunction = _pay.transferFunc;
            PbEntity.TokenTransfer    tokenTransfer    = transferFunction.maxTransfer;
            PbEntity.AccountAmtPair   accountAmtPair   = tokenTransfer.receiver;
            if (hasContracCond)
            {
                BasicMethods.assert(amount <= accountAmtPair.amt, "exceed max transfer amount");
                return(amount);
            }
            else
            {
                return(accountAmtPair.amt);
            }
        }