public static BigInteger getTransactionValue(byte tokenType, byte[] receiver) { PbEntity.TokenType token = PbEntity.getStandardTokenType(); Transaction tx = ExecutionEngine.ScriptContainer as Transaction; TransactionOutput[] outputs = tx.GetOutputs(); BigInteger result = 0; foreach (TransactionOutput output in outputs) { byte[] scriptHash = output.ScriptHash; if (!scriptHash.Equals(receiver)) { continue; } byte[] assetid = output.AssetId; //Temperately only support NEO and GAS byte type = token.INVALID; if (assetid.Equals(NeoID)) { type = token.NEO; } else if (assetid.Equals(GasID)) { type = token.GAS; } if (tokenType != type) { continue; } result += output.Value; } return(result); }
public static object resolvePaymentByConditions(byte[] resolvePayRequestBs) { PbChain.ResolvePayByConditionsRequest resolvePayRequest = new PbChain.ResolvePayByConditionsRequest(); resolvePayRequest = (PbChain.ResolvePayByConditionsRequest)Helper.Deserialize(resolvePayRequestBs); PbEntity.ConditionalPay pay = Helper.Deserialize(resolvePayRequest.condPay) as PbEntity.ConditionalPay; PbEntity.TransferFunction function = pay.transferFunc; byte funcType = function.logicType; BigInteger amount = 0; PbEntity.TransferFunctionType TransferFunctionType = PbEntity.getTransferFunctionType(); if (funcType == TransferFunctionType.BOOLEAN_AND) { amount = _calculateBooleanAndPayment(pay, resolvePayRequest.hashPreimages); } else if (funcType == TransferFunctionType.BOOLEAN_OR) { amount = _calculateBooleanOrPayment(pay, resolvePayRequest.hashPreimages); } else if (_isNumericLogic(funcType)) { amount = _calculateNumericLogicPayment(pay, resolvePayRequest.hashPreimages, funcType); } else { BasicMethods.assert(false, "error"); } byte[] payHash = SmartContract.Sha256(resolvePayRequest.condPay); _resolvePayment(pay, payHash, amount); return(true); }
public static object depositNEO(byte[] walletId) { BasicMethods.assert(BasicMethods._isByte32(walletId), "walletId is not byte32"); PbEntity.TokenType token = PbEntity.getStandardTokenType(); BigInteger value = LedgerStruct.getTransactionValue(token.NEO, ExecutionEngine.ExecutingScriptHash); BasicMethods.assert(value >= 0, "amount is less than zero"); _whenNotPaused(); BasicMethods.assert(_updateBalance(walletId, LedgerStruct.NeoAddress, value, getStandardMathOperation().add), "updateBalance failed"); DepositToWallet(walletId, LedgerStruct.NeoAddress, value); return(true); }
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 bool _isNumericLogic(byte _funcType) { PbEntity.TransferFunctionType TransferFunctionType = PbEntity.getTransferFunctionType(); return(_funcType == TransferFunctionType.NUMERIC_ADD || _funcType == TransferFunctionType.NUMERIC_MAX || _funcType == TransferFunctionType.NUMERIC_MIN); }
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); } }