public JsonBasicMiningFactoryConfig(string path)
        {
            JsonSerializer jsonSerializer = new JsonSerializer();

            using (Stream jsonFile = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.None))
                using (StreamReader reader = new StreamReader(jsonFile))
                    using (JsonReader jsonReader = new JsonTextReader(reader))
                        parameters = jsonSerializer.Deserialize <BasicMiningFactoryParameters>(jsonReader);
        }
예제 #2
0
        static void Main(string[] args)
        {
            #region Configs.

            BlockchainStorageManagerParameters managerParameters = new BlockchainStorageManagerParameters()
            {
                BlocksInUnit = 2
            };
            UnitRepositoryParameters repositoryParameters = new UnitRepositoryParameters()
            {
                DirectoryPath = Path.Combine(Directory.GetCurrentDirectory(), "blockchain")
            };
            WalletManagerParameters walletManagerParameters = new WalletManagerParameters()
            {
                WalletDirectoryPath = Path.Combine(Directory.GetCurrentDirectory(), "wallets")
            };

            NetworkParameters networkParametersFirst = new NetworkParameters()
            {
                AddressBookPath = Path.Combine(Directory.GetCurrentDirectory(), AddressBookPath),

                PeerHostName = Dns.GetHostName(),
                PeerPort     = 8910,

                ClientTimeout = new TimeSpan(0, 0, 4),
                ServerTimeout = new TimeSpan(0, 0, 4)
            };

            BasicMiningFactoryParameters parameters = new BasicMiningFactoryParameters()
            {
                HashLeastUpFactor = 1.25,
                HashMostUpFactor  = 1.75,

                HashLeastDownFactor = 0.25,
                HashMostDownFactor  = 0.75,

                DifficultyLeastUpFactor = 1.25,
                DifficultyMostUpFactor  = 1.75,

                DifficultyLeastDownFactor = 0.25,
                DifficultyMostDownFactor  = 0.75,

                MinDifficulty = Difficulty
            };

            JsonSerializer jsonSerializer = new JsonSerializer()
            {
                Formatting = Formatting.Indented
            };

            using (Stream jsonFile = File.Open(MiningConfigPath, FileMode.Create, FileAccess.Write, FileShare.None))
                using (StreamWriter writer = new StreamWriter(jsonFile))
                    using (JsonWriter jsonWriter = new JsonTextWriter(writer))
                        jsonSerializer.Serialize(jsonWriter, parameters);

            using (Stream jsonFile = File.Open(ManagerConfigPath, FileMode.Create, FileAccess.Write, FileShare.None))
                using (StreamWriter writer = new StreamWriter(jsonFile))
                    using (JsonWriter jsonWriter = new JsonTextWriter(writer))
                        jsonSerializer.Serialize(jsonWriter, managerParameters);

            using (Stream jsonFile = File.Open(RepositoryConfigPath, FileMode.Create, FileAccess.Write, FileShare.None))
                using (StreamWriter writer = new StreamWriter(jsonFile))
                    using (JsonWriter jsonWriter = new JsonTextWriter(writer))
                        jsonSerializer.Serialize(jsonWriter, repositoryParameters);

            using (Stream jsonFile = File.Open(WalletManagerConfigPath, FileMode.Create, FileAccess.Write, FileShare.None))
                using (StreamWriter writer = new StreamWriter(jsonFile))
                    using (JsonWriter jsonWriter = new JsonTextWriter(writer))
                        jsonSerializer.Serialize(jsonWriter, walletManagerParameters);

            using (Stream jsonFile = File.Open(NetworkConfigPath, FileMode.Create, FileAccess.Write, FileShare.None))
                using (StreamWriter writer = new StreamWriter(jsonFile))
                    using (JsonWriter jsonWriter = new JsonTextWriter(writer))
                        jsonSerializer.Serialize(jsonWriter, networkParametersFirst);

            JsonBasicMiningFactoryConfig       miningConfig        = new JsonBasicMiningFactoryConfig(MiningConfigPath);
            JsonBlockchainStorageManagerConfig managerConfig       = new JsonBlockchainStorageManagerConfig(ManagerConfigPath);
            JsonUnitRepositoryConfig           repositoryConfig    = new JsonUnitRepositoryConfig(RepositoryConfigPath);
            JsonWalletManagerConfig            walletManagerConfig = new JsonWalletManagerConfig(WalletManagerConfigPath);
            JsonNetworkConfig networkConfig = new JsonNetworkConfig(NetworkConfigPath);

            #endregion

            IMiningFactory    miningFactory          = new BasicMiningFactory(miningConfig);
            IHashFactory      hashFactory            = miningFactory.GetMiningHashFactoryById(3);
            IHashFactory      transactionHashFactory = new TransactionHashFactory();
            ISignatureFactory signatureFactory       = new ECDSAFactory();
            IWalletManager    walletManager          = new WalletManager(walletManagerConfig, signatureFactory, transactionHashFactory);

            Wallet                   wallet         = walletManager.GetWallets().First();
            UnitRepository           repository     = new UnitRepository(repositoryConfig);
            BlockchainStorageManager storageManager = new BlockchainStorageManager(managerConfig, repository);
            Blockchain               blockchain     = new Blockchain(wallet, walletManager, transactionHashFactory, signatureFactory, miningFactory, storageManager);

            wallet.Blockchain = blockchain;

            #region Network.

            AddressBook  addressBook = new AddressBook(AddressBookPath);
            IBroadcaster network     = new Network(blockchain, addressBook, networkConfig, wallet.Signer);

            blockchain.NetworkBroadcaster = network;

            network.Start();

            #endregion

            Console.WriteLine("Second");
            Console.WriteLine("0 - send transaction;\n1 - mine new block;\n2 - validate blockchain;\n3 - count your balance;\n4 - quit\n5 - create new wallet");

            string input;

            do
            {
                input = Console.ReadLine();

                switch (input)
                {
                case "0":
                    wallet.SendTokens(8, addressBook.First().Key.PublicKey);

                    break;

                case "1":
                    blockchain.ProcessPendingTransactions();

                    break;

                case "2":
                    Console.WriteLine(blockchain.IsValid ? "Blockchain is valid" : "Blockchain is invalid");

                    break;

                case "3":
                    Console.WriteLine(blockchain.CountBalanceForWallet(wallet.PublicKey));

                    break;

                case "4":
                    Console.WriteLine("Bye!");

                    break;

                case "5":
                    Wallet newOne = walletManager.AddNewWallet();

                    Console.WriteLine("New wallet created!");
                    Console.WriteLine($"Public key: {hashFactory.GetByteConverter().ConvertToString(newOne.PublicKey)}");

                    break;

                default:
                    Console.WriteLine("Wrong input!");

                    break;
                }
            }while (input != "4");

            network.Stop();
        }
