예제 #1
0
        static void ProcessMoneyTransfer(Core.Domain.Transaction tx, ObsidianChainContext db)
        {
            IList <VIn>   vins       = tx.TransactionIn;
            List <string> inAdresses = new List <string>();

            foreach (var vin in vins)
            {
                AddressEntity existing = db.AddressEntities.Find(vin.PrevVOutFetchedAddress);

                if (existing == null) // work around broken index till indexing is re-run
                {
                    Console.WriteLine($"This should never happen: {vin.PrevVOutFetchedAddress} could not be found.");
                    continue;
                }


                inAdresses.Add(existing.Id);
                existing.Balance -= vin.PrevVOutFetchedValue;
                existing.LastModifiedBlockHeight = (int)tx.Block.Height;
                UpdateTxIdBlog(existing, tx.TransactionId);
            }
            IList <Out> vouts = tx.TransactionsOut;

            foreach (var vout in vouts)
            {
                string outAdress = vout.Address;
                if (outAdress.StartsWith("OP_RETURN", StringComparison.OrdinalIgnoreCase))
                {
                    outAdress = "OP_RETURN";
                }

                AddressEntity existing = db.AddressEntities.Find(outAdress);
                if (existing != null)
                {
                    existing.Balance += vout.Value;
                    if (!inAdresses.Contains(existing.Id))
                    {
                        UpdateTxIdBlog(existing, tx.TransactionId);
                        existing.LastModifiedBlockHeight = (int)tx.Block.Height;
                    }
                }
                else
                {
                    var newAddress = new AddressEntity
                    {
                        Id      = vout.Address,
                        Balance = vout.Value,
                        LastModifiedBlockHeight = (int)tx.Block.Height,
                        TxIdBlob = tx.TransactionId + CRLF
                    };
                    InsertAddressIfShouldBeIndexed(newAddress, db);
                }
            }
        }
예제 #2
0
        static void ProcessStakingReward(Core.Domain.Transaction tx, ObsidianChainContext db)
        {
            var vin        = tx.TransactionIn[0];
            var inAddress  = vin.PrevVOutFetchedAddress;
            var oldBalance = vin.PrevVOutFetchedValue;

            Debug.Assert(inAddress == tx.TransactionsOut[1].Address);
            Debug.Assert(inAddress == tx.TransactionsOut[2].Address);
            var outValue1 = tx.TransactionsOut[1].Value;
            var outValue2 = tx.TransactionsOut[2].Value;
            var change    = outValue1 + outValue2 - oldBalance;

            // I assume that only pre-existing addresses get a staking reward!
            AddressEntity existing = db.AddressEntities.Find(inAddress);

            Debug.Assert(existing != null);
            existing.Balance += change;
            existing.LastModifiedBlockHeight = (int)tx.Block.Height;
            UpdateTxIdBlog(existing, tx.TransactionId);
        }
예제 #3
0
        static void ProcessTransaction(Core.Domain.Transaction blockTx, ObsidianChainContext db)
        {
            switch (blockTx.TransactionType)
            {
            case TransactionType.PoW_Reward_Coinbase:
                ProcessPoWReward(blockTx, db);
                break;

            case TransactionType.PoS_Reward:
                ProcessStakingReward(blockTx, db);
                break;

            case TransactionType.Money:
                ProcessMoneyTransfer(blockTx, db);
                break;

            default:
                throw new IndexOutOfRangeException("Unsupported TransactionType.");
            }
        }
예제 #4
0
        static void ProcessPoWReward(Core.Domain.Transaction tx, ObsidianChainContext db)
        {
            var           vout     = tx.TransactionsOut[0];
            var           address  = vout.Address;
            var           amount   = vout.Value;
            AddressEntity existing = db.AddressEntities.Find(address);

            if (existing == null)
            {
                var newAddress = new AddressEntity
                {
                    Id      = address,
                    Balance = amount,
                    LastModifiedBlockHeight = (int)tx.Block.Height,
                    TxIdBlob = tx.TransactionId + CRLF
                };
                InsertAddressIfShouldBeIndexed(newAddress, db);
                return;
            }
            existing.Balance += amount;
            existing.LastModifiedBlockHeight = (int)tx.Block.Height;
            UpdateTxIdBlog(existing, tx.TransactionId);
        }
예제 #5
0
        private Core.Domain.Transaction GetTransaction(TransactionNinjaModel t)
        {
            var block = new Core.Domain.Block()
            {
                Hash          = t.Block.Hash,
                Height        = t.Block.Height,
                Time          = t.Block.Time,
                Confirmations = t.Block.Confirmations
            };

            var inputs = t.DeserializeInputs.Select(x => new In()
            {
                TransactionId = x.TxId,
                Address       = x.Address,
                Index         = x.Index,
                Value         = x.Value,
                AssetId       = x.AssetId,
                Quantity      = x.Quantity
            }).ToList();

            var outputs = t.DeserializeOutputs.Select(x => new Out()
            {
                TransactionId = x.TxId,
                Address       = x.Address,
                Index         = x.Index,
                Value         = x.Value,
                AssetId       = x.AssetId,
                Quantity      = x.Quantity
            }).ToList();

            var assets = new List <Core.Domain.Asset>();

            foreach (var k in t.Asset.Keys)
            {
                var assetRecord = t.Asset[k];

                var asset = new Core.Domain.Asset();
                asset.Id = k;
                if (t.TransactionUrl != null)
                {
                    asset.MetadataUrl = t.TransactionUrl.ToString();
                }

                asset.Input = assetRecord.AssetDataInput.Select(x => new In()
                {
                    TransactionId = x.TxId,
                    Address       = x.Address,
                    Index         = x.Index,
                    Value         = x.Value,
                    AssetId       = x.AssetId,
                    Quantity      = x.Quantity
                }).ToList();

                asset.Output = assetRecord.AssetDataOutput.Select(x => new Out()
                {
                    TransactionId = x.TxId,
                    Address       = x.Address,
                    Index         = x.Index,
                    Value         = x.Value,
                    AssetId       = x.AssetId,
                    Quantity      = x.Quantity
                }).ToList();

                assets.Add(asset);
            }

            var transaction = new Core.Domain.Transaction()
            {
                TransactionId   = t.TxId,
                Time            = block.Time,
                Hex             = t.Hex,
                Fees            = t.Fees,
                IsCoinBase      = t.IsCoinBase,
                IsColor         = t.IsColor,
                Block           = block,
                Blockhash       = t.Block.Hash,
                TransactionIn   = inputs,
                TransactionsOut = outputs,
                Assets          = assets
            };

            return(transaction);
        }