private static void GenerateIdentity(int keySize = 256) { ECKeyPairGenerator gen = new ECKeyPairGenerator(); SecureRandom secureRandom = new SecureRandom(); KeyGenerationParameters keyGenParam = new KeyGenerationParameters(secureRandom, keySize); gen.Init(keyGenParam); var keyPair = gen.GenerateKeyPair(); BigInteger privateKey = ((ECPrivateKeyParameters)keyPair.Private).D; Console.WriteLine("Private key (hex): " + privateKey.ToString(16)); Console.WriteLine("Private key: " + privateKey.ToString(10)); Console.WriteLine("Password for private key encryption:"); var password = Console.ReadLine(); var encryptedPrivateKey = CryptographyUtilities.Encrypt(privateKey.ToByteArray(), password); StorageFileProvider <string> .SetModel(Constants.WalletEncryptedPrivateKeyFilePath, encryptedPrivateKey); ECPoint pubKey = ((ECPublicKeyParameters)keyPair.Public).Q; string pubKeyCompressed = CryptographyUtilities.EncodeECPointHexCompressed(pubKey); Console.WriteLine("Public key (compressed): " + pubKeyCompressed); string addr = CryptographyUtilities.CalcRipeMD160(pubKeyCompressed); Console.WriteLine("Blockchain address: " + addr); }
public static void UnlockWallet() { if (privateKey == null) { var encryptedPrivateKey = StorageFileProvider <string> .GetModel(Constants.WalletEncryptedPrivateKeyFilePath); if (encryptedPrivateKey != null && encryptedPrivateKey != string.Empty) { Console.WriteLine("Type your password:"******"Unlock wallet..."); var bytes = CryptographyUtilities.Decrypt(encryptedPrivateKey, password); if (bytes != null && bytes.Length > 0) { privateKey = new BigInteger(bytes); } break; } catch { Console.WriteLine("Incorrect password..."); Console.WriteLine("Type your password again:"); password = Console.ReadLine(); } } } } }
public static async Task <(string OriginName, string NewPath)> SaveAsync(this IFormFile formFile, string interval = "upload") { await using var stream = new MemoryStream(); await formFile.CopyToAsync(stream); var bytes = stream.ToArray(); var extension = Path.GetExtension(formFile.FileName); var md5 = CryptographyUtilities.ComputeMD5(bytes); var fileName = $"{md5}{extension}"; var date = $"{DateTime.Now:yyyMMdd}"; var path = $"{interval}/{date}"; var directory = Path.Combine(AppContext.BaseDirectory, $"wwwroot/{path}"); if (!Directory.Exists(directory)) { Directory.CreateDirectory(directory); } var filePath = Path.Combine(directory, fileName); if (!File.Exists(filePath)) { await File.WriteAllBytesAsync(filePath, bytes); } return(formFile.FileName, $"{path}/{fileName}"); }
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); }
private void CalculateBalances(int confirmations) { var balances = new Dictionary <string, decimal>(); foreach (var genesisTransactions in blocks[0].Transactions) { balances.Add(genesisTransactions.To, genesisTransactions.Value); } foreach (var block in blocks.Skip(1).Take(blocks.Count - confirmations)) { if (block.Index == 0) { continue; } foreach (var transaction in block.Transactions) { var senderPublicKey = CryptographyUtilities.DecodeECPointFromHex(transaction.SenderPublicKey); var bytes = Encoding.UTF8.GetBytes(transaction.TransactionHash); if (CryptographyUtilities.VerifySigniture(bytes, transaction.SenderSignature, senderPublicKey)) { balances[transaction.From] -= transaction.Value; if (balances.ContainsKey(transaction.To)) { balances[transaction.To] += transaction.Value; } else { balances.Add(transaction.To, transaction.Value); } } else { Console.WriteLine("Found incorrect signiture..."); return; } } } this.balances = balances; }
public static void UnlockWallet() { if (privateKey == null) { var encryptedPrivateKey = StorageFileProvider <string> .GetModel(Constants.WalletEncryptedPrivateKeyFilePath); if (encryptedPrivateKey != null && encryptedPrivateKey != string.Empty) { var password = "******"; var bytes = CryptographyUtilities.Decrypt(encryptedPrivateKey, password); if (bytes != null && bytes.Length > 0) { privateKey = new BigInteger(bytes); } } } }
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 byte[] SignTransaction(byte[] data) { var signiture = CryptographyUtilities.SignData(privateKey, data); return(signiture); }
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); } }