public async Task <(ClaimTransaction tx, decimal availiableGas, decimal unclaimedGas)> BuildClaimTransactions(string address) { var claimData = await _blockchainProvider.GetClaimableAsync(address); var unclaimedGas = await _blockchainProvider.GetUnclaimedAsync(address); var tx = new ClaimTransaction { Version = 0, Claims = claimData.coinReferences.ToArray(), Inputs = new CoinReference[0], Outputs = new[] { new TransactionOutput { ScriptHash = address.ToScriptHash(), AssetId = Utils.GasToken, Value = Fixed8.FromDecimal(claimData.gasAmoumt), } }, Witnesses = new Witness[0], Attributes = new TransactionAttribute[0] }; return(tx, claimData.gasAmoumt, unclaimedGas); }
private bool OnClaimCommand(string[] args) { if (Program.Wallet == null) { Console.WriteLine($"Please open a wallet"); return(true); } Coins coins = new Coins(Program.Wallet, LocalNode); switch (args[1].ToLower()) { case "shipcoin": case "sc": ClaimTransaction tx = coins.Claim(); if (tx is ClaimTransaction) { Console.WriteLine($"Tranaction Suceeded: {tx.Hash.ToString()}"); } return(true); default: return(base.OnCommand(args)); } }
// GET: ClaimTransactions/Create public async Task <IActionResult> Create(Guid productId, Guid clientId, Guid policyId, int claimNumber) { ClaimTransaction claimtransaction = new ClaimTransaction { ClaimNumber = claimNumber, Taxable = true, TaxAmount = 0, RequisitionDate = DateTime.Now, InvoiceDate = DateTime.Now }; ClaimTransactionViewModel viewModel = new ClaimTransactionViewModel { ProductID = productId, ClientID = clientId, PolicyID = policyId, ClaimNumber = claimNumber, ClaimTransaction = claimtransaction, PayeeList = new SelectList(await _context.Payees .AsNoTracking() .OrderBy(p => p.Name).ToListAsync(), "ID", "Name"), AccountList = new SelectList(await _context.AccountCharts .AsNoTracking() .OrderBy(p => p.AccountCode).ToListAsync(), "ID", "AccountCode"), AffectedList = new SelectList(await _context.Affecteds .AsNoTracking().ToListAsync(), "ID", "Name"), TransactionTypeList = new SelectList(await _context.TransactionTypes .AsNoTracking().ToListAsync(), "ID", "Name") }; return(View(viewModel)); }
public override Transaction Unwrap() { ClaimTransaction tx = (ClaimTransaction)base.Unwrap(); tx.Claims = Claims.Select(p => p.Unwrap()).ToArray(); return(tx); }
public ClaimTransaction Claim(UInt160 change_address = null) { if (this.AvailableBonus() == Fixed8.Zero) { Console.WriteLine($"no gas to claim"); return(null); } CoinReference[] claims = current_wallet.GetUnclaimedCoins().Select(p => p.Reference).ToArray(); if (claims.Length == 0) { return(null); } using (Snapshot snapshot = Blockchain.Singleton.GetSnapshot()) { ClaimTransaction tx = new ClaimTransaction { Claims = claims.Take(MAX_CLAIMS_AMOUNT).ToArray(), Attributes = new TransactionAttribute[0], Inputs = new CoinReference[0], Outputs = new[] { new TransactionOutput { AssetId = Blockchain.UtilityToken.Hash, Value = snapshot.CalculateBonus(claims.Take(MAX_CLAIMS_AMOUNT)), ScriptHash = change_address ?? current_wallet.GetChangeAddress() } } }; return((ClaimTransaction)SignTransaction(tx)); } }
public ClaimTransaction Claim() { if (this.AvailableBonus() == Fixed8.Zero) { Console.WriteLine($"no gas to claim"); return(null); } CoinReference[] claims = current_wallet.GetUnclaimedCoins().Select(p => p.Reference).ToArray(); if (claims.Length == 0) { return(null); } ClaimTransaction tx = new ClaimTransaction { Claims = claims, Attributes = new TransactionAttribute[0], Inputs = new CoinReference[0], Outputs = new[] { new TransactionOutput { AssetId = Blockchain.SystemCoin.Hash, Value = Blockchain.CalculateBonus(claims), ScriptHash = current_wallet.GetChangeAddress() } } }; return((ClaimTransaction)SignTransaction(tx)); }
public void SerializeDeserialize_ClaimTransaction() { var original = new ClaimTransaction() { Claims = RandomCoinReferences(_random.Next(1, 255)).ToArray(), Version = 0x00, }; FillRandomTx(original); var ret = _serializer.Serialize(original); var copy = _deserializer.Deserialize <Transaction>(ret); var copy2 = _deserializer.Deserialize <ClaimTransaction>(ret); // Check exclusive data foreach (var check in new ClaimTransaction[] { (ClaimTransaction)copy, copy2 }) { CollectionAssert.AreEqual(original.Claims, check.Claims); } // Check base data EqualTx(original, copy, copy2); }
private JObject ClaimGas(UInt160 to) { CheckWallet(); const int MAX_CLAIMS_AMOUNT = 50; CoinReference[] claims = Wallet.GetUnclaimedCoins().Select(p => p.Reference).ToArray(); if (claims.Length == 0) { throw new RpcException(-300, "No gas to claim"); } ClaimTransaction tx; using (Snapshot snapshot = Blockchain.Singleton.GetSnapshot()) { tx = new ClaimTransaction { Claims = claims.Take(MAX_CLAIMS_AMOUNT).ToArray(), Attributes = new TransactionAttribute[0], Inputs = new CoinReference[0], Outputs = new[] { new TransactionOutput { AssetId = Blockchain.UtilityToken.Hash, Value = snapshot.CalculateBonus(claims.Take(MAX_CLAIMS_AMOUNT)), ScriptHash = to ?? Wallet.GetChangeAddress() } } }; } return(SignAndRelay(tx)); }
public static Transaction Claim(Wallet wallet, SignDelegate sign) { CoinReference[] claims = wallet.GetUnclaimedCoins().Select(p => p.Reference).ToArray(); if (claims.Length == 0) { return(null); } using (Snapshot snapshot = Blockchain.Singleton.GetSnapshot()) { ClaimTransaction tx = new ClaimTransaction { Claims = claims, Attributes = new TransactionAttribute[0], Inputs = new CoinReference[0], Outputs = new[] { new TransactionOutput { AssetId = Blockchain.UtilityToken.Hash, Value = snapshot.CalculateBonus(claims), ScriptHash = wallet.GetChangeAddress() } } }; return(sign.Invoke(tx)); } }
public async Task <IActionResult> Edit(ClaimTransactionViewModel viewModel) { if (ModelState.IsValid) { ClaimTransaction claimTransaction = new ClaimTransaction(); claimTransaction = viewModel.ClaimTransaction; claimTransaction.TaxAmount = TaxAmount(claimTransaction.Taxable, claimTransaction.Amount, claimTransaction.ClaimNumber); try { _context.Update(claimTransaction); await _context.SaveChangesAsync(); return(RedirectToAction("Index", new { claimId = claimTransaction.ClaimNumber })); } catch (DbUpdateException ex) { ModelState.AddModelError(string.Empty, ex.InnerException.Message.ToString()); } } viewModel.AccountList = new SelectList(_context.AccountCharts, "ID", "AccountCode", viewModel.ClaimTransaction.AccountID); viewModel.AffectedList = new SelectList(_context.Affecteds, "ID", "Name", viewModel.ClaimTransaction.AffectedID); viewModel.PayeeList = new SelectList(_context.Payees, "ID", "Name", viewModel.ClaimTransaction.PayeeID); viewModel.TransactionTypeList = new SelectList(_context.TransactionTypes, "ID", "Name", viewModel.ClaimTransaction.TransactionTypeID); return(View(viewModel)); }
public ClaimTransaction[] ClaimAll(UInt160 change_address = null) { if (this.AvailableBonus() == Fixed8.Zero) { Console.WriteLine($"no gas to claim"); return(null); } CoinReference[] claims = current_wallet.GetUnclaimedCoins().Select(p => p.Reference).ToArray(); if (claims.Length == 0) { return(null); } using (Snapshot snapshot = Blockchain.Singleton.GetSnapshot()) { int claim_count = (claims.Length - 1) / MAX_CLAIMS_AMOUNT + 1; List <ClaimTransaction> txs = new List <ClaimTransaction>(); if (claim_count > 1) { Console.WriteLine($"total claims: {claims.Length}, processing(0/{claim_count})..."); } for (int i = 0; i < claim_count; i++) { if (i > 0) { Console.WriteLine($"{i * MAX_CLAIMS_AMOUNT} claims processed({i}/{claim_count})..."); } ClaimTransaction tx = new ClaimTransaction { Claims = claims.Skip(i * MAX_CLAIMS_AMOUNT).Take(MAX_CLAIMS_AMOUNT).ToArray(), Attributes = new TransactionAttribute[0], Inputs = new CoinReference[0], Outputs = new[] { new TransactionOutput { AssetId = Blockchain.UtilityToken.Hash, Value = snapshot.CalculateBonus(claims.Skip(i * MAX_CLAIMS_AMOUNT).Take(MAX_CLAIMS_AMOUNT)), ScriptHash = change_address ?? current_wallet.GetChangeAddress() } } }; if ((tx = (ClaimTransaction)SignTransaction(tx)) != null) { txs.Add(tx); } else { break; } } return(txs.ToArray()); } }
public async Task Persist_ClaimTx_CallsClaimTxPersister() { var input = new ClaimTransaction(); var claimTxPersisterMock = AutoMockContainer.GetMock <ITransactionPersister <ClaimTransaction> >(); var testee = AutoMockContainer.Create <TransactionPersister>(); await testee.Persist(input); claimTxPersisterMock.Verify(m => m.Persist(input)); }
public async Task Process_ClaimTx_CallsClaimTxProcessor() { var input = new ClaimTransaction(); var claimTxProcessorMock = AutoMockContainer.GetMock <IProcessor <ClaimTransaction> >(); var testee = AutoMockContainer.Create <TransactionProcessor>(); await testee.Process(input); claimTxProcessorMock.Verify(m => m.Process(input)); }
/// <inheritdoc /> public ClaimTransaction BuildClaimTransaction(IWallet from, TransactionAttribute[] attributes) { ClaimTransaction transaction = new ClaimTransaction(); transaction.Attributes = attributes ?? new TransactionAttribute[0]; //Exclusive Data //transaction.Claims = _repository.GetUnspent(); return(transaction); }
public async Task Persist_MarksClaimsFromMultipleTx() { var txHash1 = UInt256.Parse(RandomInt().ToString("X64")); var txHash2 = UInt256.Parse(RandomInt().ToString("X64")); var txHash3 = UInt256.Parse(RandomInt().ToString("X64")); var input = new ClaimTransaction { Claims = new[] { new CoinReference { PrevHash = txHash1, PrevIndex = 0 }, new CoinReference { PrevHash = txHash2, PrevIndex = 0 }, new CoinReference { PrevHash = txHash3, PrevIndex = 0 } } }; var coinStates = new[] { CoinState.Confirmed | CoinState.Spent, CoinState.Confirmed | CoinState.Spent, CoinState.Confirmed | CoinState.Spent }; var repositoryMock = AutoMockContainer.GetMock <IRepository>(); repositoryMock.Setup(m => m.GetCoinStates(txHash1)) .ReturnsAsync(coinStates.Skip(0).Take(1).ToArray()); repositoryMock.Setup(m => m.GetCoinStates(txHash2)) .ReturnsAsync(coinStates.Skip(1).Take(1).ToArray()); repositoryMock.Setup(m => m.GetCoinStates(txHash3)) .ReturnsAsync(coinStates.Skip(2).Take(1).ToArray()); var testee = AutoMockContainer.Create <ClaimTransactionPersister>(); await testee.Persist(input); repositoryMock.Verify(m => m.AddCoinStates( It.Is <UInt256>(u => u.Equals(txHash1)), It.Is <CoinState[]>(c => c[0].HasFlag(CoinState.Confirmed | CoinState.Spent | CoinState.Claimed)) )); repositoryMock.Verify(m => m.AddCoinStates( It.Is <UInt256>(u => u.Equals(txHash2)), It.Is <CoinState[]>(c => c[0].HasFlag(CoinState.Confirmed | CoinState.Spent | CoinState.Claimed)) )); repositoryMock.Verify(m => m.AddCoinStates( It.Is <UInt256>(u => u.Equals(txHash3)), It.Is <CoinState[]>(c => c[0].HasFlag(CoinState.Confirmed | CoinState.Spent | CoinState.Claimed)) )); }
/// <inheritdoc /> public ClaimTransaction BuildClaimTransaction(CoinReference[] inputs, TransactionAttribute[] attributes) { if (inputs == null || inputs.Length == 0) { throw new ArgumentException(); } ClaimTransaction transaction = new ClaimTransaction(); transaction.Inputs = inputs; transaction.Attributes = attributes ?? new TransactionAttribute[0]; //TODO #395: Complete transaction return(transaction); }
/// <summary> /// Creates a 'ClaimTransaction', signs it and send a 'sendrawtransaction' RPC call to the connected node. /// This method does not put gas into claimable state. Can only claim 'unclaimable' amount. /// </summary> /// <returns></returns> public override async Task <ClaimTransaction> ClaimGas(UInt160 changeAddress = null) { var(claimable, amount) = await TransactionBuilderHelper.GetClaimable(AddressScriptHash.ToAddress(), _restService); if (amount <= 0) { throw new WalletException("No GAS available to claim at this address"); } var tx = new ClaimTransaction(); var references = new List <CoinReference>(); foreach (var entry in claimable) { references.Add(new CoinReference { PrevHash = UInt256.Parse(entry.Txid), PrevIndex = (ushort)entry.N, }); } if (changeAddress == null) { changeAddress = AddressScriptHash; } var outputs = new List <TransactionOutput> { new TransactionOutput { ScriptHash = changeAddress, AssetId = Utils.GasToken, Value = Fixed8.FromDecimal(amount), } }; tx.Version = 0; tx.Claims = references.ToArray(); tx.Inputs = new CoinReference[0]; tx.Outputs = outputs.ToArray(); tx.Attributes = new TransactionAttribute[0]; var result = await SignAndSendTransaction(tx); return(result ? tx : null); }
private bool OnClaimCommand(string[] args) { if (NoWallet()) { return(true); } Coins coins = new Coins(Program.Wallet, system); switch (args[1].ToLower()) { case "gas": if (args.Length > 2) { switch (args[2].ToLower()) { case "all": ClaimTransaction[] txs = coins.ClaimAll(); if (txs.Length > 0) { foreach (ClaimTransaction tx in txs) { Console.WriteLine($"Tranaction Suceeded: {tx.Hash}"); } } return(true); default: return(base.OnCommand(args)); } } else { ClaimTransaction tx = coins.Claim(); if (tx != null) { Console.WriteLine($"Tranaction Suceeded: {tx.Hash}"); } return(true); } default: return(base.OnCommand(args)); } }
public static Transaction Claim(Wallet wallet) { CoinReference[] claims = wallet.GetUnclaimedCoins().Select(p => p.Reference).ToArray(); if (claims.Length == 0) { return(null); } ClaimTransaction tx = new ClaimTransaction { Claims = claims, Attributes = new TransactionAttribute[0], Inputs = new CoinReference[0], Outputs = new[] { new TransactionOutput { AssetId = Blockchain.UtilityToken.Hash, Value = Blockchain.CalculateBonus(claims), ScriptHash = wallet.GetChangeAddress() } } }; //交易输入是 1 GAS var input = new CoinReference() { PrevHash = new UInt256("0x51ac4f7f1662d8c9379ccce3fa7cd2085b9a865edfa53ad892352a41768dd1de".Remove(0, 2).HexToBytes().Reverse().ToArray()), PrevIndex = 0 }; //交易输出是 0.999 GAS,找回到原地址 var output = new TransactionOutput() { AssetId = Blockchain.UtilityToken.Hash, //Asset Id, this is NEO ScriptHash = Wallet.ToScriptHash("AJd31a8rYPEBkY1QSxpsGy8mdU4vTYTD4U"), //Receiver Value = new Fixed8((long)(0.999 * (long)Math.Pow(10, 8))) //Value (satoshi unit) }; //则手续费是 0.001 GAS tx.Inputs.ToList().Add(input); tx.Outputs.ToList().Add(output); return(tx); }
private bool OnClaimCommand(string[] args) { if (NoWallet()) { return(true); } Coins coins = new Coins(Program.Wallet, LocalNode); switch (args[1].ToLower()) { case "gas": ClaimTransaction tx = coins.Claim(); if (tx != null) { Console.WriteLine($"Tranaction Suceeded: {tx.Hash}"); } return(true); default: return(base.OnCommand(args)); } }
public async Task Persist_MarksCorrectCoinStateAsClaimed() { var txHash = UInt256.Parse(RandomInt().ToString("X64")); var expectedClaimIndex = (ushort)RandomInt(3); var input = new ClaimTransaction { Claims = new[] { new CoinReference { PrevHash = txHash, PrevIndex = expectedClaimIndex } } }; var coinStates = new[] { CoinState.Confirmed | CoinState.Spent, CoinState.Confirmed | CoinState.Spent, CoinState.Confirmed | CoinState.Spent }; var repositoryMock = AutoMockContainer.GetMock <IRepository>(); repositoryMock.Setup(m => m.GetCoinStates(txHash)).ReturnsAsync(coinStates); var testee = AutoMockContainer.Create <ClaimTransactionPersister>(); await testee.Persist(input); repositoryMock.Verify(m => m.AddCoinStates(It.Is <UInt256>(u => u.Equals(txHash)), coinStates)); for (var i = 0; i < coinStates.Length; i++) { coinStates[i].Should().HaveFlag(CoinState.Confirmed); coinStates[i].Should().HaveFlag(CoinState.Spent); if (i == expectedClaimIndex) { coinStates[i].Should().HaveFlag(CoinState.Claimed); } } }
private NeoTransaction ConvertOperations(Operation[] operations, Metadata metadata) { TransactionType type = metadata["tx_type"].AsString().ToTransactionType(); // operations only contains utxo transfers, and in a special order List <CoinReference> inputs = new List <CoinReference>(); List <TransactionOutput> outputs = new List <TransactionOutput>(); for (int i = 0; i < operations.Length; i++) { var operation = operations[i]; // handle from ops, CoinChange field should have values if (operation.RelatedOperations is null) { if (operation.CoinChange is null || operation.CoinChange.CoinAction != CoinAction.CoinSpent) { throw new ArgumentException(); } var coin = operation.CoinChange; inputs.Add(new CoinReference() { PrevHash = coin.CoinIdentifier.GetTxHash(), PrevIndex = (ushort)coin.CoinIdentifier.GetIndex() }); } else // handle to ops, CoinChange field may be null { string symbol = operation.Amount.Currency.Symbol.ToUpper(); UInt256 assetId = symbol == "NEO" ? Blockchain.GoverningToken.Hash : symbol == "GAS" ? Blockchain.UtilityToken.Hash : throw new NotSupportedException(); Fixed8 value = Fixed8.Parse(operation.Amount.Value); UInt160 scriptHash = operation.Account.Address.ToScriptHash(); outputs.Add(new TransactionOutput() { AssetId = assetId, Value = value, ScriptHash = scriptHash }); } } NeoTransaction neoTx; // fetch exclusive data for each tx type switch (type) { case TransactionType.ClaimTransaction: neoTx = new ClaimTransaction(); JArray coins = metadata["claims"] as JArray; CoinReference[] coinReferences = coins.Select(p => new CoinReference() { PrevHash = UInt256.Parse(p["txid"].AsString()), PrevIndex = ushort.Parse(p["vout"].AsString()) }).ToArray(); ((ClaimTransaction)neoTx).Claims = coinReferences; break; case TransactionType.ContractTransaction: neoTx = new ContractTransaction(); break; case TransactionType.InvocationTransaction: neoTx = new InvocationTransaction(); byte[] script = metadata["script"].AsString().HexToBytes(); Fixed8 gas = Fixed8.Parse(metadata["gas"].AsString()); ((InvocationTransaction)neoTx).Script = script; ((InvocationTransaction)neoTx).Gas = gas; break; case TransactionType.StateTransaction: neoTx = new StateTransaction(); JArray descriptors = metadata["descriptors"] as JArray; StateDescriptor[] stateDescriptors = descriptors.Select(p => new StateDescriptor() { Type = p["type"].TryGetEnum <StateType>(), Key = p["key"].AsString().HexToBytes(), Field = p["field"].AsString(), Value = p["value"].AsString().HexToBytes() }).ToArray(); ((StateTransaction)neoTx).Descriptors = stateDescriptors; break; default: throw new NotSupportedException(); } neoTx.Inputs = inputs.ToArray(); neoTx.Outputs = outputs.ToArray(); neoTx.Attributes = new TransactionAttribute[] { }; return(neoTx); }
protected override JObject Process(string method, JArray _params) { switch (method) { case "getapplicationlog": { UInt256 hash = UInt256.Parse(_params[0].AsString()); string path = Path.Combine(Settings.Default.Paths.ApplicationLogs, $"{hash}.json"); return(File.Exists(path) ? JObject.Parse(File.ReadAllText(path)) : throw new RpcException(-100, "Unknown transaction")); } case "getbalance": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied."); } else { JObject json = new JObject(); switch (UIntBase.Parse(_params[0].AsString())) { case UInt160 asset_id_160: //NEP-5 balance json["balance"] = Program.Wallet.GetAvailable(asset_id_160).ToString(); break; case UInt256 asset_id_256: //Global Assets balance IEnumerable <Coin> coins = Program.Wallet.GetCoins().Where(p => !p.State.HasFlag(CoinState.Spent) && p.Output.AssetId.Equals(asset_id_256)); json["balance"] = coins.Sum(p => p.Output.Value).ToString(); json["confirmed"] = coins.Where(p => p.State.HasFlag(CoinState.Confirmed)).Sum(p => p.Output.Value).ToString(); break; } return(json); } case "listaddress": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied."); } else { return(Program.Wallet.GetAccounts().Select(p => { JObject account = new JObject(); account["address"] = p.Address; account["haskey"] = p.HasKey; account["label"] = p.Label; account["watchonly"] = p.WatchOnly; return account; }).ToArray()); } case "sendfrom": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied"); } else { UIntBase assetId = UIntBase.Parse(_params[0].AsString()); AssetDescriptor descriptor = new AssetDescriptor(assetId); UInt160 from = Wallet.ToScriptHash(_params[1].AsString()); UInt160 to = Wallet.ToScriptHash(_params[2].AsString()); BigDecimal value = BigDecimal.Parse(_params[3].AsString(), descriptor.Decimals); if (value.Sign <= 0) { throw new RpcException(-32602, "Invalid params"); } Fixed8 fee = _params.Count >= 5 ? Fixed8.Parse(_params[4].AsString()) : Fixed8.Zero; if (fee < Fixed8.Zero) { throw new RpcException(-32602, "Invalid params"); } UInt160 change_address = _params.Count >= 6 ? Wallet.ToScriptHash(_params[5].AsString()) : null; Transaction tx = Program.Wallet.MakeTransaction(null, new[] { new TransferOutput { AssetId = assetId, Value = value, ScriptHash = to } }, from: from, change_address: change_address, fee: fee); if (tx == null) { throw new RpcException(-300, "Insufficient funds"); } ContractParametersContext context = new ContractParametersContext(tx); Program.Wallet.Sign(context); if (context.Completed) { tx.Scripts = context.GetScripts(); Program.Wallet.ApplyTransaction(tx); LocalNode.Relay(tx); return(tx.ToJson()); } else { return(context.ToJson()); } } case "sendtoaddress": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied"); } else { UIntBase assetId = UIntBase.Parse(_params[0].AsString()); AssetDescriptor descriptor = new AssetDescriptor(assetId); UInt160 scriptHash = Wallet.ToScriptHash(_params[1].AsString()); BigDecimal value = BigDecimal.Parse(_params[2].AsString(), descriptor.Decimals); if (value.Sign <= 0) { throw new RpcException(-32602, "Invalid params"); } Fixed8 fee = _params.Count >= 4 ? Fixed8.Parse(_params[3].AsString()) : Fixed8.Zero; if (fee < Fixed8.Zero) { throw new RpcException(-32602, "Invalid params"); } UInt160 change_address = _params.Count >= 5 ? Wallet.ToScriptHash(_params[4].AsString()) : null; Transaction tx = Program.Wallet.MakeTransaction(null, new[] { new TransferOutput { AssetId = assetId, Value = value, ScriptHash = scriptHash } }, change_address: change_address, fee: fee); if (tx == null) { throw new RpcException(-300, "Insufficient funds"); } ContractParametersContext context = new ContractParametersContext(tx); Program.Wallet.Sign(context); if (context.Completed) { tx.Scripts = context.GetScripts(); Program.Wallet.ApplyTransaction(tx); LocalNode.Relay(tx); return(tx.ToJson()); } else { return(context.ToJson()); } } case "sendmany": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied"); } else { JArray to = (JArray)_params[0]; if (to.Count == 0) { throw new RpcException(-32602, "Invalid params"); } TransferOutput[] outputs = new TransferOutput[to.Count]; for (int i = 0; i < to.Count; i++) { UIntBase asset_id = UIntBase.Parse(to[i]["asset"].AsString()); AssetDescriptor descriptor = new AssetDescriptor(asset_id); outputs[i] = new TransferOutput { AssetId = asset_id, Value = BigDecimal.Parse(to[i]["value"].AsString(), descriptor.Decimals), ScriptHash = Wallet.ToScriptHash(to[i]["address"].AsString()) }; if (outputs[i].Value.Sign <= 0) { throw new RpcException(-32602, "Invalid params"); } } Fixed8 fee = _params.Count >= 2 ? Fixed8.Parse(_params[1].AsString()) : Fixed8.Zero; if (fee < Fixed8.Zero) { throw new RpcException(-32602, "Invalid params"); } UInt160 change_address = _params.Count >= 3 ? Wallet.ToScriptHash(_params[2].AsString()) : null; Transaction tx = Program.Wallet.MakeTransaction(null, outputs, change_address: change_address, fee: fee); if (tx == null) { throw new RpcException(-300, "Insufficient funds"); } ContractParametersContext context = new ContractParametersContext(tx); Program.Wallet.Sign(context); if (context.Completed) { tx.Scripts = context.GetScripts(); Program.Wallet.ApplyTransaction(tx); LocalNode.Relay(tx); return(tx.ToJson()); } else { return(context.ToJson()); } } case "getnewaddress": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied"); } else { WalletAccount account = Program.Wallet.CreateAccount(); if (Program.Wallet is NEP6Wallet wallet) { wallet.Save(); } return(account.Address); } case "dumpprivkey": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied"); } else { UInt160 scriptHash = Wallet.ToScriptHash(_params[0].AsString()); WalletAccount account = Program.Wallet.GetAccount(scriptHash); return(account.GetKey().Export()); } case "invoke": case "invokefunction": case "invokescript": JObject result = base.Process(method, _params); if (Program.Wallet != null) { InvocationTransaction tx = new InvocationTransaction { Version = 1, Script = result["script"].AsString().HexToBytes(), Gas = Fixed8.Parse(result["gas_consumed"].AsString()) }; tx.Gas -= Fixed8.FromDecimal(10); if (tx.Gas < Fixed8.Zero) { tx.Gas = Fixed8.Zero; } tx.Gas = tx.Gas.Ceiling(); tx = Program.Wallet.MakeTransaction(tx); if (tx != null) { ContractParametersContext context = new ContractParametersContext(tx); Program.Wallet.Sign(context); if (context.Completed) { tx.Scripts = context.GetScripts(); } else { tx = null; } } result["tx"] = tx?.ToArray().ToHexString(); } return(result); case "getunclaimedgas": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied."); } else { JObject json = new JObject(); uint height = Blockchain.Default.Height + 1; Fixed8 unavailable; try { unavailable = Blockchain.CalculateBonus(Program.Wallet.FindUnspentCoins().Where(p => p.Output.AssetId.Equals(Blockchain.GoverningToken.Hash)).Select(p => p.Reference), height); } catch (Exception) { unavailable = Fixed8.Zero; } json["unavailable"] = unavailable.ToString(); Fixed8 available = Blockchain.CalculateBonus(Program.Wallet.GetUnclaimedCoins().Select(p => p.Reference)); json["available"] = available.ToString(); return(json); } case "claimgas": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied."); } else { Fixed8 availableBonus = Blockchain.CalculateBonus(Program.Wallet.GetUnclaimedCoins().Select(p => p.Reference)); if (availableBonus == Fixed8.Zero) { // no gas to claim return(null); } CoinReference[] claims = Program.Wallet.GetUnclaimedCoins().Select(p => p.Reference).ToArray(); if (claims.Length == 0) { return(null); } ClaimTransaction tx = new ClaimTransaction { Claims = claims, Attributes = new TransactionAttribute[0], Inputs = new CoinReference[0], Outputs = new[] { new TransactionOutput { AssetId = Blockchain.UtilityToken.Hash, Value = Blockchain.CalculateBonus(claims), ScriptHash = Program.Wallet.GetChangeAddress() } } }; ContractParametersContext context; try { context = new ContractParametersContext(tx); } catch (InvalidOperationException) { // unsynchronized block return(null); } Program.Wallet.Sign(context); if (context.Completed) { context.Verifiable.Scripts = context.GetScripts(); Program.Wallet.ApplyTransaction(tx); bool relay_result = LocalNode.Relay(tx); if (relay_result) { return(tx.ToJson()); } else { throw new RpcException(-401, "Could not relay transaction"); } } else { return(context.ToJson()); } } default: return(base.Process(method, _params)); } }
private JObject Process(string method, JArray _params) { switch (method) { case "claimgas": if (wallet == null || WalletLocker.Locked()) { throw new RpcException(-400, "Access denied."); } using (Snapshot snapshot = Blockchain.Singleton.GetSnapshot()) { if (snapshot.CalculateBonus(wallet.GetUnclaimedCoins().Select(p => p.Reference)) == Fixed8.Zero) { throw new RpcException(-100, "No gas to claim"); } CoinReference[] claims = wallet.GetUnclaimedCoins().Select(p => p.Reference).ToArray(); if (claims.Length == 0) { throw new RpcException(-100, "No gas to claim"); } ClaimTransaction tx = new ClaimTransaction { Claims = claims.Take(MAX_CLAIMS_AMOUNT).ToArray(), Attributes = new TransactionAttribute[0], Inputs = new CoinReference[0], Outputs = new[] { new TransactionOutput { AssetId = Blockchain.UtilityToken.Hash, Value = snapshot.CalculateBonus(claims.Take(MAX_CLAIMS_AMOUNT)), ScriptHash = _params.Count > 0 ? _params[0].AsString().ToScriptHash() : wallet.GetChangeAddress() } } }; ContractParametersContext context; try { context = new ContractParametersContext(tx); } catch (InvalidOperationException) { throw new RpcException(-400, "Access denied"); } wallet.Sign(context); if (context.Completed) { tx.Witnesses = context.GetWitnesses(); wallet.ApplyTransaction(tx); system.LocalNode.Tell(new LocalNode.Relay { Inventory = tx }); return(tx.ToJson()); } else { return(context.ToJson()); } } case "dumpprivkey": if (wallet == null || WalletLocker.Locked()) { throw new RpcException(-400, "Access denied."); } else { UInt160 scriptHash = _params[0].AsString().ToScriptHash(); WalletAccount account = Wallet.GetAccount(scriptHash); return(account.GetKey().Export()); } case "getaccountstate": { UInt160 script_hash = _params[0].AsString().ToScriptHash(); AccountState account = Blockchain.Singleton.Store.GetAccounts().TryGet(script_hash) ?? new AccountState(script_hash); return(account.ToJson()); } case "getassetstate": { UInt256 asset_id = UInt256.Parse(_params[0].AsString()); AssetState asset = Blockchain.Singleton.Store.GetAssets().TryGet(asset_id); return(asset?.ToJson() ?? throw new RpcException(-100, "Unknown asset")); } case "getbalance": if (Wallet == null) { throw new RpcException(-400, "Access denied."); } else { JObject json = new JObject(); switch (UIntBase.Parse(_params[0].AsString())) { case UInt160 asset_id_160: //NEP-5 balance json["balance"] = Wallet.GetAvailable(asset_id_160).ToString(); break; case UInt256 asset_id_256: //Global Assets balance IEnumerable <Coin> coins = Wallet.GetCoins().Where(p => !p.State.HasFlag(CoinState.Spent) && p.Output.AssetId.Equals(asset_id_256)); json["balance"] = coins.Sum(p => p.Output.Value).ToString(); json["confirmed"] = coins.Where(p => p.State.HasFlag(CoinState.Confirmed)).Sum(p => p.Output.Value).ToString(); break; } return(json); } case "getbestblockhash": return(Blockchain.Singleton.CurrentBlockHash.ToString()); case "getblock": { Block block; if (_params[0] is JNumber) { uint index = (uint)_params[0].AsNumber(); block = Blockchain.Singleton.Store.GetBlock(index); } else { UInt256 hash = UInt256.Parse(_params[0].AsString()); block = Blockchain.Singleton.Store.GetBlock(hash); } if (block == null) { throw new RpcException(-100, "Unknown block"); } bool verbose = _params.Count >= 2 && _params[1].AsBoolean(); if (verbose) { JObject json = block.ToJson(); json["confirmations"] = Blockchain.Singleton.Height - block.Index + 1; UInt256 hash = Blockchain.Singleton.Store.GetNextBlockHash(block.Hash); if (hash != null) { json["nextblockhash"] = hash.ToString(); } return(json); } return(block.ToArray().ToHexString()); } case "getblockcount": return(Blockchain.Singleton.Height + 1); case "getblockhash": { uint height = (uint)_params[0].AsNumber(); if (height <= Blockchain.Singleton.Height) { return(Blockchain.Singleton.GetBlockHash(height).ToString()); } throw new RpcException(-100, "Invalid Height"); } case "getblockheader": { Header header; if (_params[0] is JNumber) { uint height = (uint)_params[0].AsNumber(); header = Blockchain.Singleton.Store.GetHeader(height); } else { UInt256 hash = UInt256.Parse(_params[0].AsString()); header = Blockchain.Singleton.Store.GetHeader(hash); } if (header == null) { throw new RpcException(-100, "Unknown block"); } bool verbose = _params.Count >= 2 && _params[1].AsBoolean(); if (verbose) { JObject json = header.ToJson(); json["confirmations"] = Blockchain.Singleton.Height - header.Index + 1; UInt256 hash = Blockchain.Singleton.Store.GetNextBlockHash(header.Hash); if (hash != null) { json["nextblockhash"] = hash.ToString(); } return(json); } return(header.ToArray().ToHexString()); } case "getblocksysfee": { uint height = (uint)_params[0].AsNumber(); if (height <= Blockchain.Singleton.Height) { return(Blockchain.Singleton.Store.GetSysFeeAmount(height).ToString()); } throw new RpcException(-100, "Invalid Height"); } case "getconnectioncount": return(LocalNode.Singleton.ConnectedCount); case "getcontractstate": { UInt160 script_hash = UInt160.Parse(_params[0].AsString()); ContractState contract = Blockchain.Singleton.Store.GetContracts().TryGet(script_hash); return(contract?.ToJson() ?? throw new RpcException(-100, "Unknown contract")); } case "getnewaddress": if (wallet == null || WalletLocker.Locked()) { throw new RpcException(-400, "Access denied."); } else { WalletAccount account = Wallet.CreateAccount(); if (Wallet is NEP6Wallet nep6) { nep6.Save(); } return(account.Address); } case "getpeers": { JObject json = new JObject(); json["unconnected"] = new JArray(LocalNode.Singleton.GetUnconnectedPeers().Select(p => { JObject peerJson = new JObject(); peerJson["address"] = p.Address.ToString(); peerJson["port"] = p.Port; return(peerJson); })); json["bad"] = new JArray(); //badpeers has been removed json["connected"] = new JArray(LocalNode.Singleton.GetRemoteNodes().Select(p => { JObject peerJson = new JObject(); peerJson["address"] = p.Remote.Address.ToString(); peerJson["port"] = p.ListenerPort; return(peerJson); })); return(json); } case "getrawmempool": { bool shouldGetUnverified = _params.Count >= 1 && _params[0].AsBoolean(); if (!shouldGetUnverified) { return(new JArray(Blockchain.Singleton.MemPool.GetVerifiedTransactions().Select(p => (JObject)p.Hash.ToString()))); } JObject json = new JObject(); json["height"] = Blockchain.Singleton.Height; Blockchain.Singleton.MemPool.GetVerifiedAndUnverifiedTransactions( out IEnumerable <Transaction> verifiedTransactions, out IEnumerable <Transaction> unverifiedTransactions); json["verified"] = new JArray(verifiedTransactions.Select(p => (JObject)p.Hash.ToString())); json["unverified"] = new JArray(unverifiedTransactions.Select(p => (JObject)p.Hash.ToString())); return(json); } case "getrawtransaction": { UInt256 hash = UInt256.Parse(_params[0].AsString()); bool verbose = _params.Count >= 2 && _params[1].AsBoolean(); Transaction tx = Blockchain.Singleton.GetTransaction(hash); if (tx == null) { throw new RpcException(-100, "Unknown transaction"); } if (verbose) { JObject json = tx.ToJson(); uint? height = Blockchain.Singleton.Store.GetTransactions().TryGet(hash)?.BlockIndex; if (height != null) { Header header = Blockchain.Singleton.Store.GetHeader((uint)height); json["blockhash"] = header.Hash.ToString(); json["confirmations"] = Blockchain.Singleton.Height - header.Index + 1; json["blocktime"] = header.Timestamp; } return(json); } return(tx.ToArray().ToHexString()); } case "getstorage": { UInt160 script_hash = UInt160.Parse(_params[0].AsString()); byte[] key = _params[1].AsString().HexToBytes(); StorageItem item = Blockchain.Singleton.Store.GetStorages().TryGet(new StorageKey { ScriptHash = script_hash, Key = key }) ?? new StorageItem(); return(item.Value?.ToHexString()); } case "gettransactionheight": { UInt256 hash = UInt256.Parse(_params[0].AsString()); uint? height = Blockchain.Singleton.Store.GetTransactions().TryGet(hash)?.BlockIndex; if (height.HasValue) { return(height.Value); } throw new RpcException(-100, "Unknown transaction"); } case "gettxout": { UInt256 hash = UInt256.Parse(_params[0].AsString()); ushort index = (ushort)_params[1].AsNumber(); return(Blockchain.Singleton.Store.GetUnspent(hash, index)?.ToJson(index)); } case "getvalidators": using (Snapshot snapshot = Blockchain.Singleton.GetSnapshot()) { var validators = snapshot.GetValidators(); return(snapshot.GetEnrollments().Select(p => { JObject validator = new JObject(); validator["publickey"] = p.PublicKey.ToString(); validator["votes"] = p.Votes.ToString(); validator["active"] = validators.Contains(p.PublicKey); return validator; }).ToArray()); } case "getversion": { JObject json = new JObject(); json["port"] = LocalNode.Singleton.ListenerPort; json["nonce"] = LocalNode.Nonce; json["useragent"] = LocalNode.UserAgent; return(json); } case "getwalletheight": if (Wallet == null) { throw new RpcException(-400, "Access denied."); } else { return((Wallet.WalletHeight > 0) ? Wallet.WalletHeight - 1 : 0); } case "invoke": { UInt160 script_hash = UInt160.Parse(_params[0].AsString()); ContractParameter[] parameters = ((JArray)_params[1]).Select(p => ContractParameter.FromJson(p)).ToArray(); byte[] script; using (ScriptBuilder sb = new ScriptBuilder()) { script = sb.EmitAppCall(script_hash, parameters).ToArray(); } return(GetInvokeResult(script)); } case "invokefunction": { UInt160 script_hash = UInt160.Parse(_params[0].AsString()); string operation = _params[1].AsString(); ContractParameter[] args = _params.Count >= 3 ? ((JArray)_params[2]).Select(p => ContractParameter.FromJson(p)).ToArray() : new ContractParameter[0]; byte[] script; using (ScriptBuilder sb = new ScriptBuilder()) { script = sb.EmitAppCall(script_hash, operation, args).ToArray(); } return(GetInvokeResult(script)); } case "invokescript": { byte[] script = _params[0].AsString().HexToBytes(); return(GetInvokeResult(script)); } case "listaddress": if (Wallet == null) { throw new RpcException(-400, "Access denied."); } else { return(Wallet.GetAccounts().Select(p => { JObject account = new JObject(); account["address"] = p.Address; account["haskey"] = p.HasKey; account["label"] = p.Label; account["watchonly"] = p.WatchOnly; return account; }).ToArray()); } case "lockwallet": if (wallet == null) { throw new RpcException(-400, "Access denied"); } else { WalletLocker.Lock(); return(true); } case "sendfrom": if (wallet == null || WalletLocker.Locked()) { throw new RpcException(-400, "Access denied."); } else { UIntBase assetId = UIntBase.Parse(_params[0].AsString()); AssetDescriptor descriptor = new AssetDescriptor(assetId); UInt160 from = _params[1].AsString().ToScriptHash(); UInt160 to = _params[2].AsString().ToScriptHash(); BigDecimal value = BigDecimal.Parse(_params[3].AsString(), descriptor.Decimals); if (value.Sign <= 0) { throw new RpcException(-32602, "Invalid params"); } Fixed8 fee = _params.Count >= 5 ? Fixed8.Parse(_params[4].AsString()) : Fixed8.Zero; if (fee < Fixed8.Zero) { throw new RpcException(-32602, "Invalid params"); } UInt160 change_address = _params.Count >= 6 ? _params[5].AsString().ToScriptHash() : null; Transaction tx = Wallet.MakeTransaction(null, new[] { new TransferOutput { AssetId = assetId, Value = value, ScriptHash = to } }, from: from, change_address: change_address, fee: fee); if (tx == null) { throw new RpcException(-300, "Insufficient funds"); } ContractParametersContext context = new ContractParametersContext(tx); Wallet.Sign(context); if (context.Completed) { tx.Witnesses = context.GetWitnesses(); Wallet.ApplyTransaction(tx); system.LocalNode.Tell(new LocalNode.Relay { Inventory = tx }); return(tx.ToJson()); } else { return(context.ToJson()); } } case "sendmany": if (wallet == null || WalletLocker.Locked()) { throw new RpcException(-400, "Access denied."); } else { JArray to = (JArray)_params[0]; if (to.Count == 0) { throw new RpcException(-32602, "Invalid params"); } TransferOutput[] outputs = new TransferOutput[to.Count]; for (int i = 0; i < to.Count; i++) { UIntBase asset_id = UIntBase.Parse(to[i]["asset"].AsString()); AssetDescriptor descriptor = new AssetDescriptor(asset_id); outputs[i] = new TransferOutput { AssetId = asset_id, Value = BigDecimal.Parse(to[i]["value"].AsString(), descriptor.Decimals), ScriptHash = to[i]["address"].AsString().ToScriptHash() }; if (outputs[i].Value.Sign <= 0) { throw new RpcException(-32602, "Invalid params"); } } Fixed8 fee = _params.Count >= 2 ? Fixed8.Parse(_params[1].AsString()) : Fixed8.Zero; if (fee < Fixed8.Zero) { throw new RpcException(-32602, "Invalid params"); } UInt160 change_address = _params.Count >= 3 ? _params[2].AsString().ToScriptHash() : null; Transaction tx = Wallet.MakeTransaction(null, outputs, change_address: change_address, fee: fee); if (tx == null) { throw new RpcException(-300, "Insufficient funds"); } ContractParametersContext context = new ContractParametersContext(tx); Wallet.Sign(context); if (context.Completed) { tx.Witnesses = context.GetWitnesses(); Wallet.ApplyTransaction(tx); system.LocalNode.Tell(new LocalNode.Relay { Inventory = tx }); return(tx.ToJson()); } else { return(context.ToJson()); } } case "sendrawtransaction": { Transaction tx = Transaction.DeserializeFrom(_params[0].AsString().HexToBytes()); RelayResultReason reason = system.Blockchain.Ask <RelayResultReason>(tx).Result; return(GetRelayResult(reason)); } case "sendtoaddress": if (wallet == null || WalletLocker.Locked()) { throw new RpcException(-400, "Access denied."); } else { UIntBase assetId = UIntBase.Parse(_params[0].AsString()); AssetDescriptor descriptor = new AssetDescriptor(assetId); UInt160 scriptHash = _params[1].AsString().ToScriptHash(); BigDecimal value = BigDecimal.Parse(_params[2].AsString(), descriptor.Decimals); if (value.Sign <= 0) { throw new RpcException(-32602, "Invalid params"); } Fixed8 fee = _params.Count >= 4 ? Fixed8.Parse(_params[3].AsString()) : Fixed8.Zero; if (fee < Fixed8.Zero) { throw new RpcException(-32602, "Invalid params"); } UInt160 change_address = _params.Count >= 5 ? _params[4].AsString().ToScriptHash() : null; Transaction tx = Wallet.MakeTransaction(null, new[] { new TransferOutput { AssetId = assetId, Value = value, ScriptHash = scriptHash } }, change_address: change_address, fee: fee); if (tx == null) { throw new RpcException(-300, "Insufficient funds"); } ContractParametersContext context = new ContractParametersContext(tx); Wallet.Sign(context); if (context.Completed) { tx.Witnesses = context.GetWitnesses(); Wallet.ApplyTransaction(tx); system.LocalNode.Tell(new LocalNode.Relay { Inventory = tx }); return(tx.ToJson()); } else { return(context.ToJson()); } } case "showgas": using (Snapshot snapshot = Blockchain.Singleton.GetSnapshot()) { uint height = snapshot.Height + 1; Fixed8 unavailable; try { unavailable = snapshot.CalculateBonus(wallet.FindUnspentCoins().Where(p => p.Output.AssetId.Equals(Blockchain.GoverningToken.Hash)).Select(p => p.Reference), height); } catch (Exception) { unavailable = Fixed8.Zero; } return(new JObject { ["available"] = snapshot.CalculateBonus(wallet.GetUnclaimedCoins().Select(p => p.Reference)).ToString(), ["unavailable"] = unavailable.ToString() }); } case "submitblock": { Block block = _params[0].AsString().HexToBytes().AsSerializable <Block>(); RelayResultReason reason = system.Blockchain.Ask <RelayResultReason>(block).Result; return(GetRelayResult(reason)); } case "unlockwallet": if (wallet == null) { throw new RpcException(-400, "Access denied"); } else { try { if (_params.Count > 1) { WalletLocker.Unlock(wallet, _params[0].AsString(), uint.Parse(_params[1].AsString())); } else { WalletLocker.Unlock(wallet, _params[0].AsString(), DEFAULT_UNLOCK_TIME); } } catch (FormatException) { throw new RpcException(-32602, "Invalid params"); } return(true); } case "validateaddress": { JObject json = new JObject(); UInt160 scriptHash; try { scriptHash = _params[0].AsString().ToScriptHash(); } catch { scriptHash = null; } json["address"] = _params[0]; json["isvalid"] = scriptHash != null; return(json); } default: throw new RpcException(-32601, "Method not found"); } }
public async Task <IActionResult> Create(ClaimTransactionViewModel viewModel) { var invoiceNumber = viewModel.ClaimTransaction.InvoiceNumber; var currentProductId = viewModel.ProductID; var currentClientId = viewModel.ClientID; var currentPolicyId = viewModel.PolicyID; var currentClaimNumber = viewModel.ClaimTransaction.ClaimNumber; try { if (ModelState.IsValid) { ClaimTransaction claimTransaction = new ClaimTransaction(); TransactionNumbers transactionnumber = new TransactionNumbers(); claimTransaction = viewModel.ClaimTransaction; claimTransaction.ID = Guid.NewGuid(); claimTransaction.ClaimNumber = viewModel.ClaimNumber; claimTransaction.TransactionNumber = transactionnumber.GetTransactionNumber(_context); claimTransaction.TaxAmount = TaxAmount(claimTransaction.Taxable, claimTransaction.Amount, claimTransaction.ClaimNumber); _context.Add(claimTransaction); await _context.SaveChangesAsync(); var tranParam = claimTransaction.TransactionNumber; await _context.Database.ExecuteSqlCommandAsync( "INSERT INTO ClaimTransactionGenerator(TransactionNumber) " + "Values ({0})", parameters : tranParam); return(RedirectToAction("Index", new { productId = currentProductId, clientId = currentClientId, policyId = currentPolicyId, claimId = currentClaimNumber })); } } catch (DbUpdateException ex) { var errorMsg = ex.InnerException.Message.ToString(); viewModel.ErrMsg = errorMsg; if (errorMsg.Contains("IX_ClaimTransaction_InvoiceNumber")) { viewModel.ErrMsg = $"Duplicate Invoice Number {invoiceNumber} exists."; ModelState.AddModelError(string.Empty, viewModel.ErrMsg); } ModelState.AddModelError(string.Empty, ex.InnerException.Message.ToString()); } viewModel.PayeeList = new SelectList(await _context.Payees.OrderBy(p => p.Name) .AsNoTracking() .ToListAsync(), "ID", "Name", viewModel.ClaimTransaction.ID); viewModel.AccountList = new SelectList(await _context.AccountCharts .AsNoTracking() .OrderBy(p => p.AccountCode).ToListAsync(), "ID", "AccountCode", viewModel.ClaimTransaction.AccountID); viewModel.AffectedList = new SelectList(await _context.Affecteds .AsNoTracking() .OrderBy(p => p.Name).ToListAsync(), "ID", "Name", viewModel.ClaimTransaction.AffectedID); viewModel.TransactionTypeList = new SelectList(await _context.TransactionTypes .AsNoTracking() .OrderByDescending(p => p.Name).ToListAsync(), "ID", "Name", viewModel.ClaimTransaction.TransactionTypeID); return(View(viewModel)); }
public void Verify_ClaimTransacWithNegativeResultOfUtilityToken() { var testee = AutoMockContainer.Create <TransactionOperationManager>(); var transaction = new ClaimTransaction { Attributes = new [] { new TransactionAttribute { Usage = TransactionAttributeUsage.ContractHash } }, Inputs = new[] { new CoinReference { PrevHash = UInt256.Zero, PrevIndex = 1 }, new CoinReference { PrevHash = UInt256.Zero, PrevIndex = 2 } }, Outputs = new[] { new TransactionOutput { AssetId = UInt256.Zero, Value = Fixed8.One } } }; var transactionOfPreviousHash = new Transaction { Outputs = new [] { new TransactionOutput(), // it's not using the first because PrevIndex is 1 new TransactionOutput { AssetId = UInt256.Parse("602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7"), Value = new Fixed8(-5) } } }; var transactionModelMock = this.AutoMockContainer.GetMock <ITransactionRepository>(); transactionModelMock .Setup(b => b.IsDoubleSpend(transaction)) .Returns(false); transactionModelMock .Setup(x => x.GetTransaction(It.IsAny <UInt256>())) .ReturnsAsync(() => transactionOfPreviousHash); this.AutoMockContainer .GetMock <IAssetRepository>() .Setup(b => b.GetAsset(It.IsAny <UInt256>())) .ReturnsAsync(() => new Asset { AssetType = AssetType.GoverningToken }); var transactionContextMock = this.AutoMockContainer.GetMock <ITransactionContext>(); transactionContextMock .SetupGet(x => x.UtilityTokenHash) .Returns(UInt256.Parse("602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7")); transactionContextMock .Setup(x => x.GetSystemFee(It.IsAny <Transaction>())) .Returns(Fixed8.Zero); var result = testee.Verify(transaction); result.Should().BeFalse(); }
/// <summary> /// Combine creates a network-specific transaction from an unsigned transaction and an array of provided signatures. /// The signed transaction returned from this method will be sent to the `/construction/submit` endpoint by the caller. /// </summary> /// <param name="request"></param> /// <returns></returns> public JObject ConstructionCombine(ConstructionCombineRequest request) { NeoTransaction neoTx; try { byte[] unsigned = request.UnsignedTransaction.HexToBytes(); TransactionType type = (TransactionType)unsigned[0]; switch (type) { case TransactionType.ClaimTransaction: neoTx = new ClaimTransaction(); break; case TransactionType.ContractTransaction: neoTx = new ContractTransaction(); break; case TransactionType.StateTransaction: neoTx = new StateTransaction(); break; case TransactionType.InvocationTransaction: neoTx = new InvocationTransaction(); break; default: throw new ArgumentException(); } using (MemoryStream ms = new MemoryStream(unsigned, false)) using (BinaryReader br = new BinaryReader(ms, Encoding.UTF8)) { (neoTx as IVerifiable).DeserializeUnsigned(br); } } catch (Exception) { return(Error.TX_DESERIALIZE_ERROR.ToJson()); } if (neoTx.Witnesses != null && neoTx.Witnesses.Length > 0) { return(Error.TX_ALREADY_SIGNED.ToJson()); } if (request.Signatures.Length == 0) { return(Error.NO_SIGNATURE.ToJson()); } Witness witness; if (request.Signatures.Length == 1) // single signed { witness = CreateSignatureWitness(request.Signatures[0]); } else { witness = CreateMultiSignatureWitness(request.Signatures); } if (witness is null) { return(Error.INVALID_SIGNATURES.ToJson()); } neoTx.Witnesses = new Witness[] { witness }; byte[] signed = neoTx.ToArray(); ConstructionCombineResponse response = new ConstructionCombineResponse(signed.ToHexString()); return(response.ToJson()); }
public void TestFilterForBlock_ClaimHasPriority() { // Should contain "ClaimTransaction" in "HighPriorityTxType" Settings.Default.HighPriorityTxType.Contains(TransactionType.ClaimTransaction).Should().Be(true); ClaimTransaction claimTxZero1 = GetClaimTransaction(0); claimTxZero1.Size.Should().Be(7 + 21); // 7 + 21 (random script) claimTxZero1.Hash.ToString().Should().Be("0x60037520be0fd903703c2b67973296f22cac8932db07a2723addf79478aea75f"); ClaimTransaction claimTxZero2 = GetClaimTransaction(0); claimTxZero2.Size.Should().Be(7 + 21); // 7 + 21 (random script) claimTxZero2.Hash.ToString().Should().Be("0xb29426673b3ef5c226bd35d53c2cb2242e09c06f0efe9c0d5be2034f41cb85ba"); ClaimTransaction claimTxZero3 = GetClaimTransaction(0); claimTxZero3.Size.Should().Be(7 + 21); // 7 + 21 (random script) claimTxZero3.Hash.ToString().Should().Be("0x01027faead9a0538048db7ac5657172f6e2240bff3f7d902e490bb1bd75c2df7"); //ClaimTransaction claimTxTwo = GetClaimTransaction(2); //claimTxTwo.Size.Should().Be(75 + 21); // 2*34 + 7 + 21 ClaimTransaction claimTx30 = GetClaimTransaction(30); claimTx30.Size.Should().Be(1027 + 21); // 30*34 + 7 + 21 claimTx30.NetworkFee.Should().Be(Fixed8.Zero); claimTx30.IsLowPriority.Should().Be(true); // by default is Low Priority, but plugin makes it High Priority //uut.IsLowPriority -> cannot inspect because it's private... no problem! List <Transaction> TxList = new List <Transaction>(); TxList.Insert(0, claimTxZero1); TxList.Insert(0, claimTxZero2); TxList.Insert(0, claimTxZero3); TxList.Insert(0, claimTx30); //Console.WriteLine("Tx List Claim"); //foreach(var tx in TxList) // Console.WriteLine($"Claim TX fee: {tx.NetworkFee} size: {tx.Size} ratio: {tx.FeePerByte} hash: {tx.Hash}" ); // ======================== BEGIN TESTS ============================ // insert 100 paid invocation transactions for (var i = 0; i < 100; i++) { TxList.Insert(0, MockGenerateInvocationTransaction(Fixed8.One, 50).Object); } // insert 100 low priority invocation transactions (18 satoshi + 82 zero) for (var i = 0; i < 100; i++) { if (i < 18) { TxList.Insert(0, MockGenerateInvocationTransaction(Fixed8.Satoshi, 50).Object); } else { TxList.Insert(0, MockGenerateInvocationTransaction(Fixed8.Zero, 50).Object); } } TxList.Count().Should().Be(204); // 100 free + 100 paid + 4 claims TxList.Where(tx => tx.NetworkFee == Fixed8.Zero).Count().Should().Be(100 - 18 + 4); // 82 fully free + 4 claims IEnumerable <Transaction> filteredTxList = uut.FilterForBlock(TxList); //filteredTxList.Count().Should().Be(124); // 20 free + 100 paid + 4 claims filteredTxList.Count().Should().Be(120); // 20 free (including 2 claims) + 100 paid filteredTxList.Where(tx => tx.NetworkFee == Fixed8.Zero).Count().Should().Be(2); // 2 fully free (2 claims) // will select 20 low priority (including Claims) var vx = filteredTxList.Where(tx => tx.IsLowPriority == true); vx.Count().Should().Be(20); // two Claim Transaction will survive vx = filteredTxList.Where(tx => tx.Type == TransactionType.ClaimTransaction); vx.Count().Should().Be(2); // ================================================================= // insert more paid invocation transactions (400 of each) for (var i = 0; i < 400; i++) { TxList.Insert(0, MockGenerateInvocationTransaction(Fixed8.One, 50).Object); } // insert more free invocation transactions (400 of each) for (var i = 0; i < 400; i++) { TxList.Insert(0, MockGenerateInvocationTransaction(Fixed8.Zero, 50).Object); } TxList.Count().Should().Be(1004); // 500 free + 500 paid + 4 claims TxList.Where(tx => tx.NetworkFee == Fixed8.Zero).Count().Should().Be(400 + 100 - 18 + 4); // 500-18 fully free + 4 claims filteredTxList = uut.FilterForBlock(TxList); filteredTxList.Count().Should().Be(499); // full block // will select 20 low priority (including Claims) vx = filteredTxList.Where(tx => tx.IsLowPriority == true); vx.Count().Should().Be(20); // will still select Claim Transactions vx = filteredTxList.Where(tx => tx.Type == TransactionType.ClaimTransaction); vx.Count().Should().Be(2); // there are 3 tied Claim tx, will solve it based on smaller hash (0x01, 0x60) => 0xb2 is excluded // 0x01027faead9a0538048db7ac5657172f6e2240bff3f7d902e490bb1bd75c2df7 // 0x60037520be0fd903703c2b67973296f22cac8932db07a2723addf79478aea75f // 0xb29426673b3ef5c226bd35d53c2cb2242e09c06f0efe9c0d5be2034f41cb85ba vx = filteredTxList.Where(tx => tx.Hash.ToString() == "0x01027faead9a0538048db7ac5657172f6e2240bff3f7d902e490bb1bd75c2df7"); vx.Count().Should().Be(1); vx = filteredTxList.Where(tx => tx.Hash.ToString() == "0x60037520be0fd903703c2b67973296f22cac8932db07a2723addf79478aea75f"); vx.Count().Should().Be(1); vx = filteredTxList.Where(tx => tx.Hash.ToString() == "0xb29426673b3ef5c226bd35d53c2cb2242e09c06f0efe9c0d5be2034f41cb85ba"); vx.Count().Should().Be(0); //Console.WriteLine("filtered"); //foreach(var tx in filteredTxList) // Console.WriteLine($"TX fee: {tx.NetworkFee} size: {tx.Size} ratio: {tx.FeePerByte} hash: {tx.Hash}" ); }
public void TestSetup() { uut = new ClaimTransaction(); }
private static JArray GetMempoolTransaction(UInt160 ScriptHash) { JArray result = new JArray(); foreach (Transaction tx in LocalNode.GetMemoryPool()) { UInt160 from_script = null; UInt160 to_script = null; JObject obj = new JObject(); if (tx is ContractTransaction) { try { foreach (CoinReference input in tx.Inputs) { Transaction inputTx = Blockchain.Default.GetTransaction(input.PrevHash); if (inputTx != null) { from_script = inputTx.Outputs[input.PrevIndex].ScriptHash; } else { foreach (Transaction inTx in LocalNode.GetMemoryPool()) { if (inTx.Hash.Equals(input.PrevHash)) { from_script = inTx.Outputs[input.PrevIndex].ScriptHash; } } } } } catch (Exception ex) { } if (tx.Outputs.Length > 0) { to_script = tx.Outputs[0].ScriptHash; } Dictionary <UInt256, Fixed8> balance = new Dictionary <UInt256, Fixed8>(); Dictionary <UInt256, Fixed8> fee = new Dictionary <UInt256, Fixed8>(); for (int i = 0; i < tx.Outputs.Length; i++) { AssetState state = Blockchain.Default.GetAssetState(tx.Outputs[i].AssetId); if (tx.Outputs[i].ScriptHash.Equals(to_script)) { if (balance.ContainsKey(tx.Outputs[i].AssetId)) { balance[tx.Outputs[i].AssetId] += tx.Outputs[i].Value; } else { balance[tx.Outputs[i].AssetId] = tx.Outputs[i].Value; } } if (!fee.ContainsKey(tx.Outputs[i].AssetId)) { if (tx.Outputs[i].Fee != Fixed8.Zero) { fee[tx.Outputs[i].AssetId] = tx.Outputs[i].Fee; } } } Fixed8 qrgFee = fee.Sum(p => p.Value); if (balance.Count > 0) { UInt256 assetId = balance.First().Key; Fixed8 value = balance.Sum(p => p.Value); AssetState assetState = Blockchain.Default.GetAssetState(assetId); obj["asset"] = assetState.GetName(); obj["amount"] = value.ToString(); obj["fee"] = qrgFee.ToString(); } } else if (tx is ClaimTransaction) { ClaimTransaction claimTx = (ClaimTransaction)tx; if (claimTx.Outputs.Length > 0) { from_script = to_script = tx.Outputs[0].ScriptHash; } Dictionary <UInt256, Fixed8> balance = new Dictionary <UInt256, Fixed8>(); Dictionary <UInt256, Fixed8> fee = new Dictionary <UInt256, Fixed8>(); for (int i = 0; i < tx.Outputs.Length; i++) { AssetState state = Blockchain.Default.GetAssetState(tx.Outputs[i].AssetId); if (tx.Outputs[i].ScriptHash.Equals(to_script)) { if (balance.ContainsKey(tx.Outputs[i].AssetId)) { balance[tx.Outputs[i].AssetId] += tx.Outputs[i].Value; } else { balance[tx.Outputs[i].AssetId] = tx.Outputs[i].Value; } } if (!fee.ContainsKey(tx.Outputs[i].AssetId)) { if (tx.Outputs[i].Fee != Fixed8.Zero) { fee[tx.Outputs[i].AssetId] = tx.Outputs[i].Fee; } } } obj["asset"] = Blockchain.UtilityToken.Name; obj["amount"] = balance[Blockchain.UtilityToken.Hash].value.ToString(); obj["fee"] = Fixed8.Zero.ToString(); } else if (tx is InvocationTransaction) { InvocationTransaction invocTx = (InvocationTransaction)tx; try { foreach (CoinReference input in tx.Inputs) { from_script = tx.References[input].ScriptHash; } } catch (Exception ex) { } obj["asset"] = Blockchain.UtilityToken.Name; obj["amount"] = invocTx.Gas.ToString(); obj["fee"] = Fixed8.Zero.ToString(); } else if (tx is IssueTransaction) { AssetState state = Blockchain.Default.GetAssetState(Blockchain.UtilityToken.Hash); IssueTransaction issueTx = (IssueTransaction)tx; try { foreach (CoinReference input in tx.Inputs) { from_script = tx.References[input].ScriptHash; } } catch (Exception ex) { } if (tx.Outputs.Length > 0) { to_script = tx.Outputs[0].ScriptHash; } if (tx.Outputs.Length > 0) { state = Blockchain.Default.GetAssetState(tx.Outputs[0].AssetId); } Fixed8 totalAmount = Fixed8.Zero; foreach (TransactionOutput output in tx.Outputs) { if (output.AssetId != Blockchain.UtilityToken.Hash) { totalAmount += output.Value; } } Fixed8 fee = issueTx.NetworkFee + issueTx.SystemFee; obj["asset"] = state.GetName(); obj["amount"] = totalAmount.ToString(); obj["fee"] = fee.ToString(); } if (!ScriptHash.Equals(from_script) && !ScriptHash.Equals(to_script)) { continue; } if (from_script != null) { obj["from"] = Wallet.ToAddress(from_script); } else { obj["from"] = ""; } if (to_script != null) { obj["to"] = Wallet.ToAddress(to_script); } else { obj["to"] = ""; } obj["txType"] = tx.Type; obj["blockHeight"] = Fixed8.Zero.ToString(); obj["txid"] = tx.Hash.ToString(); obj["timestamp"] = DateTime.Now.ToTimestamp(); obj["status"] = 0; result.Add(obj); } return(result); }