protected static UnspentCoin[] FindUnspentCoins(IEnumerable <UnspentCoin> unspents, UInt256 asset_id, Fixed8 amount) { unspents = unspents.Where(p => p.AssetId == asset_id); UnspentCoin coin = unspents.FirstOrDefault(p => p.Value == amount); if (coin != null) { return new[] { coin } } ; coin = unspents.OrderBy(p => p.Value).FirstOrDefault(p => p.Value > amount); if (coin != null) { return new[] { coin } } ; Fixed8 sum = unspents.Sum(p => p.Value); if (sum < amount) { return(null); } if (sum == amount) { return(unspents.ToArray()); } return(unspents.OrderByDescending(p => p.Value).TakeWhile(p => { if (amount == Fixed8.Zero) { return false; } amount -= Fixed8.Min(amount, p.Value); return true; }).ToArray()); }
private void ProcessNewBlock(Block block) { List <TransactionInput> spent = new List <TransactionInput>(); Dictionary <TransactionInput, UnspentCoin> unspent = new Dictionary <TransactionInput, UnspentCoin>(); lock (contracts) { foreach (Transaction tx in block.Transactions) { for (ushort index = 0; index < tx.Outputs.Length; index++) { TransactionOutput output = tx.Outputs[index]; if (contracts.ContainsKey(output.ScriptHash)) { UnspentCoin coin = new UnspentCoin { Input = new TransactionInput { PrevHash = tx.Hash, PrevIndex = index }, AssetId = output.AssetId, Value = output.Value, ScriptHash = output.ScriptHash }; unspent.Add(coin.Input, coin); } } } } foreach (TransactionInput input in block.Transactions.SelectMany(p => p.GetAllInputs())) { if (unspent.ContainsKey(input)) { unspent.Remove(input); } else { spent.Add(input); } } lock (unspent_coins) lock (change_coins) { foreach (TransactionInput input in spent) { unspent_coins.Remove(input); change_coins.Remove(input); } foreach (var coin in unspent) { change_coins.Remove(coin.Key); unspent_coins.Add(coin.Key, coin.Value); } } current_height++; if (spent.Count > 0 || unspent.Count > 0) { OnProcessNewBlock(spent, unspent.Values); if (BalanceChanged != null) { BalanceChanged(this, EventArgs.Empty); } } }