public static async Task Main(string[] args) { if (args.Length == 0) { Console.WriteLine("User Mode"); CreateHostBuilder(args).Build().Run(); } else { if (args.Length >= 1) { Port = int.Parse(args[0]); } if (Port > 0) { // inject DbContext and HashProvider to Program.cs var services = new ServiceCollection(); services.AddTransient <IHashProvider, HashProvider>(); services.AddTransient <IBlockchainProvider, BlockchainProvider>(); services.AddDbContext <ApplicationDbContext>(options => options.UseSqlServer("Server=localhost; Database=BlockchainCharity; Trusted_Connection=True; MultipleActiveResultSets=True;") , ServiceLifetime.Transient); var serviceProvider = services.BuildServiceProvider(); _dbContext = serviceProvider.GetService <ApplicationDbContext>(); _hash = serviceProvider.GetService <IHashProvider>(); _blockchain = serviceProvider.GetService <IBlockchainProvider>(); Client = new Client(_blockchain, _hash); Server = new Server(); Server.Start(); // construct signalr connection SignalRConnection = new HubConnectionBuilder() .WithUrl(new Uri("https://127.0.0.1:5001/donateHub"), options => { //bypass SSL on SignalR Client var handler = new HttpClientHandler { ClientCertificateOptions = ClientCertificateOption.Manual, ServerCertificateCustomValidationCallback = (httpRequestMessage, cert, cetChain, policyErrors) => true }; options.HttpMessageHandlerFactory = _ => handler; options.WebSocketConfiguration = sockets => { sockets.RemoteCertificateValidationCallback = (sender, certificate, chain, policyErrors) => true; }; }) .Build(); // subscribe on method SendTransaction SignalRConnection.On <Transaction>("SendTransaction", async transaction => { await Validate(transaction); // await ChangeLeader(); Client.Broadcast($"Decrease Cooldown"); Client.InvokeVote(); await SignalRConnection.InvokeAsync("RemoveFromGroup", "Donate"); }); await SignalRConnection.StartAsync(); } await LoadChain(); Console.WriteLine("========================="); Console.WriteLine("1. Connect to a node"); Console.WriteLine("2. Be A Leader"); Console.WriteLine("3. Sync Number of Node"); Console.WriteLine("4. Vote for New Leader"); Console.WriteLine("5. Get All nodes that this node connects to"); Console.WriteLine("6. Get Current Leader"); Console.WriteLine("7. Get Cooldown"); Console.WriteLine("8. Search Transaction"); Console.WriteLine("9. Edit Transaction (For malicious node)"); Console.WriteLine("10. Get Chains"); Console.WriteLine("999. Exit"); Console.WriteLine("========================="); int selection = 0; while (selection != 999) { switch (selection) { case 1: Console.WriteLine("Please enter the port"); string port = Console.ReadLine(); Client.Connect($"{SocketUrl}{port}/Blockchain"); break; case 2: if (IsChainValid) { await Coup(); } else { Console.WriteLine("The chain is invalid...."); } break; case 3: NumNode = Client.GetServers().Count + 1; Console.WriteLine("Current Nodes are : " + NumNode); Client.Broadcast($"NumNode : {NumNode}"); DoneConnecting = true; break; case 4: Client.Broadcast($"Decrease Cooldown"); Client.InvokeVote(); await SignalRConnection.InvokeAsync("RemoveFromGroup", "Donate"); break; case 5: Console.WriteLine(JsonConvert.SerializeObject(Client.GetServers(), Formatting.Indented)); break; case 6: Console.WriteLine($"CurrentLeader : {CurrentLeader}"); break; case 7: Console.WriteLine($"CoolDown : {CoolDown}"); Console.WriteLine($"Penalty : {Penalty()}"); Console.WriteLine($"NumNode : {NumNode}"); break; case 8: Console.WriteLine("Please enter the transactionId"); string transactionId = Console.ReadLine(); var searchedTransaction = _dbContext.Transactions .FirstOrDefault(x => x.HashedTransactionId == transactionId); if (searchedTransaction == null) { Console.WriteLine("Transaction not found!"); } else { Console.WriteLine(JsonConvert.SerializeObject(searchedTransaction)); } break; case 9: Console.WriteLine("Please enter the transactionId"); string editedTransactionId = Console.ReadLine(); var transaction = _dbContext.Transactions .AsNoTracking() .FirstOrDefault(x => x.HashedTransactionId == editedTransactionId); if (transaction == null) { Console.WriteLine("Transaction not found!"); } else { var allTransactions = _dbContext.Transactions .Where(x => x.BlockHeight == transaction.BlockHeight) .AsNoTracking() .ToList(); transaction.Amount = 5000; transaction.HashedTransactionId = _hash.HashTransaction(transaction); foreach (var item in allTransactions) { if (item.id == transaction.id) { item.HashedTransactionId = transaction.HashedTransactionId; item.Amount = transaction.Amount; } } if (Program.Port == 2222) { var block = _dbContext.Blockchains1.FirstOrDefault(x => x.Height == transaction.BlockHeight); var hashedTransactions = String.Join('-', allTransactions.Select(x => x.HashedTransactionId)); block.HashedTransactionIds = hashedTransactions; block.Hash = _hash.HashBlock(block); } else if (Program.Port == 2223) { var block = _dbContext.Blockchains1.FirstOrDefault(x => x.Height == transaction.BlockHeight); var hashedTransactions = String.Join('-', allTransactions.Select(x => x.HashedTransactionId)); block.HashedTransactionIds = hashedTransactions; block.Hash = _hash.HashBlock(block); } else { var block = _dbContext.Blockchains1.FirstOrDefault(x => x.Height == transaction.BlockHeight); var hashedTransactions = String.Join('-', allTransactions.Select(x => x.HashedTransactionId)); block.HashedTransactionIds = hashedTransactions; block.Hash = _hash.HashBlock(block); } await _dbContext.SaveChangesAsync(); Console.WriteLine("Done Changing Transaction....."); } break; case 10: Console.WriteLine(JsonConvert.SerializeObject(Chain, Formatting.Indented)); break; } Console.WriteLine("Please select an action"); string action = Console.ReadLine(); await LoadChain(); selection = int.Parse(action); // if (DoneConnecting) // { // await Task.Delay(5000); if (IsDonatable) { await DonateToFoundationIfAble(); } // Console.WriteLine("FCK ASYNC"); // } } Client.Close(); await SignalRConnection.InvokeAsync("RemoveFromGroup", "Donate"); } // CreateHostBuilder(args).Build().Run(); }