コード例 #1
0
        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);
        }
コード例 #2
0
 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...");
     }
 }
コード例 #3
0
        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);
        }
コード例 #4
0
        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);
        }
コード例 #5
0
        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);
        }
コード例 #6
0
        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);
        }
コード例 #7
0
        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);
        }
コード例 #8
0
        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);
                //    }
                //}
            }
        }
コード例 #9
0
ファイル: Mine.cs プロジェクト: David-Mavrodiev/DBlockchain
        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);
            }
        }