예제 #1
0
        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);
            }
        }
예제 #2
0
        /// <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));
        }
예제 #3
0
        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);
        }
예제 #4
0
        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;
        }
예제 #5
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);
        }
예제 #6
0
        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);
        }
예제 #7
0
        /// <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);
        }
예제 #8
0
 public void Put(UtxoSet set)
 {
     Put(new UtxoSet[] { set });
 }
예제 #9
0
 public static bool IsSpentInPool(this UtxoSet utxoSet)
 {
     return(utxoSet.IsSpent || TransactionPoolDac.Default.UtxoHasSpent(utxoSet.TransactionHash, utxoSet.Index));
 }
예제 #10
0
 public static bool IsSpent(this UtxoSet utxoSet)
 {
     return(utxoSet.IsSpent && utxoSet.SpentHeight != 0 && GlobalParameters.LocalHeight >= utxoSet.SpentHeight);
 }
예제 #11
0
        /// <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);
        }
예제 #12
0
 /// <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));
 }
예제 #13
0
        /// <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));
        }
예제 #14
0
        /// <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));
        }