예제 #3
0
        static void Main(string[] args)
        {
            #region Configs.

            BlockchainStorageManagerParameters managerParameters = new BlockchainStorageManagerParameters()
            {
                BlocksInUnit = 2
            };
            UnitRepositoryParameters repositoryParameters = new UnitRepositoryParameters()
            {
                DirectoryPath = Path.Combine(Directory.GetCurrentDirectory(), "blockchain")
            };
            WalletManagerParameters walletManagerParameters = new WalletManagerParameters()
            {
                WalletDirectoryPath = Path.Combine(Directory.GetCurrentDirectory(), "wallets")
            };

            NetworkParameters networkParametersFirst = new NetworkParameters()
            {
                AddressBookPath = Path.Combine(Directory.GetCurrentDirectory(), AddressBookPath),

                PeerHostName = Dns.GetHostName(),
                PeerPort     = 8900,

                ClientTimeout = new TimeSpan(0, 0, 4),
                ServerTimeout = new TimeSpan(0, 0, 4)
            };

            BasicMiningFactoryParameters parameters = new BasicMiningFactoryParameters()
            {
                HashLeastUpFactor = 1.25,
                HashMostUpFactor  = 1.75,

                HashLeastDownFactor = 0.25,
                HashMostDownFactor  = 0.75,

                DifficultyLeastUpFactor = 1.25,
                DifficultyMostUpFactor  = 1.75,

                DifficultyLeastDownFactor = 0.25,
                DifficultyMostDownFactor  = 0.75,

                MinDifficulty = Difficulty
            };

            JsonSerializer jsonSerializer = new JsonSerializer()
            {
                Formatting = Formatting.Indented
            };

            using (Stream jsonFile = File.Open(MiningConfigPath, FileMode.Create, FileAccess.Write, FileShare.None))
                using (StreamWriter writer = new StreamWriter(jsonFile))
                    using (JsonWriter jsonWriter = new JsonTextWriter(writer))
                        jsonSerializer.Serialize(jsonWriter, parameters);

            using (Stream jsonFile = File.Open(ManagerConfigPath, FileMode.Create, FileAccess.Write, FileShare.None))
                using (StreamWriter writer = new StreamWriter(jsonFile))
                    using (JsonWriter jsonWriter = new JsonTextWriter(writer))
                        jsonSerializer.Serialize(jsonWriter, managerParameters);

            using (Stream jsonFile = File.Open(RepositoryConfigPath, FileMode.Create, FileAccess.Write, FileShare.None))
                using (StreamWriter writer = new StreamWriter(jsonFile))
                    using (JsonWriter jsonWriter = new JsonTextWriter(writer))
                        jsonSerializer.Serialize(jsonWriter, repositoryParameters);

            using (Stream jsonFile = File.Open(WalletManagerConfigPath, FileMode.Create, FileAccess.Write, FileShare.None))
                using (StreamWriter writer = new StreamWriter(jsonFile))
                    using (JsonWriter jsonWriter = new JsonTextWriter(writer))
                        jsonSerializer.Serialize(jsonWriter, walletManagerParameters);

            using (Stream jsonFile = File.Open(NetworkConfigPath, FileMode.Create, FileAccess.Write, FileShare.None))
                using (StreamWriter writer = new StreamWriter(jsonFile))
                    using (JsonWriter jsonWriter = new JsonTextWriter(writer))
                        jsonSerializer.Serialize(jsonWriter, networkParametersFirst);

            JsonBasicMiningFactoryConfig       miningConfig        = new JsonBasicMiningFactoryConfig(MiningConfigPath);
            JsonBlockchainStorageManagerConfig managerConfig       = new JsonBlockchainStorageManagerConfig(ManagerConfigPath);
            JsonUnitRepositoryConfig           repositoryConfig    = new JsonUnitRepositoryConfig(RepositoryConfigPath);
            JsonWalletManagerConfig            walletManagerConfig = new JsonWalletManagerConfig(WalletManagerConfigPath);
            JsonNetworkConfig networkConfig = new JsonNetworkConfig(NetworkConfigPath);

            #endregion

            #region Directory remove.

            removeDirectory(repositoryConfig.DirectoryPath);
            removeDirectory(SecondPeerRepositoryPath);
            //removeDirectory(walletManagerConfig.WalletDirectoryPath);

            #endregion

            #region Directory creation.

            Directory.CreateDirectory(repositoryParameters.DirectoryPath);
            Directory.CreateDirectory(Path.Combine(repositoryConfig.DirectoryPath, "addressers"));
            Directory.CreateDirectory(Path.Combine(repositoryConfig.DirectoryPath, "units"));
            //Directory.CreateDirectory(walletManagerConfig.WalletDirectoryPath);

            #endregion

            #region Initial units.

            // Addressers.
            string addresser0Path = Path.Combine(repositoryParameters.DirectoryPath, "addressers", "addresser0.addr");

            File.Create(addresser0Path).Close();

            // Units.
            string unit0Path = Path.Combine(repositoryParameters.DirectoryPath, "units", "unit0.unit");

            File.Create(unit0Path).Close();

            BlockchainUnit unit0 = new BlockchainUnit(unit0Path, new AddressStorage(addresser0Path));

            #endregion

            IMiningFactory    miningFactory          = new BasicMiningFactory(miningConfig);
            IHashFactory      hashFactory            = miningFactory.GetMiningHashFactoryById(3);
            IHashFactory      transactionHashFactory = new TransactionHashFactory();
            ISignatureFactory signatureFactory       = new ECDSAFactory();
            IWalletManager    walletManager          = new WalletManager(walletManagerConfig, signatureFactory, transactionHashFactory);

            Wallet wallet = walletManager.GetWallets().First();

            #region Initial transactions.

            LinkedList <Transaction> firstInitialList  = new LinkedList <Transaction>();
            LinkedList <Transaction> secondInitialList = new LinkedList <Transaction>();

            Transaction firstInitialTransaction  = new Transaction(wallet.PublicKey, wallet.PublicKey, 32, transactionHashFactory);
            Transaction secondInitialTransaction = new Transaction(wallet.PublicKey, wallet.PublicKey, 19, transactionHashFactory);
            Transaction thirdInitialTransaction  = new Transaction(wallet.PublicKey, wallet.PublicKey, 32, transactionHashFactory);
            Transaction fourthInitialTransaction = new Transaction(wallet.PublicKey, wallet.PublicKey, 19, transactionHashFactory);

            firstInitialTransaction.SignTransaction(wallet.Signer);
            secondInitialTransaction.SignTransaction(wallet.Signer);
            thirdInitialTransaction.SignTransaction(wallet.Signer);
            fourthInitialTransaction.SignTransaction(wallet.Signer);

            firstInitialList.AddLast(firstInitialTransaction);
            firstInitialList.AddLast(secondInitialTransaction);
            secondInitialList.AddLast(thirdInitialTransaction);
            secondInitialList.AddLast(fourthInitialTransaction);

            #endregion

            #region Initial blocks.

            IHashFactory miningHashFactory = miningFactory.GetMiningHashFactoryById(3);
            IMiner       miner             = new BasicMiner(3, Difficulty, miningHashFactory);

            Block firstInitialBlock = new Block(wallet.PublicKey, new byte[hashFactory.GetDigest().HashLength], firstInitialList, hashFactory);

            miner.MineBlock(firstInitialBlock);
            firstInitialBlock.SignBlock(wallet.Signer);

            Block secondInitialBlock = new Block(wallet.PublicKey, firstInitialBlock.Hash, secondInitialList, hashFactory);

            miner.MineBlock(secondInitialBlock);
            secondInitialBlock.SignBlock(wallet.Signer);

            unit0.AddBlock(firstInitialBlock);
            unit0.AddBlock(secondInitialBlock);

            unit0.Dispose();

            #endregion

            Copy(repositoryConfig.DirectoryPath, SecondPeerRepositoryPath);

            UnitRepository           repository     = new UnitRepository(repositoryConfig);
            BlockchainStorageManager storageManager = new BlockchainStorageManager(managerConfig, repository);
            Blockchain blockchain = new Blockchain(wallet, walletManager, transactionHashFactory, signatureFactory, miningFactory, storageManager);

            wallet.Blockchain = blockchain;

            #region Network.

            AddressBook  addressBook = new AddressBook(AddressBookPath);
            IBroadcaster network     = new Network(blockchain, addressBook, networkConfig, wallet.Signer);

            blockchain.NetworkBroadcaster = network;

            network.Start();

            #endregion

            Console.WriteLine("First");
            Console.WriteLine("0 - send transaction;\n1 - mine new block;\n2 - validate blockchain;\n3 - count your balance;\n4 - quit");

            string input;

            do
            {
                input = Console.ReadLine();

                switch (input)
                {
                case "0":
                    wallet.SendTokens(8, addressBook.First().Key.PublicKey);

                    break;

                case "1":
                    blockchain.ProcessPendingTransactions();

                    break;

                case "2":
                    Console.WriteLine(blockchain.IsValid ? "Blockchain is valid" : "Blockchain is invalid");

                    break;

                case "3":
                    Console.WriteLine($"Current balance for testing wallet: " + blockchain.CountBalanceForWallet(wallet.PublicKey));

                    break;

                case "4":
                    Console.WriteLine("Bye!");

                    break;

                default:
                    Console.WriteLine("Wrong input!");

                    break;
                }
            }while (input != "4");

            network.Stop();
        }
