private static IEnumerable <Output> GetTransactionOutputs(IRpcTransaction rpcTransaction) { foreach (var output in rpcTransaction.Outputs) { var addresses = new string[0]; if (!string.IsNullOrEmpty(output.ScriptPublicKey.Hex)) { addresses = GetAddress(DecodeScriptHex(output.ScriptPublicKey.Hex)); } yield return(new Output { Value = output.Value, Index = output.Index, OutputScriptPublicKey = new OutputScriptPublicKey { Asm = output.ScriptPublicKey.Asm, Hex = output.ScriptPublicKey.Hex, RequestedSignatures = output.ScriptPublicKey.RequestedSignatures, Type = output.ScriptPublicKey.Type, OutputScriptPublicKeyAddresses = addresses.Select(address => new OutputScriptPublicKeyAddress { Address = address }) } }); } }
public static async Task Main(string[] args) { ShowAscii(); ConfigureServiceProvider(); SetNetwork(); var configuration = _serviceProvider.GetService <IConfiguration>(); var mutexName = configuration.GetValue <string>("MutexName"); using (var mutex = new Mutex(false, mutexName)) { if (!mutex.WaitOne(0, false)) { Console.WriteLine("Application already running"); return; } if (args?.FirstOrDefault() == "clear") { Console.WriteLine("Are you sure you want to clear all data? [Yes/No]"); var answer = Console.ReadLine(); if (answer?.ToLower() == "yes") { Console.WriteLine("Clearing all data..."); var clearAllDataRepository = _serviceProvider.GetService <IClearAllDataRepository>(); await clearAllDataRepository.ClearAllData(); Console.WriteLine("All data cleared"); return; } else { Console.WriteLine("Aborted"); return; } } while (true) { var c = 0L; c++; await Task.Delay(500); try { if (c % 12000 == 1) { Console.WriteLine("Still running"); } var rpcBlockCountService = _serviceProvider.GetService <IRpcBlockCountService>(); var rpcBlockService = _serviceProvider.GetService <IRpcBlockService>(); var rpcTransactionService = _serviceProvider.GetService <IRpcTransactionService>(); var rpcBlockCount = await rpcBlockCountService.GetBlockCount(); var blockCountRepository = _serviceProvider.GetService <IBlockRepository>(); var blockCount = await blockCountRepository.GetBlockHeight(); if (blockCount > 0) { blockCount++; } if (rpcBlockCount == blockCount - 1 && rpcBlockCount > 0) { continue; } for (var i = blockCount; i <= rpcBlockCount; i++) { using (var scope = _serviceProvider.CreateScope()) { var blockRepository = scope.ServiceProvider.GetService <IBlockRepository>(); var transactionRepository = scope.ServiceProvider .GetService <ITransactionRepository>(); var rpcBlock = await rpcBlockService.GetBlock(i); var block = new Block { Id = rpcBlock.Hash, Bits = rpcBlock.Bits, Chainwork = rpcBlock.Chainwork, Difficulty = rpcBlock.Difficulty, Height = rpcBlock.Height, MedianTime = rpcBlock.MedianTime, Time = rpcBlock.Time, Merkleroot = rpcBlock.Merkleroot, Nonce = rpcBlock.Nonce, Size = rpcBlock.Size, Version = rpcBlock.Version, Weight = rpcBlock.Weight, PreviousBlock = rpcBlock.PreviousBlock == GenesisBlock ? null : rpcBlock.PreviousBlock, Json = rpcBlock.Json }; await blockRepository.Insert(block); var blockOrder = 0L; foreach (var rpcBlockTransaction in rpcBlock.Transactions) { IRpcTransaction rpcTransaction = null; try { rpcTransaction = await rpcTransactionService.GetTransaction(rpcBlockTransaction); } catch (Exception) { if (block.Height > 0) { throw; } } if (rpcTransaction == null) { continue; } var transaction = new Transaction { BlockTime = rpcTransaction.BlockTime, Hash = rpcTransaction.TxId, Id = rpcTransaction.TxId, Locktime = rpcTransaction.Locktime, Size = rpcTransaction.Size, Time = rpcTransaction.Time, Version = rpcTransaction.Version, Vsize = rpcTransaction.Vsize, BlockId = rpcTransaction.BlockHash, BlockOrder = blockOrder, Json = rpcTransaction.Json }; var inputs = rpcTransaction.Inputs.Select(p => new Input { Coinbase = p.Coinbase, OutputIndex = p.Vout, Sequence = p.Sequence, TransactionId = rpcTransaction.TxId, OutputTransactionId = p.TxId, InputScriptSignature = p.ScriptSignature == null ? null : new InputScriptSignature { Asm = p.ScriptSignature.Asm, Hex = p.ScriptSignature.Hex } }); var outputs = GetTransactionOutputs(rpcTransaction); await transactionRepository.Insert(transaction, inputs, outputs); blockOrder++; } await FrontEndNotification(block.Height); if (block.Height % 100 == 0 || i == blockCount || i == rpcBlockCount) { Console.WriteLine($"{block.Height} - {block.Id}"); } } } } catch (Exception e) { Console.WriteLine("Error => {0}", e.Message); await Task.Delay(10000); } } } }