using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.Threading; using System.Windows.Threading; using System.Collections.ObjectModel; using System.Collections; using System.Data; using System.Net.Sockets; using System.Net; using System.Windows.Media.Media3D; using System.Text.Json; using System.Security.Claims; namespace WpfBlockChanApp { public partial class MainWindow : Window { DispatcherTimer timer1s; DispatcherTimer timer1m; ObservableCollection observableBlockChain = new ObservableCollection(); ObservableCollection observableString = new ObservableCollection(); //static List strings = new List(); static List clients = new List(); const string STD_IP = "127.0.0.1"; static string data; public MainWindow() { InitializeComponent(); this.DataContext = this; ChainView.ItemsSource = observableBlockChain; LogView.ItemsSource = observableString; timer1s = new DispatcherTimer(); timer1s.Interval = TimeSpan.FromSeconds(1); timer1s.Tick += UpdateData; timer1s.Start(); timer1m = new DispatcherTimer(); timer1m.Interval = TimeSpan.FromSeconds(30); timer1m.Tick += Timer1m_Tick; timer1m.Start(); tcpListener = new TcpListener(IPAddress.Parse(STD_IP), 0); tcpListener.Start(); data = ((IPEndPoint)tcpListener.LocalEndpoint).Port.ToString(); MyPort.Content = data; Blockchain.Chain = new List(); Blockchain.Compute = true; Block tmpBlock = new Block(0, "", "", 0, 0); tmpBlock.Hash = ""; Blockchain.Chain.Add(tmpBlock); stopNetwork = false; listenThread = new Thread(() => listenerThredFunction()); listenThread.Start(); } private void Timer1m_Tick(object? sender, EventArgs e) { UpdateClients(); } void UpdateData(object? sender, EventArgs e) { for (int i = observableBlockChain.Count; i < Blockchain.Chain.Count; i++) observableBlockChain.Add(Blockchain.Chain[i]); for (int i = observableString.Count; i < clients.Count; i++) observableString.Add(clients[i]); } Thread calcualteBlockThread; static bool stopNetwork = false; static bool stopMiner = false; static void ComputeBlockThreadFunction() { while (true) { if (stopMiner) break; Blockchain.Compute = true; ReturnOption option = Blockchain.ComputeBlock(data); if (!option.isValid) { continue; } if (Blockchain.AddBlock(option.value)) { UpdateClients(option.value); //UpdateClients(); } } } static TcpListener tcpListener; Thread listenThread; static void listenerThredFunction() { while (true) { if (stopNetwork) break; listen(); } } static void listen() { try { using TcpClient tcpClient = tcpListener.AcceptTcpClient(); using NetworkStream networkStream = tcpClient.GetStream(); byte[] buffer = new byte[4]; int readByts = networkStream.Read(buffer, 0, buffer.Length); if (readByts <= 0) return; int sizeOfStruct = BitConverter.ToInt32(buffer); byte[] isListBuffer = new byte[1]; readByts = networkStream.Read(isListBuffer, 0, isListBuffer.Length); if(readByts <= 0) return; bool isList = BitConverter.ToBoolean(isListBuffer); byte[] data = new byte[sizeOfStruct]; int messageSize = networkStream.Read(data, 0, data.Length); if (messageSize <= 0) return; string messageString = Encoding.UTF8.GetString(data, 0, messageSize); if (isList) { List chain = JsonSerializer.Deserialize>(messageString); if (!Blockchain.IsValid(chain)) return; bool update = Blockchain.Evaluete(chain, Blockchain.Chain); if (update) { Blockchain.Chain = chain; Blockchain.Compute = false; UpdateClients(); } } else { Block block = JsonSerializer.Deserialize(messageString); if (Blockchain.AddBlock(block)) { Blockchain.Compute = false; UpdateClients(block); } } } catch (Exception e) { } } static void UpdateClients() { string chainString = JsonSerializer.Serialize(Blockchain.Chain); foreach (var clien in clients) { UpdateClient(clien, chainString, true); } } static void UpdateClients(Block block) { string blockString = JsonSerializer.Serialize(block); foreach (var clien in clients) { UpdateClient(clien, blockString, false); } } static void UpdateClient(int port, string data, bool isListBool) { try { using TcpClient tcpClient = new TcpClient(); tcpClient.Connect(IPAddress.Parse(STD_IP), port); using NetworkStream networkStream = tcpClient.GetStream(); byte[] dataBytes = Encoding.UTF8.GetBytes(data); byte[] isList = BitConverter.GetBytes(isListBool); byte[] size = BitConverter.GetBytes(dataBytes.Length); networkStream.Write(size, 0, size.Length); networkStream.Write(isList, 0, isList.Length); networkStream.Write(dataBytes, 0, dataBytes.Length); }catch(Exception e) { } } private void Start_Click(object sender, RoutedEventArgs e) { Blockchain.Compute = true; stopMiner = false; calcualteBlockThread = new Thread(() => ComputeBlockThreadFunction()); calcualteBlockThread.Start(); } private void Stop_Click(object sender, RoutedEventArgs e) { Blockchain.Compute = false; stopMiner = true; } private void Connect_Click(object sender, RoutedEventArgs e) { int i = 0; if(int.TryParse(ConnectBox.Text, out i)) { clients.Add(i); ConnectBox.Text = ""; } } private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) { stopNetwork = true; stopMiner = true; tcpListener.Stop(); Blockchain.Compute = false; } } }