public static object transferToCelerWallet(byte[] invoker, byte[] from, byte[] walletAddr, byte[] walletId, BigInteger value) { BasicMethods.assert(BasicMethods._isLegalAddress(invoker), "invoker or spender address is illegal"); BasicMethods.assert(BasicMethods._isLegalAddress(from), "from address is illegal"); BasicMethods.assert(BasicMethods._isLegalAddress(walletAddr), "to address is illegal"); BasicMethods.assert(BasicMethods._isByte32(walletId), "walletId is not byte32"); BasicMethods.assert(value >= 0, "amount is less than 0"); BasicMethods.assert(Runtime.CheckWitness(invoker), "CheckWitness failed"); BigInteger approvedBalance = allowance(from, invoker); BasicMethods.assert(value <= approvedBalance, "value is greater than allowance of spender allowed to spend"); Storage.Put(Storage.CurrentContext, ApprovePrefix.Concat(from).Concat(invoker), approvedBalance - value); Approved(from, invoker, allowance(from, invoker)); BigInteger fromBalance = balanceOf(from); BasicMethods.assert(value <= fromBalance, "value is greater than the owner's balance"); Storage.Put(Storage.CurrentContext, BalancePrefix.Concat(from), fromBalance - value); Transferred(from, walletAddr, value); byte[] celerWalletHash = Storage.Get(Storage.CurrentContext, CelerWalletHashKey); byte[] nep5Hash = Storage.Get(Storage.CurrentContext, NEP5HashKey); DynamicCallContract dyncall = (DynamicCallContract)celerWalletHash.ToDelegate(); BasicMethods.assert((bool)dyncall("depositNEP5", new object[] { invoker, walletId, nep5Hash, value }), "transfer NEP5 token to the to the celer wallet failed"); return(true); }
public static void _resolvePayment(PbEntity.ConditionalPay _pay, byte[] _payHash, BigInteger _amount) { BasicMethods.assert(_amount >= 0, "amount is less than zero"); BigInteger now = Blockchain.GetHeight(); BasicMethods.assert(now <= _pay.resolveDeadline, "passed pay resolve deadline in condPay msg"); byte[] payId = _calculatePayId(_payHash, ExecutionEngine.ExecutingScriptHash); byte[] payRegistryHash = getPayRegistryHash(); DynamicCallContract dyncall = (DynamicCallContract)payRegistryHash.ToDelegate(); BigInteger[] res = (BigInteger[])dyncall("getPayInfo", new object[] { payId }); BigInteger currentAmt = res[0]; BigInteger currentDeadline = res[1]; BasicMethods.assert( currentDeadline == 0 || now <= currentDeadline, "Passed onchain resolve pay deadline" ); PbEntity.TransferFunction transferFunction = _pay.transferFunc; PbEntity.TokenTransfer tokenTransfer = transferFunction.maxTransfer; PbEntity.AccountAmtPair accountAmtPair = tokenTransfer.receiver; if (currentDeadline > 0) { BasicMethods.assert(_amount > currentAmt, "New amount is not larger"); if (_amount == accountAmtPair.amt) { BasicMethods.assert((bool)dyncall("setPayInfo", new object[] { _payHash, _amount, now }), "setPayInfo error"); ResolvePayment(payId, _amount, now); } else { BasicMethods.assert((bool)dyncall("setPayAmount", new object[] { _payHash, _amount }), "setPayAmount error"); ResolvePayment(payId, _amount, currentDeadline); } } else { BigInteger newDeadline = 0; if (_amount == accountAmtPair.amt) { newDeadline = now; } else { newDeadline = min(now + _pay.resolveTimeout, _pay.resolveDeadline); BasicMethods.assert(newDeadline > 0, "new resolve deadline is not greater than 0"); } BasicMethods.assert((bool)dyncall("setPayInfo", new object[] { _payHash, _amount, newDeadline }), "setPayInfo error"); ResolvePayment(payId, _amount, currentDeadline); } }
//Transfer NEP5 for a specified addresses private static bool _transfer(byte[] from, byte[] to, BigInteger value) { Storage.Put(Storage.CurrentContext, BalancePrefix.Concat(from), balanceOf(from) - value); byte[] nep5Hash = Storage.Get(Storage.CurrentContext, NEP5HashKey); DynamicCallContract dyncall = (DynamicCallContract)nep5Hash.ToDelegate(); BasicMethods.assert((bool)dyncall("transfer", new object[] { ExecutionEngine.ExecutingScriptHash, to, value }), "transfer NEP5 token to the to as the withdrawer'd like to failed"); Transferred(from, to, 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); } }
public static LedgerStruct.Channel _importChannelMigrationArgs(LedgerStruct.Channel _c, byte[] _fromLedgerAddr, byte[] _channelId) { BasicMethods.assert(BasicMethods._isLegalAddress(_fromLedgerAddr), "invalid contract address"); BasicMethods.assert(BasicMethods._isByte32(_channelId), "invalid _channelId"); DynamicCallContract dyncall = (DynamicCallContract)_fromLedgerAddr.ToDelegate(); LedgerStruct.ChannelMigrationArgs args = (LedgerStruct.ChannelMigrationArgs)dyncall("getChannelMigrationArgs", new object[] { _channelId }); _c.disputeTimeout = args.disputeTimeout; PbEntity.TokenInfo token = new PbEntity.TokenInfo(); token.tokenType = args.tokenType; token.address = args.tokenAddress; _c.token = token; _c.cooperativeWithdrawSeqNum = args.cooperativeWithdrawSeqNum; return(_c); }
public static object withdraw(byte[] withdrawer, BigInteger value) { BasicMethods.assert(BasicMethods._isLegalAddress(withdrawer), "withdrawer address is illegal"); BasicMethods.assert(value >= 0, "amount is less than zero"); BasicMethods.assert(Runtime.CheckWitness(withdrawer), "Checkwitness failed"); byte[] nep5Hash = Storage.Get(Storage.CurrentContext, NEP5HashKey); DynamicCallContract dyncall = (DynamicCallContract)nep5Hash.ToDelegate(); BasicMethods.assert((BigInteger)dyncall("balanceOf", new object[] { ExecutionEngine.ExecutingScriptHash }) >= value, "the contract accout nep5 balance not enough"); BasicMethods.assert(balanceOf(withdrawer) >= value, "withdrawer does not have enough balance"); BasicMethods.assert(_transfer(withdrawer, withdrawer, value), "withdraw nep5 token failed"); return(true); }
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 }); }
public static object deposit(byte[] depositer, byte[] receiver, BigInteger amount) { BasicMethods.assert(BasicMethods._isLegalAddress(depositer), "depositer address is illegal"); BasicMethods.assert(BasicMethods._isLegalAddress(receiver), "receiver address is illegal"); BasicMethods.assert(amount >= 0, "amount is less than 0"); BasicMethods.assert(Runtime.CheckWitness(depositer), "Checkwitness failed"); byte[] nep5Hash = Storage.Get(Storage.CurrentContext, NEP5HashKey); DynamicCallContract dyncall = (DynamicCallContract)nep5Hash.ToDelegate(); BasicMethods.assert((bool)dyncall("transfer", new object[] { depositer, ExecutionEngine.ExecutingScriptHash, amount }), "transfer NEP5 token to the contract failed"); Storage.Put(Storage.CurrentContext, BalancePrefix.Concat(receiver), balanceOf(receiver) + amount); DepositEvent(receiver, amount); return(true); }
public static LedgerStruct.Channel _importPeersMigrationInfo(LedgerStruct.Channel _c, byte[] _fromLedgerAddr, byte[] _channelId) { BasicMethods.assert(BasicMethods._isLegalAddress(_fromLedgerAddr), "invalid contract address"); BasicMethods.assert(BasicMethods._isByte32(_channelId), "invalid _channelId"); object[] input = new object[] { _channelId }; DynamicCallContract dyncall = (DynamicCallContract)_fromLedgerAddr.ToDelegate(); LedgerStruct.PeersMigrationInfo args = (LedgerStruct.PeersMigrationInfo)dyncall("getPeersMigrationInfo", input); byte[][] peerAddr = args.peerAddr; BigInteger[] deposit = args.deposit; BigInteger[] withdrawal = args.withdrawal; BigInteger[] seqNum = args.seqNum; BigInteger[] transferOut = args.transferOut; BigInteger[] pendingPayout = args.pendingPayout; LedgerStruct.PeerProfile[] peerProfiles = _c.peerProfiles; for (int i = 0; i < 2; i++) { LedgerStruct.PeerProfile originalPeerProfile = peerProfiles[i]; LedgerStruct.PeerState originaPeerState = originalPeerProfile.state; LedgerStruct.PeerState peerState = new LedgerStruct.PeerState { seqNum = seqNum[i], transferOut = transferOut[i], nextPayIdListHash = originaPeerState.nextPayIdListHash, lastPayResolveDeadline = originaPeerState.lastPayResolveDeadline, pendingPayOut = pendingPayout[i] }; LedgerStruct.PeerProfile peerProfile = new LedgerStruct.PeerProfile() { peerAddr = peerAddr[i], deposit = deposit[i], withdrawal = withdrawal[i], state = peerState }; peerProfiles[i] = peerProfile; } return(_c); }
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); } }