public void Initialize() { var accountDac = new AccountDac(); var accountIds = accountDac.SelectAll().Select(a => a.Id).ToArray(); UtxoSet.Initialize(accountIds); foreach (var id in accountIds) { this.RefreshUtxoSet(id); } }
/// <summary> /// 是否可花费 /// </summary> /// <param name="utxoSet"></param> /// <param name="lastHeight"></param> /// <param name="localTime"></param> /// <returns></returns> public static bool IsSpentable(this UtxoSet utxoSet, long lastHeight, long localTime) { if (utxoSet.IsSpent()) { return(false); } var confirmcount = lastHeight - utxoSet.BlockHeight; if (TransactionPoolDac.Default.UtxoHasSpent(utxoSet.TransactionHash, utxoSet.Index)) { return(false); } return((confirmcount >= 100 && utxoSet.IsCoinbase) || (confirmcount >= 6 && !utxoSet.IsCoinbase && utxoSet.Locktime <= localTime)); }
private bool ValidateDoubleSpend() { var inputs = Bitcoin.TransactionPool .SelectMany(x => x.InputList) .Distinct(); foreach (var item in inputs) { var utxo = UtxoSet.Where(x => x.TxId == item.TxId && x.vOut == item.VOut); if (utxo != null && utxo.Count() > 1) { return(false); } } return(true); }
private void CreateUtxo() { var utxoMiner = new Utxo("0000000000", 0, rewardMinerCoinbase, AddressMiner); UtxoSet.Add(utxoMiner); foreach (var transaction in Bitcoin.TransactionPool.Distinct()) { foreach (var output in transaction.OutputList) { var vOut = transaction.OutputList.IndexOf(output); var utxo = new Utxo(transaction.TxId, vOut, output.Value, output.Address); UtxoSet.Add(utxo); } } rewardMinerCoinbase = 0; }
private void ExcludeUtxo() { var inputs = Bitcoin.TransactionPool .SelectMany(x => x.InputList) .Distinct(); var utxoList = new List <Utxo>(); foreach (var item in inputs) { UtxoSet.RemoveAll(x => x.TxId == item.TxId && x.vOut == item.VOut); } //var exclude = UtxoSet.FirstOrDefault(x => x.TxId == "0000000000" && x.Address == AddressMiner); UtxoSet.RemoveAll(x => x.TxId == "0000000000" && x.Address == AddressMiner); }
private decimal ReturnSumInputs() { var inputs = Bitcoin.TransactionPool .SelectMany(x => x.InputList) .Distinct(); decimal sumInputs = 0; foreach (var item in inputs) { var utxo = UtxoSet.FirstOrDefault(x => x.TxId == item.TxId && x.vOut == item.VOut); if (utxo != null) { sumInputs += utxo.Value; } } sumInputs += UtxoSet.Where(x => x.Address == AddressMiner && x.TxId == "0000000000").Sum(x => x.Value); return(sumInputs); }
/// <summary> /// 获取到区块受影响的UTXO信息 /// </summary> /// <param name="block"></param> /// <returns></returns> public static BlockUpdateData GetBlockUpdateData(this BlockMsg block) { BlockUpdateData blockUpdateData = new BlockUpdateData(); var coinbase = block.Transactions[0]; foreach (var tx in block.Transactions) { foreach (var output in tx.Outputs) { UtxoSet utxoSet = new UtxoSet { BlockHeight = block.Header.Height, IsCoinbase = tx.Hash.Equals(coinbase.Hash), IsSpent = false, Locktime = tx.Locktime, DepositTime = tx.DepositTime, TransactionHash = tx.Hash, Index = output.Index, Amount = output.Amount, BlockHash = block.Header.Hash, BlockTime = block.Header.Timestamp, TransactionTime = tx.Timestamp, LockScript = output.LockScript, Account = GetAccountByLockScript == null ? null : GetAccountByLockScript(output.LockScript) }; blockUpdateData.NewUtxoSet.Add(utxoSet); blockUpdateData.UtxoSetState.Add(new UtxoSetState { Transaction = tx.Hash, Index = output.Index }); } foreach (var input in tx.Inputs) { blockUpdateData.SpentUtxoSet.Add($"{input.OutputTransactionHash}_{input.OutputIndex}"); blockUpdateData.UtxoSetState.Add(new UtxoSetState { Transaction = input.OutputTransactionHash, Index = input.OutputIndex, State = 1 }); } } return(blockUpdateData); }
public void Put(UtxoSet set) { Put(new UtxoSet[] { set }); }
public static bool IsSpentInPool(this UtxoSet utxoSet) { return(utxoSet.IsSpent || TransactionPoolDac.Default.UtxoHasSpent(utxoSet.TransactionHash, utxoSet.Index)); }
public static bool IsSpent(this UtxoSet utxoSet) { return(utxoSet.IsSpent && utxoSet.SpentHeight != 0 && GlobalParameters.LocalHeight >= utxoSet.SpentHeight); }
/// <summary> /// 这笔Utxo消费是否已确认 /// </summary> /// <param name="utxoSet"></param> /// <param name="lastHeight"></param> /// <returns></returns> public static bool IsSpentConfirmed(this UtxoSet utxoSet, long lastHeight) { var confirmcount = utxoSet.SpentHeight - lastHeight; return(confirmcount >= 6); }
/// <summary> /// 是否正在等待中 /// </summary> /// <param name="utxoSet"></param> /// <param name="lastHeight"></param> /// <param name="localTime"></param> /// <returns></returns> public static bool IsWaiting(this UtxoSet utxoSet, long lastHeight, long localTime) { return(!utxoSet.IsSpent() && utxoSet.IsSpentableWithoutPool(lastHeight, localTime)); }
/// <summary> /// 是否可花费(排除交易池中的数据) /// </summary> /// <param name="utxoSet"></param> /// <param name="lastHeight"></param> /// <param name="localTime"></param> /// <returns></returns> private static bool IsSpentableWithoutPool(this UtxoSet utxoSet, long lastHeight, long localTime) { var confirmcount = lastHeight - utxoSet.BlockHeight; return(!((confirmcount < 100 && utxoSet.IsCoinbase) || (confirmcount < 6 && !utxoSet.IsCoinbase) || utxoSet.Locktime > localTime)); }
/// <summary> /// 是否已确认 /// </summary> /// <param name="utxoSet"></param> /// <param name="lastHeight"></param> /// <returns></returns> public static bool IsConfirmed(this UtxoSet utxoSet, long lastHeight) { var confirmcount = lastHeight - utxoSet.BlockHeight; return((confirmcount >= 100 && utxoSet.IsCoinbase) || (confirmcount >= 6 && !utxoSet.IsCoinbase)); }