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); } }