예제 #1
0
        //Check whether output has been spent or contained in another transaction, true = spent, false = unspent
        private bool checkOutputSpent(string currentTxHash, string outputTxHash, int outputIndex)
        {
            var outputDac = new OutputDac();
            var inputDac  = new InputDac();
            var txDac     = new TransactionDac();
            var blockDac  = new BlockDac();

            var outputEntity = outputDac.SelectByHashAndIndex(outputTxHash, outputIndex);
            var inputEntity  = inputDac.SelectByOutputHash(outputTxHash, outputIndex);

            if (inputEntity != null && inputEntity.TransactionHash != currentTxHash)
            {
                var tx = txDac.SelectByHash(inputEntity.TransactionHash);

                if (tx != null)
                {
                    var blockEntity = blockDac.SelectByHash(tx.BlockHash);

                    if (blockEntity != null && blockEntity.IsVerified)
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
예제 #2
0
        private BlockMsg convertEntityToBlockMsg(Block entity)
        {
            var txDac     = new TransactionDac();
            var inputDac  = new InputDac();
            var outputDac = new OutputDac();

            var blockMsg  = new BlockMsg();
            var headerMsg = new BlockHeaderMsg();

            headerMsg.Version           = entity.Version;
            headerMsg.Hash              = entity.Hash;
            headerMsg.Height            = entity.Height;
            headerMsg.PreviousBlockHash = entity.PreviousBlockHash;
            headerMsg.Bits              = entity.Bits;
            headerMsg.Nonce             = entity.Nonce;
            headerMsg.Timestamp         = entity.Timestamp;

            var transactions = txDac.SelectByBlockHash(entity.Hash);

            headerMsg.TotalTransaction = transactions == null ? 0: transactions.Count;

            foreach (var tx in transactions)
            {
                var txMsg = new TransactionMsg();
                txMsg.Version   = tx.Version;
                txMsg.Hash      = tx.Hash;
                txMsg.Timestamp = tx.Timestamp;
                txMsg.Locktime  = tx.LockTime;

                var inputs  = inputDac.SelectByTransactionHash(tx.Hash);
                var outputs = outputDac.SelectByTransactionHash(tx.Hash);

                foreach (var input in inputs)
                {
                    txMsg.Inputs.Add(new InputMsg
                    {
                        OutputTransactionHash = input.OutputTransactionHash,
                        OutputIndex           = input.OutputIndex,
                        Size         = input.Size,
                        UnlockScript = input.UnlockScript
                    });
                }

                foreach (var output in outputs)
                {
                    txMsg.Outputs.Add(new OutputMsg
                    {
                        Index      = output.Index,
                        Amount     = output.Amount,
                        Size       = output.Size,
                        LockScript = output.LockScript
                    });
                }

                blockMsg.Transactions.Add(txMsg);
            }

            blockMsg.Header = headerMsg;
            return(blockMsg);
        }
예제 #3
0
        public List <BlockMsg> GetBlockMsgByHeights(List <long> heights)
        {
            var blockDac  = new BlockDac();
            var txDac     = new TransactionDac();
            var inputDac  = new InputDac();
            var outputDac = new OutputDac();
            var blocks    = new List <BlockMsg>();

            foreach (var height in heights)
            {
                var items = blockDac.SelectByHeight(height);

                foreach (var entity in items)
                {
                    blocks.Add(this.convertEntityToBlockMsg(entity));
                }
            }

            return(blocks);
        }
예제 #4
0
        public TransactionMsg ConvertTxEntityToMsg(Transaction tx)
        {
            var inputDac  = new InputDac();
            var outputDac = new OutputDac();

            var txMsg = new TransactionMsg();

            txMsg.Version   = tx.Version;
            txMsg.Hash      = tx.Hash;
            txMsg.Timestamp = tx.Timestamp;
            txMsg.Locktime  = tx.LockTime;

            var inputs  = inputDac.SelectByTransactionHash(tx.Hash);
            var outputs = outputDac.SelectByTransactionHash(tx.Hash);

            foreach (var input in inputs)
            {
                txMsg.Inputs.Add(new InputMsg
                {
                    OutputTransactionHash = input.OutputTransactionHash,
                    OutputIndex           = input.OutputIndex,
                    Size         = input.Size,
                    UnlockScript = input.UnlockScript
                });
            }

            foreach (var output in outputs)
            {
                txMsg.Outputs.Add(new OutputMsg
                {
                    Index      = output.Index,
                    Amount     = output.Amount,
                    Size       = output.Size,
                    LockScript = output.LockScript
                });
            }

            return(txMsg);
        }
예제 #5
0
        public Transaction GetTransactionEntityByHash(string hash)
        {
            var inputDac  = new InputDac();
            var outputDac = new OutputDac();
            var item      = new TransactionDac().SelectByHash(hash);

            if (item != null)
            {
                item.Inputs  = inputDac.SelectByTransactionHash(item.Hash);
                item.Outputs = outputDac.SelectByTransactionHash(item.Hash);
            }
            else
            {
                var msg = TransactionPool.Instance.GetTransactionByHash(hash);

                if (msg != null)
                {
                    item = this.ConvertTxMsgToEntity(msg);
                }
            }

            return(item);
        }
예제 #6
0
        public void SaveBlockIntoDB(BlockMsg msg)
        {
            try
            {
                VerifyBlock(msg);

                Block block = this.convertBlockMsgToEntity(msg);
                block.IsDiscarded = false;
                block.IsVerified  = false;

                var blockDac       = new BlockDac();
                var transactionDac = new TransactionDac();
                var inputDac       = new InputDac();
                var outputDac      = new OutputDac();

                //foreach (var tx in block.Transactions)
                //{
                //    foreach (var input in tx.Inputs)
                //    {
                //        if (input.OutputTransactionHash != Base16.Encode(HashHelper.EmptyHash()))
                //        {
                //            var output = outputDac.SelectByHashAndIndex(input.OutputTransactionHash, input.OutputIndex);

                //            if (output != null)
                //            {
                //                input.AccountId = output.ReceiverId;
                //                outputDac.UpdateSpentStatus(input.OutputTransactionHash, input.OutputIndex);
                //            }
                //        }
                //    }
                //}

                blockDac.Save(block);

                //update nextblock hash
                //blockDac.UpdateNextBlockHash(block.PreviousBlockHash, block.Hash);

                //remove transactions in tx pool
                foreach (var tx in block.Transactions)
                {
                    TransactionPool.Instance.RemoveTransaction(tx.Hash);

                    //save into utxo set
                    foreach (var output in tx.Outputs)
                    {
                        var accountId = AccountIdHelper.CreateAccountAddressByPublicKeyHash(
                            Base16.Decode(
                                Script.GetPublicKeyHashFromLockScript(output.LockScript)
                                )
                            );

                        UtxoSet.Instance.AddUtxoRecord(new UtxoMsg
                        {
                            AccountId       = accountId,
                            BlockHash       = block.Hash,
                            TransactionHash = tx.Hash,
                            OutputIndex     = output.Index,
                            Amount          = output.Amount,
                            IsConfirmed     = true
                        });
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error(ex.Message, ex);
                throw ex;
            }
        }
예제 #7
0
        public List <Transaction> SearchTransactionEntities(string account, int count, int skip = 0, bool includeWatchOnly = true)
        {
            var inputDac  = new InputDac();
            var outputDac = new OutputDac();
            var items     = new TransactionDac().SelectTransactions(account, count, skip, includeWatchOnly);
            var accounts  = new AccountDac().SelectAll();

            foreach (var item in items)
            {
                item.Inputs  = inputDac.SelectByTransactionHash(item.Hash);
                item.Outputs = outputDac.SelectByTransactionHash(item.Hash);
            }

            if (skip == 0)
            {
                var  txList = TransactionPool.Instance.GetAllTransactions();
                bool containsUnconfirmedTx = false;

                foreach (var tx in txList)
                {
                    var  entity            = this.ConvertTxMsgToEntity(tx);
                    bool isSendTransaction = false;
                    if (entity != null)
                    {
                        foreach (var input in entity.Inputs)
                        {
                            if (accounts.Where(a => a.Id == input.AccountId).Count() > 0)
                            {
                                items.Add(entity);
                                isSendTransaction     = true;
                                containsUnconfirmedTx = true;
                                break;
                            }
                        }

                        if (!isSendTransaction)
                        {
                            foreach (var output in entity.Outputs)
                            {
                                if (accounts.Where(a => a.Id == output.ReceiverId).Count() > 0)
                                {
                                    items.Add(entity);
                                    containsUnconfirmedTx = true;
                                    break;
                                }
                            }
                        }
                    }
                }

                if (containsUnconfirmedTx)
                {
                    items = items.OrderByDescending(t => t.Timestamp).ToList();
                }
            }
            //var result = new List<TransactionMsg>();

            //foreach(var item in items)
            //{
            //    result.Add(convertTxEntityToMsg(item));
            //}

            //return result;
            return(items);
        }