//Generates and returns a new transaction from this wallet. public Transaction SendFunds(ECPublicKeyParameters recipient, decimal value, Chain chain) { if(GetBalance(chain) < value) { //gather balance and check funds. Console.WriteLine("Not Enough funds to send transaction. Transaction Discarded."); return null; } //create list of inputs - adding transaction inputs until we've got enough to satify the value List<TransactionInput> inputs = new List<TransactionInput>(); decimal total = 0; foreach(var utxo in this.Utxos.Values) { total += utxo.Value; inputs.Add(new TransactionInput(utxo.Id)); if(total > value) { break; } } // Create and sign a new transaction Transaction transaction = new Transaction(PublicKey, recipient , value, inputs); transaction.Sign(PrivateKey); // And finally clear down any utxos we've used foreach(TransactionInput ti in inputs) { Utxos.Remove(ti.TransactionOutputId); } return transaction; }
/// <summary> /// Reload address Utxos list. It will sort descending the utxos based on the utxos number of confirmations. /// Smallest number of confirmations leads to newest transations /// </summary> /// <returns></returns> public async Task ReloadUtxos() { var count = Utxos.Count; GetAddressUtxosResponse ux = null; try { ux = await DogeTransactionHelpers.AddressUtxosAsync(Address); } catch (Exception ex) { Console.WriteLine("Cannot get dogecoin address utxos. Please check the internet connection. " + ex.Message); return; } if (ux == null) { Console.WriteLine("Cannot get dogecoin address utxos. Please check the internet connection. "); return; } var ouxox = ux.Data.Utxos.OrderBy(u => u.Confirmations).ToList(); if (ouxox.Count > 0) { lock (_lock) { Utxos.Clear(); } TotalBalance = 0.0; TotalUnconfirmedBalance = 0.0; TotalSpendableBalance = 0.0; // add new ones foreach (var u in ouxox) { if (u.Confirmations <= DogeTransactionHelpers.MinimumConfirmations) { TotalUnconfirmedBalance += (Convert.ToDouble(u.Value, CultureInfo.InvariantCulture)); } else { TotalSpendableBalance += (Convert.ToDouble(u.Value, CultureInfo.InvariantCulture)); lock (_lock) { Utxos.Add(u); } } } TotalBalance = TotalSpendableBalance + TotalUnconfirmedBalance; } if (count != Utxos.Count) { NewDogeUtxos?.Invoke(this, await EventFactory.GetEvent(EventType.Info, "New Doge Transactions", "Received new dogecoin transactions.")); } }
void InitData() { if (runningTask != null) { return; } if (settingModel == null) { settingModel = BootStrapService.Default.GetPage(Pages.SendSettingPage).DataContext as SendSettingViewModel; } StaticViewModel.GlobalViewModel.IsLoading = true; Task task = new Task(() => { var min = Convert.ToInt64(MinAmount * pow); var max = Convert.ToInt64(MaxAmount * pow); var listUnspentResult = UtxoService.Default.ListPageUnspent(7, CurrentPage, PageSize, 9999999, min, max, true); if (!listUnspentResult.IsFail) { var itemCount = Convert.ToInt32(listUnspentResult.Value.Count); var pageCount = itemCount / PageSize; if (itemCount % PageSize > 0) { pageCount++; } PageCount = pageCount; Application.Current.Dispatcher.Invoke(() => { Utxos.Clear(); var items = listUnspentResult.Value.UnspentList; var utxos = settingModel.Setting.UTXO; if (utxos != null) { items = items.Where(x => !utxos.Any(u => u.Txid == x.Txid && u.Vout == x.Vout)).ToList(); } items.ForEach(x => Utxos.Add(x)); runningTask = null; }); } }); task.ContinueWith(t => { StaticViewModel.GlobalViewModel.IsLoading = false; runningTask = null; }); task.Start(); runningTask = task; }
public async Task StartAsync(CancellationToken cancel) { while (true) { try { if (cancel.IsCancellationRequested) { return; } int blockCount = await Global.RpcClient.GetBlockCountAsync(); // purge outdated at every new block if (PreviousBlockCount != blockCount) { var toRemove = new HashSet <BannedUtxo>(); // remove the expired ones foreach (BannedUtxo utxo in Utxos) { var maxBan = (int)TimeSpan.FromDays(30).TotalMinutes; int banLeft = maxBan - (int)((DateTimeOffset.UtcNow - utxo.TimeOfBan).TotalMinutes); if (banLeft < 0) { toRemove.Add(utxo); } } // note: do not check if still utxo, it's faster to iterate this list needlessly than ask the rpc if (toRemove.Count > 0) { foreach (var utxo in toRemove) { Utxos.TryRemove(utxo); } await ToFileAsync(Global.UtxoRefereePath); } } await Task.Delay(TimeSpan.FromSeconds(21), cancel).ContinueWith(t => { }); } catch (Exception ex) { Console.WriteLine($"Ignoring {nameof(UtxoReferee)} exception: {ex}"); } } }
private async Task <string> processOrder(Utxos utxo, ITransaction txinfo, IShopItem mainItem) { var amountOfTokens = (int)((mainItem.Price / (utxo.Value / neblio.FromSatToMainRatio)) * mainItem.Lot); if (amountOfTokens != 0) { try { var meta = new Dictionary <string, string>(); meta.Add("Token Order", "true"); meta.Add("PaymentTxId", utxo.Txid); var sutxs = await NeblioTransactionHelpers.FindUtxoForMintNFT(Address, TokenId, amountOfTokens - 1); if (sutxs.Count != 0) { var sendutxos = new List <string>(); foreach (var s in sutxs) { sendutxos.Add(s.Txid + ":" + s.Index); } var dto = new SendTokenTxData() { Amount = amountOfTokens, Id = TokenId, Metadata = meta, Password = string.Empty, // shop must be unlocked SenderAddress = Address, ReceiverAddress = txinfo.From[0], sendUtxo = sendutxos, NeblUtxo = utxo.Txid, UseRPCPrimarily = false }; var resp = await NeblioTransactionHelpers.SendNTP1TokenAPI(dto, isItMintNFT : true); return(resp); } } catch (Exception ex) { log.Error("Cannot send ordered tokens!", ex); } } return(string.Empty); }
public void UpdateUtxos() { lock (Utxos) { var inEntries = Chain.SelectMany(x => x.Transactions.SelectMany(tx => tx.Inputs)); var txO = Chain.SelectMany(x => x.Transactions) .Select(x => (x.Outputs, x.Id)) .SelectMany((x) => ToTxO(x.Outputs, x.Id)); var newUtxos = txO .Where(x => !inEntries.Any(input => input.TransactionId.Equals(x.TransactionId) && input.OutputIndex == x.OutIndex ) ); Utxos.Clear(); Utxos.AddRange(newUtxos); } }
public void Run(Transaction tx, DateTime blockTime, ulong coinbase = 0, List <TransactionOutput> spentTxo = null) { logger.LogDebug($@"Attempt to run TX:{ tx.Id.ToString().Substring(0, 7)}"); // Transaction header validity check. if (tx.Timestamp > blockTime || !(coinbase == 0 ^ tx.InEntries.Count == 0)) { throw new ArgumentException(); } // In-Entry validity check. ulong inSum = coinbase; var redeemed = new List <TransactionOutput>(); var signHash = BlockchainUtil.GetTransactionSignHash(tx.Original); foreach (var inEntry in tx.InEntries) { // Signature check. var verified = EccService.Verify( signHash, inEntry.Signature, inEntry.PublicKey); // UTXO check. The transaction output must not be spent by // previous transactions. var txo = new TransactionOutput { TransactionId = inEntry.TransactionId, OutIndex = inEntry.OutEntryIndex, }; var unspent = !(spentTxo?.Contains(txo) ?? false) && Utxos.TryGetValue(txo, out txo); // Recipient address check. var addr = BlockchainUtil.ToAddress(inEntry.PublicKey); var redeemable = txo.Recipient.Equals( ByteString.CopyFrom(addr)); // Sum all the reedemable. inSum = checked (inSum + txo.Amount); if (!verified || !unspent || !redeemable) { throw new ArgumentException(); } redeemed.Add(txo); } // Out-entry validity check. ulong outSum = 0; ushort outIndex = 0; var generated = new List <TransactionOutput>(); foreach (var outEntry in tx.OutEntries) { if (outEntry.RecipientHash.IsNull() || outEntry.Amount <= 0) { throw new ArgumentException(); } // Sum all the transferred. outSum = checked (outSum + outEntry.Amount); // Create new UTXO entry. generated.Add(new TransactionOutput { TransactionId = tx.Id, OutIndex = outIndex++, Recipient = outEntry.RecipientHash, Amount = outEntry.Amount, }); } // Output exceeds input or coinbase. if (outSum > inSum) { throw new ArgumentException(); } tx.ExecInfo = new TransactionExecInformation { Coinbase = coinbase != 0, RedeemedOutputs = redeemed, GeneratedOutputs = generated, TransactionFee = inSum - outSum, }; }
/// <summary> /// Constructor which loads the Utxo hash /// </summary> /// <param name="utxo"></param> public NeblioBuilderUtxo(Utxos utxo) { Utxo = utxo; }
public static Utxos GetFakeNeblioUtxo(string address = "", bool randomIndex = true, int maxIndex = 4, int index = 0, int blocktime = 0, int maxBlocktime = 1000, int blockheight = 0, int value = 0, int maxValue = 1000000000) { var utxo = new Utxos(); var random = new Random(); var addr = GetAddress(address); if (randomIndex) { index = random.Next(0, maxIndex); } utxo.Index = index; utxo.ScriptPubKey = addr.ScriptPubKey.ToString(); if (blocktime == 0) { blocktime = random.Next(0, maxBlocktime); } utxo.Blocktime = blocktime; if (blockheight == 0) { blockheight = blocktime + 10000; } utxo.Blockheight = blockheight; utxo.Tokens = new List <Tokens>(); if (value == 0) { value = random.Next(0, maxValue); } utxo.Value = value; //fake tx to create some real calc hash var transaction = Transaction.Create(NeblioTransactionHelpers.Network); transaction.Inputs.Add(new TxIn() { PrevOut = new OutPoint(uint256.Parse(RandHash()), (int)utxo.Index), ScriptSig = addr.ScriptPubKey, }); transaction.Inputs.Add(new TxIn() { PrevOut = new OutPoint(uint256.Parse(RandHash()), (int)utxo.Index), ScriptSig = addr.ScriptPubKey, }); transaction.Outputs.Add(new Money(1000000), addr.ScriptPubKey); transaction.Outputs.Add(new Money(100000), addr.ScriptPubKey); utxo.Txid = transaction.GetHash().ToString(); return(utxo); }