Example #1
0
        // Composition Root - 组合根:
        // 设计模式。在程序的入口处进行抽象-具体的依赖关系配置。
        // Pure DI
        public static void Main()
        {
            // 出创世区块:通过执行一批交易来初始化整条链,一般包括部署系统合约,如共识合约,多资产合约等,并对系统合约做初步配置
            //   准备交易
            var transactionPool = new TransactionPool
            {
                Logger = new ConsoleLogger()
            };

            foreach (var genesisTransaction in TransactionGenerationHelper.GetGenesisTransactions())
            {
                transactionPool.AddTransaction(genesisTransaction);
            }

            //   打包创世区块
            //     准备MineService
            var blockValidationService = new BlockValidationService(new List <IBlockValidationProvider>
            {
                new BlockTransactionValidationProvider
                {
                    Logger = new ConsoleLogger()
                },
                new BlockBasicInformationValidationProvider
                {
                    Logger = new ConsoleLogger()
                }
            })
            {
                Logger = new ConsoleLogger()
            };
            var blockChainService = new BlockChainService(new PureDIChainIdProvider(), blockValidationService)
            {
                Logger = new ConsoleLogger()
            };
            var transactionExecutingService = new TransactionExecutingService
            {
                Logger = new ConsoleLogger()
            };

            var mineService = new MineService(transactionPool, blockChainService, transactionExecutingService);

            //     生产创世区块
            var genesisBlock = mineService.Mine();

            //     把创世区块添加到链上
            blockChainService.AppendBlock(genesisBlock);
            //   创世区块不广播,每一个节点都独立生成创世区块

            // 所以NetworkService实例较晚才出现
            var networkService = new NetworkService
            {
                Logger = new ConsoleLogger()
            };

            // 开始产生其他区块 - 挖矿
            // Demo: 出2个块
            var count = 2;

            while (count > 0)
            {
                // 交易应该是从网络收取的,这里随机生成一些
                var txs = TransactionGenerationHelper.GetSomeRandomTransactions();
                // 正常流程:从网络中收到交易,验证交易,然后丢进交易池
                foreach (var tx in txs)
                {
                    transactionPool.AddTransaction(tx);
                }
                // 交易池里已经有交易了,然后开始出块
                var block = mineService.Mine();
                // 拿到区块以后,自己做一些列验证,没问题的话就广播,并添加到本地的链上
                networkService.BroadcastBlock(block);
                blockChainService.AppendBlock(block);
                count--;
            }
            // 实际上,共识决定了谁应该在什么时候出块,以及收到一个区块以后该怎么验证这个区块的合法性
        }
Example #2
0
        public static void Main()
        {
            // MS.DI中,DI容器的生成分为两步:
            // 先初始化ServiceCollection,进行一系列注册
            // 再通过ServiceCollection生成
            var serviceCollection = new ServiceCollection();

            // 配置依赖关系
            serviceCollection.AddSingleton <IBlockChainService, BlockChainService>();
            serviceCollection.AddSingleton <ITransactionPool, TransactionPool>();

            serviceCollection.AddTransient <IMineService, MineService>();
            serviceCollection.AddTransient <ITransactionExecutingService, TransactionExecutingService>();
            serviceCollection.AddTransient <INetworkService, NetworkService>();

            serviceCollection.AddTransient <ConsoleLoggerWithTimestamp>();
            serviceCollection.AddTransient <ILogger, ConsoleLoggerWithTimestampDecorator>();
            serviceCollection.AddTransient <IChainIdProvider, MSDIChainIdProvider>();
            serviceCollection.AddTransient <IBlockValidationService, BlockValidationService>();

            // 有新的验证逻辑的时候,添加一个IBlockValidationProvider的实现,在这里添加依赖关系就行了
            serviceCollection.AddSingleton <IBlockValidationProvider, BlockTransactionValidationProvider>();
            serviceCollection.AddSingleton <IBlockValidationProvider, BlockBasicInformationValidationProvider>();

            var container = serviceCollection.BuildServiceProvider();

            // 组合根结束

            // 配置Logger
            var loggingTypes = from type in typeof(IBlockChainService).Assembly.GetTypes()
                               where !type.IsInterface
                               where type.GetProperties().Any(p => p.PropertyType == typeof(ILogger))
                               select type;
            var logger = container.GetRequiredService <ILogger>();

            foreach (var loggingType in loggingTypes.ToList())
            {
                // 看起来"Logger"像是hard code过来的,但是也可以给这种方式起一个好听一点的名字:
                // Convention over configuration,惯例优先原则。
                var loggerProperty = loggingType.GetProperty("Logger");
                var targetInstance = container.GetServices(loggingType.GetInterfaces().First())
                                     .First(i => i.GetType() == loggingType);
                loggerProperty?.SetValue(targetInstance, logger);
            }

            using (var scope = container.CreateScope())
            {
                // 从scope中根据依赖获取实例
                var serviceProvider             = scope.ServiceProvider;
                var transactionPool             = serviceProvider.GetRequiredService <ITransactionPool>();
                var blockChainService           = serviceProvider.GetRequiredService <IBlockChainService>();
                var mineService                 = serviceProvider.GetRequiredService <IMineService>();
                var transactionExecutingService =
                    serviceProvider.GetRequiredService <ITransactionExecutingService>(); // 这里没有用
                var networkService = serviceProvider.GetRequiredService <INetworkService>();

                // 开始了

                // 准备创世交易
                foreach (var genesisTx in TransactionGenerationHelper.GetGenesisTransactions())
                {
                    transactionPool.AddTransaction(genesisTx);
                }

                // 打包添加创世区块
                var genesisBlock = mineService.Mine();
                blockChainService.AppendBlock(genesisBlock);
                // 打包其他区块
                var count = 10;
                while (count > 0)
                {
                    var txs = TransactionGenerationHelper.GetSomeRandomTransactions();
                    foreach (var tx in txs)
                    {
                        transactionPool.AddTransaction(tx);
                    }

                    var block = mineService.Mine();
                    blockChainService.AppendBlock(block);
                    networkService.BroadcastBlock(block);
                    count--;
                }
            }
        }