public bool ValidateInput(string[] args) { string lastBlockHash = this.blockchain.LastBlock.BlockHash; int nonce = int.Parse(args[1]); string winnerHash = CryptographyUtilities.BytesToHex(CryptographyUtilities.CalcSHA256($"{lastBlockHash}{nonce}")); if (!winnerHash.ToCharArray().Take(this.blockchain.Difficulty).All(s => s == '0')) { Console.WriteLine("Incorrect hash..."); return(false); } return(true); }
public void Run(string[] args) { if (this.walletProvider.HasWallet()) { Console.WriteLine("-------------------------"); Console.WriteLine($"Address: {this.walletProvider.Address}"); Console.WriteLine($"Public key: {CryptographyUtilities.BytesToHex(this.walletProvider.PublicKey.GetEncoded())}"); Console.WriteLine("-------------------------"); Console.WriteLine("Transaction history"); PrintTransactionHistory(this.walletProvider.Address); } else { Console.WriteLine("None wallet found..."); } }
public Block AddBlock(int nonce, WalletProvider walletProvider) { string lastBlockHash = this.LastBlock.BlockHash; string winnerHash = CryptographyUtilities.BytesToHex(CryptographyUtilities.CalcSHA256($"{lastBlockHash}{nonce}")); if (!winnerHash.ToCharArray().Take(this.Difficulty).All(s => s == '0')) { Console.WriteLine("Incorrect winner hash..."); return(null); } var transactions = this.pendingTransactions; foreach (var transaction in transactions) { transaction.DateReceived = DateTime.Now; transaction.MinedInBlockIndex = this.LastBlock.Index + 1; } var block = new Block() { Index = this.LastBlock.Index + 1, DateCreated = DateTime.Now, Difficulty = this.Difficulty, MinedBy = walletProvider.Address, Nonce = nonce, PreviousBlockHash = this.LastBlock.BlockHash, Transactions = transactions.ToList() }; string blockJson = JsonConvert.SerializeObject(block); var blockHash = CryptographyUtilities.BytesToHex(CryptographyUtilities.CalcSHA256(blockJson)); block.BlockHash = blockHash; this.blocks.Add(block); StorageFileProvider <Block> .SetModel($"{Constants.BlocksFilePath}/block_{block.Index}.json", block); //Shoud think :-) this.pendingTransactions = new List <Transaction>(); StorageFileProvider <Transaction[]> .SetModel(Constants.PendingTransactionsFilePath, this.pendingTransactions.ToArray()); return(block); }
public void CreateGenesis() { var genesisBlock = new Block(); genesisBlock.Index = 0; genesisBlock.DateCreated = DateTime.Now; genesisBlock.Difficulty = 0; genesisBlock.MinedBy = "GENESIS"; genesisBlock.Nonce = 0; genesisBlock.PreviousBlockHash = "GENESIS"; var transaction = new Transaction() { From = "GENESIS", To = "e39f2a9daf79084f96b28d0b92439b0b6112981c", Value = 1000000000000000, SenderPublicKey = null, SenderSignature = null }; string transactionJson = JsonConvert.SerializeObject(transaction); var transactionHash = CryptographyUtilities.BytesToHex(CryptographyUtilities.CalcSHA256(transactionJson)); transaction.TransactionHash = transactionHash; transaction.DateReceived = DateTime.Now; genesisBlock.Transactions = new List <Transaction>(); genesisBlock.Transactions.Add(transaction); string blockJson = JsonConvert.SerializeObject(genesisBlock); var blockHash = CryptographyUtilities.BytesToHex(CryptographyUtilities.CalcSHA256(blockJson)); genesisBlock.BlockHash = blockHash; string path = $"{Constants.BlocksFilePath}/block_0.json"; StorageFileProvider <Block> .SetModel(path, genesisBlock); this.blocks.Add(genesisBlock); }
public Transaction AddTransaction(string from, string to, decimal amount, IWalletProvider walletProvider) { this.CalculateBalances(0); if (balances.ContainsKey(from) && balances[from] < amount) { Console.WriteLine("Not enought coins..."); return(null); } var publicKeyHex = CryptographyUtilities.BytesToHex(walletProvider.PublicKey.GetEncoded()); var transaction = new Transaction() { From = from, To = to, Value = amount, SenderPublicKey = publicKeyHex }; string transactionJson = JsonConvert.SerializeObject(transaction, new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }); var transactionHash = CryptographyUtilities.BytesToHex(CryptographyUtilities.CalcSHA256(transactionJson)); var signiture = walletProvider.SignTransaction(Encoding.UTF8.GetBytes(transactionHash)); transaction.TransactionHash = transactionHash; transaction.SenderSignature = signiture; this.pendingTransactions.Add(transaction); StorageFileProvider <Transaction[]> .SetModel(Constants.PendingTransactionsFilePath, this.pendingTransactions.ToArray()); Console.WriteLine("Transaction is pending..."); return(transaction); }
public bool ValidateBlock(Block block, IDictionary <string, decimal> futureBalances = null) { Console.WriteLine("Validate block..."); int nonce = block.Nonce; string lastBlockHash = this.LastBlock.BlockHash; string winnerHash = CryptographyUtilities.BytesToHex(CryptographyUtilities.CalcSHA256($"{lastBlockHash}{nonce}")); if (!winnerHash.ToCharArray().Take(this.Difficulty).All(s => s == '0')) { Console.WriteLine("^^^^^^^^^^^^^^^^^^^^^^^^^"); Console.WriteLine("Block validation failed..."); Console.WriteLine("INFO -> Incorrect winner hash..."); Console.WriteLine($"Block number: {block.Index}, last block: {this.LastBlock.Index}"); return(false); } var copyOfBlock = new Block() { Index = block.Index, DateCreated = block.DateCreated, Difficulty = block.Difficulty, MinedBy = block.MinedBy, Nonce = block.Nonce, PreviousBlockHash = block.PreviousBlockHash, Transactions = block.Transactions }; string blockJson = JsonConvert.SerializeObject(copyOfBlock); var blockHash = CryptographyUtilities.BytesToHex(CryptographyUtilities.CalcSHA256(blockJson)); if (blockHash != block.BlockHash) { Console.WriteLine("^^^^^^^^^^^^^^^^^^^^^^^^^"); Console.WriteLine("Block validation failed..."); Console.WriteLine("INFO -> Incorrect block hash..."); return(false); } IDictionary <string, decimal> balances; if (futureBalances != null) { balances = futureBalances; } else { balances = GetBalances(0); } foreach (var transaction in block.Transactions) { if (!ValidateTransaction(transaction, balances)) { return(false); } } return(true); }
private bool ValidateTransaction(Transaction transaction, IDictionary <string, decimal> futureBalances = null) { IDictionary <string, decimal> balances; bool inSimulationMode = false; if (futureBalances != null) { inSimulationMode = true; balances = futureBalances; } else { balances = GetBalances(0); } var bytes = Encoding.UTF8.GetBytes(transaction.TransactionHash); ECPoint senderPublicKey = CryptographyUtilities.DecodeECPointFromHex(transaction.SenderPublicKey); if (!CryptographyUtilities.VerifySigniture(bytes, transaction.SenderSignature, senderPublicKey)) { Console.WriteLine("^^^^^^^^^^^^^^^^^^^^^^^^^"); Console.WriteLine("Transaction validation failed..."); Console.WriteLine("INFO -> incorrect signiture..."); return(false); } if (!balances.ContainsKey(transaction.From) || balances[transaction.From] < transaction.Value) { Console.WriteLine("^^^^^^^^^^^^^^^^^^^^^^^^^"); Console.WriteLine("Transaction validation failed..."); Console.WriteLine("INFO -> not enought money of sender..."); return(false); } if (inSimulationMode) { balances[transaction.From] -= transaction.Value; } var copyOftransaction = new Transaction() { From = transaction.From, To = transaction.To, Value = transaction.Value, SenderPublicKey = transaction.SenderPublicKey }; var transactionJson = JsonConvert.SerializeObject(copyOftransaction); var transactionHash = CryptographyUtilities.BytesToHex(CryptographyUtilities.CalcSHA256(transactionJson)); if (transactionHash != transaction.TransactionHash) { Console.WriteLine("^^^^^^^^^^^^^^^^^^^^^^^^^"); Console.WriteLine("Transaction validation failed..."); Console.WriteLine("INFO -> incorrect transaction hash..."); return(false); } Console.WriteLine("Transaction validation success..."); return(true); }
public void Receive(SocketDataBody data) { Console.WriteLine($"{data.NodesPair.Item1} -> {data.NodesPair.Item2}"); if (data.Type == SocketDataType.Send) { var block = JsonConvert.DeserializeObject <Block>(data.Body); if (block.Index == this.blockchain.LastBlock.Index + 1 && block.PreviousBlockHash == this.blockchain.LastBlock.BlockHash) { string lastBlockHash = this.blockchain.LastBlock.BlockHash; int nonce = block.Nonce; string winnerHash = CryptographyUtilities.BytesToHex(CryptographyUtilities.CalcSHA256($"{lastBlockHash}{nonce}")); if (!winnerHash.ToCharArray().Take(this.blockchain.Difficulty).All(s => s == '0')) { Console.WriteLine("Incorrect hash..."); return; } this.blockchain.AddBlock(block); } else { if (block.Index <= this.blockchain.LastBlock.Index) { Console.WriteLine("Other node is not synced..."); } else { Console.WriteLine("This node is not synced..."); var ip = data.NodesPair.Item1.Split(':')[0]; var port = int.Parse(data.NodesPair.Item1.Split(':')[1]); CommandFabric.RunDynamic($"sync -ip {ip} -p {port}"); } } } else if (data.Type == SocketDataType.Receive) { if (data.Body == "sync") { var ip = data.NodesPair.Item2.Split(':')[0]; var port = int.Parse(data.NodesPair.Item2.Split(':')[1]); CommandFabric.RunDynamic($"sync -ip {ip} -p {port}"); } //if (data.Body != string.Empty) //{ // var newBlocks = JsonConvert.DeserializeObject<Block[]>(data.Body).ToList(); // this.blockchain.RemoveBlockInterval(newBlocks.First().Index, newBlocks.Last().Index); // foreach (var block in newBlocks) // { // this.blockchain.AddBlock(block); // } //} } }
public void MineAsync() { int nonce = 0; string hash = string.Empty; try { string lastBlockPath = Directory.GetFiles($"{Constants.BlocksFilePath}/", "*.json") .OrderBy(n => int.Parse(n.Split('_')[1].Replace(".json", ""))).ToList().Last(); string lastBlockHash = StorageFileProvider <Block> .GetModel(lastBlockPath).BlockHash; int counter = 0; while (true) { counter++; if (StopThread) { break; } if (counter > 100000) { lastBlockPath = Directory.GetFiles($"{Constants.BlocksFilePath}/", "*.json") .OrderBy(n => int.Parse(n.Split('_')[1].Replace(".json", ""))).ToList().Last(); lastBlockHash = StorageFileProvider <Block> .GetModel(lastBlockPath).BlockHash; counter = 0; } hash = CryptographyUtilities.BytesToHex(CryptographyUtilities.CalcSHA256($"{lastBlockHash}{nonce}")); if (hash.ToCharArray().Take(this.blockchain.Difficulty).All(s => s == '0')) { string currentLastBlockPath = Directory.GetFiles($"{Constants.BlocksFilePath}/", "*.json") .OrderBy(n => int.Parse(n.Split('_')[1].Replace(".json", ""))).ToList().Last(); string newLastBlockHash = StorageFileProvider <Block> .GetModel(currentLastBlockPath).BlockHash; counter = 0; if (newLastBlockHash != lastBlockHash) { nonce = 0; continue; } break; } nonce++; } } catch { } if (!StopThread) { NextBlockMined(hash, nonce); Thread thread = new Thread(MineAsync); thread.Start(); var miningThread = CommandFabric.ThreadsInfo.First(t => t.Key == "Mining"); CommandFabric.ThreadsInfo.Remove(miningThread); CommandFabric.ThreadsInfo.Add("Mining", thread.ManagedThreadId); } }