예제 #4
0
        static void Main(string[] args)
        {
            #region Configs creation.

            BlockchainStorageManagerParameters managerParameters = new BlockchainStorageManagerParameters()
            {
                BlocksInUnit = 2
            };
            UnitRepositoryParameters firstRepositoryParameters = new UnitRepositoryParameters()
            {
                DirectoryPath = Path.Combine(Directory.GetCurrentDirectory(), "blockchain0")
            };
            UnitRepositoryParameters secondRepositoryParameters = new UnitRepositoryParameters()
            {
                DirectoryPath = Path.Combine(Directory.GetCurrentDirectory(), "blockchain1")
            };
            WalletManagerParameters walletManagerParameters = new WalletManagerParameters()
            {
                WalletDirectoryPath = Path.Combine(Directory.GetCurrentDirectory(), "wallets")
            };

            NetworkParameters networkParametersFirst = new NetworkParameters()
            {
                AddressBookPath = Path.Combine(Directory.GetCurrentDirectory(), FirstBookPath),

                PeerHostName = Dns.GetHostName(),
                PeerPort     = 8900,

                ClientTimeout = new TimeSpan(0, 0, 4),
                ServerTimeout = new TimeSpan(0, 0, 4)
            };

            NetworkParameters networkParametersSecond = new NetworkParameters()
            {
                AddressBookPath = Path.Combine(Directory.GetCurrentDirectory(), SecondBookPath),

                PeerHostName = Dns.GetHostName(),
                PeerPort     = 8910,

                ClientTimeout = new TimeSpan(0, 0, 4),
                ServerTimeout = new TimeSpan(0, 0, 4)
            };

            BasicMiningFactoryParameters parameters = new BasicMiningFactoryParameters()
            {
                HashLeastUpFactor = 1.25,
                HashMostUpFactor  = 1.75,

                HashLeastDownFactor = 0.25,
                HashMostDownFactor  = 0.75,

                DifficultyLeastUpFactor = 1.25,
                DifficultyMostUpFactor  = 1.75,

                DifficultyLeastDownFactor = 0.25,
                DifficultyMostDownFactor  = 0.75,

                MinDifficulty = Difficulty
            };

            JsonSerializer jsonSerializer = new JsonSerializer()
            {
                Formatting = Formatting.Indented
            };

            using (Stream jsonFile = File.Open(MiningConfigPath, FileMode.Create, FileAccess.Write, FileShare.None))
                using (StreamWriter writer = new StreamWriter(jsonFile))
                    using (JsonWriter jsonWriter = new JsonTextWriter(writer))
                        jsonSerializer.Serialize(jsonWriter, parameters);

            using (Stream jsonFile = File.Open(ManagerConfigPath, FileMode.Create, FileAccess.Write, FileShare.None))
                using (StreamWriter writer = new StreamWriter(jsonFile))
                    using (JsonWriter jsonWriter = new JsonTextWriter(writer))
                        jsonSerializer.Serialize(jsonWriter, managerParameters);

            using (Stream jsonFile = File.Open(FirstRepositoryConfigPath, FileMode.Create, FileAccess.Write, FileShare.None))
                using (StreamWriter writer = new StreamWriter(jsonFile))
                    using (JsonWriter jsonWriter = new JsonTextWriter(writer))
                        jsonSerializer.Serialize(jsonWriter, firstRepositoryParameters);

            using (Stream jsonFile = File.Open(SecondRepositoryConfigPath, FileMode.Create, FileAccess.Write, FileShare.None))
                using (StreamWriter writer = new StreamWriter(jsonFile))
                    using (JsonWriter jsonWriter = new JsonTextWriter(writer))
                        jsonSerializer.Serialize(jsonWriter, secondRepositoryParameters);

            using (Stream jsonFile = File.Open(WalletManagerConfigPath, FileMode.Create, FileAccess.Write, FileShare.None))
                using (StreamWriter writer = new StreamWriter(jsonFile))
                    using (JsonWriter jsonWriter = new JsonTextWriter(writer))
                        jsonSerializer.Serialize(jsonWriter, walletManagerParameters);

            using (Stream jsonFile = File.Open(FirstNetworkConfigPath, FileMode.Create, FileAccess.Write, FileShare.None))
                using (StreamWriter writer = new StreamWriter(jsonFile))
                    using (JsonWriter jsonWriter = new JsonTextWriter(writer))
                        jsonSerializer.Serialize(jsonWriter, networkParametersFirst);

            using (Stream jsonFile = File.Open(SecondNetworkConfigPath, FileMode.Create, FileAccess.Write, FileShare.None))
                using (StreamWriter writer = new StreamWriter(jsonFile))
                    using (JsonWriter jsonWriter = new JsonTextWriter(writer))
                        jsonSerializer.Serialize(jsonWriter, networkParametersSecond);

            JsonBasicMiningFactoryConfig       miningConfig           = new JsonBasicMiningFactoryConfig(MiningConfigPath);
            JsonBlockchainStorageManagerConfig managerConfig          = new JsonBlockchainStorageManagerConfig(ManagerConfigPath);
            JsonUnitRepositoryConfig           firstRepositoryConfig  = new JsonUnitRepositoryConfig(FirstRepositoryConfigPath);
            JsonUnitRepositoryConfig           secondRepositoryConfig = new JsonUnitRepositoryConfig(SecondRepositoryConfigPath);
            JsonWalletManagerConfig            walletManagerConfig    = new JsonWalletManagerConfig(WalletManagerConfigPath);
            JsonNetworkConfig firstNetworkConfig  = new JsonNetworkConfig(FirstNetworkConfigPath);
            JsonNetworkConfig secondNetworkConfig = new JsonNetworkConfig(SecondNetworkConfigPath);

            #endregion

            #region Directory remove.

            removeDirectory(firstRepositoryConfig.DirectoryPath);
            removeDirectory(secondRepositoryConfig.DirectoryPath);
            removeDirectory(walletManagerConfig.WalletDirectoryPath);

            #endregion

            #region Directory creation.

            Directory.CreateDirectory(firstRepositoryParameters.DirectoryPath);
            Directory.CreateDirectory(secondRepositoryParameters.DirectoryPath);
            Directory.CreateDirectory(Path.Combine(firstRepositoryConfig.DirectoryPath, "addressers"));
            Directory.CreateDirectory(Path.Combine(firstRepositoryConfig.DirectoryPath, "units"));
            Directory.CreateDirectory(Path.Combine(secondRepositoryConfig.DirectoryPath, "addressers"));
            Directory.CreateDirectory(Path.Combine(secondRepositoryConfig.DirectoryPath, "units"));
            Directory.CreateDirectory(walletManagerConfig.WalletDirectoryPath);

            #endregion

            #region Initial units.

            // Addressers.
            string firstAddresser0Path  = Path.Combine(firstRepositoryParameters.DirectoryPath, "addressers", "addresser0.addr");
            string secondAddresser0Path = Path.Combine(secondRepositoryParameters.DirectoryPath, "addressers", "addresser0.addr");

#if (CREATE_EXTRA_FILE)
            string firstAddresser1Path  = Path.Combine(firstRepositoryParameters.DirectoryPath, "addressers", "addresser1.addr");
            string secondAddresser1Path = Path.Combine(secondRepositoryParameters.DirectoryPath, "addressers", "addresser1.addr");
#endif

            File.Create(firstAddresser0Path).Close();
            File.Create(secondAddresser0Path).Close();

#if (CREATE_EXTRA_FILE)
            File.Create(firstAddresser1Path).Close();
            File.Create(secondAddresser1Path).Close();
#endif

            // Units.
            string firstUnit0Path  = Path.Combine(firstRepositoryParameters.DirectoryPath, "units", "unit0.unit");
            string secondUnit0Path = Path.Combine(secondRepositoryParameters.DirectoryPath, "units", "unit0.unit");

#if (CREATE_EXTRA_FILE)
            string firstUnit1Path  = Path.Combine(firstRepositoryParameters.DirectoryPath, "units", "unit1.unit");
            string secondUnit1Path = Path.Combine(secondRepositoryParameters.DirectoryPath, "units", "unit1.unit");
#endif

            File.Create(firstUnit0Path).Close();
            File.Create(secondUnit0Path).Close();

#if (CREATE_EXTRA_FILE)
            File.Create(firstUnit1Path).Close();
            File.Create(secondUnit1Path).Close();
#endif

            BlockchainUnit firstUnit0  = new BlockchainUnit(firstUnit0Path, new AddressStorage(firstAddresser0Path));
            BlockchainUnit secondUnit0 = new BlockchainUnit(secondUnit0Path, new AddressStorage(secondAddresser0Path));

            #endregion

            IMiningFactory    miningFactory          = new BasicMiningFactory(miningConfig);
            IHashFactory      hashFactory            = miningFactory.GetMiningHashFactoryById(3);
            IHashFactory      transactionHashFactory = new TransactionHashFactory();
            ISignatureFactory signatureFactory       = new ECDSAFactory();
            IWalletManager    walletManager          = new WalletManager(walletManagerConfig, signatureFactory, transactionHashFactory);

            Wallet firstWallet = walletManager.AddNewWallet();

            #region Initial transactions.

            LinkedList <Transaction> firstInitialList  = new LinkedList <Transaction>();
            LinkedList <Transaction> secondInitialList = new LinkedList <Transaction>();

            Transaction firstInitialTransaction  = new Transaction(firstWallet.PublicKey, firstWallet.PublicKey, 32, transactionHashFactory);
            Transaction secondInitialTransaction = new Transaction(firstWallet.PublicKey, firstWallet.PublicKey, 19, transactionHashFactory);
            Transaction thirdInitialTransaction  = new Transaction(firstWallet.PublicKey, firstWallet.PublicKey, 32, transactionHashFactory);
            Transaction fourthInitialTransaction = new Transaction(firstWallet.PublicKey, firstWallet.PublicKey, 19, transactionHashFactory);

            firstInitialTransaction.SignTransaction(firstWallet.Signer);
            secondInitialTransaction.SignTransaction(firstWallet.Signer);
            thirdInitialTransaction.SignTransaction(firstWallet.Signer);
            fourthInitialTransaction.SignTransaction(firstWallet.Signer);

            firstInitialList.AddLast(firstInitialTransaction);
            firstInitialList.AddLast(secondInitialTransaction);
            secondInitialList.AddLast(thirdInitialTransaction);
            secondInitialList.AddLast(fourthInitialTransaction);

            #endregion

            #region Initial blocks.

            IHashFactory miningHashFactory = miningFactory.GetMiningHashFactoryById(3);
            IMiner       miner             = new BasicMiner(3, Difficulty, miningHashFactory);

            Block firstInitialBlock = new Block(firstWallet.PublicKey, new byte[hashFactory.GetDigest().HashLength], firstInitialList, hashFactory);

            miner.MineBlock(firstInitialBlock);
            firstInitialBlock.SignBlock(firstWallet.Signer);

            Block secondInitialBlock = new Block(firstWallet.PublicKey, firstInitialBlock.Hash, secondInitialList, hashFactory);

            miner.MineBlock(secondInitialBlock);
            secondInitialBlock.SignBlock(firstWallet.Signer);

            firstUnit0.AddBlock(firstInitialBlock);
            firstUnit0.AddBlock(secondInitialBlock);
            secondUnit0.AddBlock(firstInitialBlock);
            secondUnit0.AddBlock(secondInitialBlock);

            firstUnit0.Dispose();
            secondUnit0.Dispose();

            #endregion

            UnitRepository firstRepository  = new UnitRepository(firstRepositoryConfig);
            UnitRepository secondRepository = new UnitRepository(secondRepositoryConfig);

            BlockchainStorageManager firstManager  = new BlockchainStorageManager(managerConfig, firstRepository);
            BlockchainStorageManager secondManager = new BlockchainStorageManager(managerConfig, secondRepository);

            Blockchain firstBlockchain  = new Blockchain(firstWallet, walletManager, transactionHashFactory, signatureFactory, miningFactory, firstManager);
            Wallet     secondWallet     = walletManager.AddNewWallet();
            Blockchain secondBlockchain = new Blockchain(secondWallet, walletManager, transactionHashFactory, signatureFactory, miningFactory, secondManager);

            #region Address books creation.

            File.Create(FirstBookPath).Close();
            File.Create(SecondBookPath).Close();

            PeerAddress firstPeer  = new PeerAddress(firstWallet.PublicKey);
            PeerAddress secondPeer = new PeerAddress(secondWallet.PublicKey);

            AddressBook firstPeerAddressBook  = new AddressBook(FirstBookPath);
            AddressBook secondPeerAddressBook = new AddressBook(SecondBookPath);

            firstPeerAddressBook.Add(secondPeer, "ws://" + secondNetworkConfig.PeerHostName + $":{secondNetworkConfig.PeerPort}/simplecoin");
            secondPeerAddressBook.Add(firstPeer, "ws://" + firstNetworkConfig.PeerHostName + $":{firstNetworkConfig.PeerPort}/simplecoin");

            firstPeerAddressBook.SaveOnDrive();
            secondPeerAddressBook.SaveOnDrive();

            #endregion

            #region Network.

            IBroadcaster firstNetwork = new Network(firstBlockchain, firstPeerAddressBook, firstNetworkConfig, firstWallet.Signer);

            IBroadcaster secondNetwork = new Network(secondBlockchain, secondPeerAddressBook, secondNetworkConfig, secondWallet.Signer);

            firstBlockchain.NetworkBroadcaster  = firstNetwork;
            secondBlockchain.NetworkBroadcaster = secondNetwork;

            firstNetwork.Start();
            secondNetwork.Start();

            #endregion

            firstWallet.Blockchain  = firstBlockchain;
            secondWallet.Blockchain = secondBlockchain;

            firstWallet.SendTokens(16, secondWallet.PublicKey);
            firstWallet.SendTokens(8, secondWallet.PublicKey);

            secondBlockchain.ProcessPendingTransactions();

            secondWallet.SendTokens(8, firstWallet.PublicKey);
            firstBlockchain.ProcessPendingTransactions();

            Console.WriteLine("First blockchain:\n");

            foreach (Block block in firstBlockchain)
            {
                Console.WriteLine(JsonConvert.SerializeObject(block, Formatting.Indented));
                Console.WriteLine();
            }

            Console.WriteLine("--------------------------------------------------------------------------------------");

            Console.WriteLine("Second blockchain:\n");

            foreach (Block block in secondBlockchain)
            {
                Console.WriteLine(JsonConvert.SerializeObject(block, Formatting.Indented));
                Console.WriteLine();
            }

            Console.WriteLine("}\n");

            Console.WriteLine(firstBlockchain.IsValid ? "First blockchain is valid" : "First blockchain is invalid");
            Console.WriteLine(firstBlockchain.IsValid ? "Second blockchain is valid" : "Second blockchain is invalid");

            Console.WriteLine($"Cryptocurrency ownership for first wallet: {firstBlockchain.CountBalanceForWallet(firstWallet.PublicKey)}");
            Console.WriteLine($"Cryptocurrency ownership for second wallet: {firstBlockchain.CountBalanceForWallet(secondWallet.PublicKey)}");
        }