static void ProcessPoWReward(Network.Models.Transaction tx, Model.BCExplorerContext context) { foreach (var vout in tx.TransactionsOut) { //var vout = tx.TransactionsOut; var address = vout.Address; var amount = vout.Value; Model.Address existing = context.Addresses.Find(address); if (existing == null) { var newAddress = new Model.Address { Id = address, Balance = amount, LastModifiedBlockHeight = (int)tx.Block.Height, }; InsertAddressIfShouldBeIndexed(newAddress, context); UpdateTxIdBlob(newAddress, tx.TransactionId, tx.Time, newAddress.Balance, amount, context); return; } existing.Balance += amount; existing.LastModifiedBlockHeight = (int)tx.Block.Height; UpdateTxIdBlob(existing, tx.TransactionId, tx.Time, existing.Balance, amount, context); } }
private static void ProcessMoneyTransfer(Network.Models.Transaction tx, Model.BCExplorerContext context) { List <Network.Models.Transaction.TransactionIn> vins = tx.TransactionsIn; List <string> inAdresses = new List <string>(); foreach (var vin in vins) { Model.Address existing = context.Addresses.Find(vin.PrevVOutFetchedAddress); if (existing == null) { _logger.LogWarning($"{vin.PrevVOutFetchedAddress} could not be found."); continue; } inAdresses.Add(existing.Id); existing.Balance -= vin.PrevVOutFetchedValue; existing.LastModifiedBlockHeight = (int)tx.Block.Height; UpdateTxIdBlob(existing, tx.TransactionId, tx.Time, existing.Balance, -vin.PrevVOutFetchedValue, context); } IList <Network.Models.Transaction.TransactionOut> vouts = tx.TransactionsOut; foreach (var vout in vouts) { string outAdress = vout.Address; if (outAdress.StartsWith("OP_RETURN", StringComparison.OrdinalIgnoreCase)) { outAdress = "OP_RETURN"; } Model.Address existing = context.Addresses.Find(outAdress); if (existing != null) { existing.Balance += vout.Value; if (!inAdresses.Contains(existing.Id)) { UpdateTxIdBlob(existing, tx.TransactionId, tx.Time, existing.Balance, vout.Value, context); existing.LastModifiedBlockHeight = (int)tx.Block.Height; } } else { var newAddress = new Model.Address { Id = vout.Address, Balance = vout.Value, LastModifiedBlockHeight = (int)tx.Block.Height }; InsertAddressIfShouldBeIndexed(newAddress, context); UpdateTxIdBlob(newAddress, tx.TransactionId, tx.Time, newAddress.Balance, vout.Value, context); } } }
static void ProcessTransaction(Network.Models.Transaction blockTx, Model.BCExplorerContext context) { switch (blockTx.TransactionType) { case TransactionType.PoW_Reward_Coinbase: ProcessPoWReward(blockTx, context); break; case TransactionType.PoS_Reward: ProcessStakingReward(blockTx, context); break; case TransactionType.Money: ProcessMoneyTransfer(blockTx, context); break; default: throw new IndexOutOfRangeException("Unsupported TransactionType."); } }
static void ProcessStakingReward(Network.Models.Transaction tx, Model.BCExplorerContext context) { foreach (var vin in tx.TransactionsIn) { //var vin = tx.TransactionsIn[0]; var inAddress = vin.PrevVOutFetchedAddress; var oldBalance = vin.PrevVOutFetchedValue; var outValue1 = tx.TransactionsOut[1].Value; var outValue2 = tx.TransactionsOut[2].Value; var change = outValue1 + outValue2 - oldBalance; // we can assume that only pre-existing addresses get a staking reward Model.Address existing = context.Addresses.Find(inAddress); if (existing == null) { _logger.LogError($"{vin.PrevVOutFetchedAddress} could not be found."); } existing.Balance += change; existing.LastModifiedBlockHeight = (int)tx.Block.Height; UpdateTxIdBlob(existing, tx.TransactionId, tx.Time, existing.Balance, change, context); } }