区块链的入门与应用(1)

区块链:

区块链是一个 信息技术领域的术语。从本质上讲,它是一个共享 数据库,存储于其中的数据或信息,具有“不可伪造”“全程留痕”“可以追溯”“公开透明”“集体维护”等特征。基于这些特征, 区块链技术奠定了坚实的“信任“基础,创造了可靠的“合作”机制,具有广阔的运用前景。
2019年1月10日,国家互联网信息办公室发布《 区块链信息服务管理规定 [1]  。2019年10月24日,在中央政治局第十八次集体学习时,总书记强调,“把区块链作为核心技术自主创新的重要突破口”“加快推动区块链技术和产业创新发展”。“区块链”已走进大众视野,成为社会的关注焦点。  (百度百科)
 
关键字:  共享数据库、术语
特征:“不可伪造”“全程留痕”“可以追溯”“公开透明”“集体维护”
奠定:“信任“、 创造 “合作”
 
现在主要应用到:  产品溯源、信用合约、“比特币”发币;

c# 开发一个简单的区块链demo

1、定义结构:

 public struct Block
    {
        /// <summary>
        /// 区块位置
        /// </summary>
        public int Index { get; set; }
        /// <summary>
        /// 区块生成时间戳
        /// </summary>
        public string TimeStamp { get; set; }
        /// <summary>
        /// 心率数值
        /// </summary>
        public int BPM { get; set; }
        /// <summary>
        /// 区块 SHA-256 散列值
        /// </summary>
        public string Hash { get; set; }
        /// <summary>
        /// 前一个区块 SHA-256 散列值
        /// </summary>
        public string PrevHash { get; set; }
        /// <summary>
        /// 下一个区块生成难度
        /// </summary>
        public int Difficulty { get; set; }
        /// <summary>
        /// 随机值
        /// </summary>
        public string Nonce { get; set; }
    }
View Code

2、定义操作类 :生成 校验都在这边

 public static class BlockGenerator
    {
        public static List<Block> _blockChain = new List<Block>();
        public static int _difficulty;
        /// <summary>
        /// 计算区块 HASH 值  比特币是采用double 的sha256. 我们这边采用以单层
        /// </summary>
        /// <param name="block">区块实例</param>
        /// <returns>计算完成的区块散列值</returns>
        public static string CalculateHash(Block block)
        {
            //明文
            string calculationStr = $"{block.Index}{block.TimeStamp}{block.BPM}{block.PrevHash}{block.Nonce}";
            //$"{block.Index}{block.TimeStamp}{block.BPM}{block.PrevHash}";
            SHA256 sha256Generator = SHA256.Create();
            byte[] sha256HashBytes = sha256Generator.ComputeHash(Encoding.UTF8.GetBytes(calculationStr));
            StringBuilder sha256StrBuilder = new StringBuilder();
            foreach (byte @byte in sha256HashBytes)
            {
                sha256StrBuilder.Append(@byte.ToString("x2"));
            }
            return sha256StrBuilder.ToString();
        }
        /// <summary>
        /// 生成新的区块
        /// </summary>
        /// <param name="oldBlock">旧的区块数据</param>
        /// <param name="BPM">心率</param>
        /// <returns>新的区块</returns>
        public static Block GenerateBlock(Block oldBlock, int BPM)
        {
            Block newBlock = new Block()
            {
                Index = oldBlock.Index + 1,
                TimeStamp = CalculateCurrentTimeUTC(),
                BPM = BPM,
                PrevHash = oldBlock.Hash,
                Difficulty = oldBlock.Difficulty
            };
            _difficulty = oldBlock.Difficulty;//
            // 挖矿 ing...
            for (int i = 0; ; i++)
            {
                newBlock.Nonce = i.ToString("x2");
                if (!IsHashValid(CalculateHash(newBlock), oldBlock.Difficulty))
                {
                    Console.WriteLine($"目前结果:{CalculateHash(newBlock)} ,正在计算中...");
                    Task.Delay(1);
                    continue;
                }
                else
                {
                    Console.WriteLine($"目前结果:{CalculateHash(newBlock)} ,计算完毕...");
                    newBlock.Hash = CalculateHash(newBlock);
                    break;
                }
            }

            // 原有代码
            // newBlock.Hash = CalculateHash(newBlock);
            return newBlock;
        }
        /// <summary>
        /// 计算当前时间的 UTC 表示格式
        /// </summary>
        /// <returns>UTC 时间字符串</returns>
        public static string CalculateCurrentTimeUTC()
        {
            DateTime startTime = new DateTime(1970, 1, 1, 0, 0, 0, 0);
            DateTime nowTime = DateTime.Now;
            long unixTime = (long)Math.Round((nowTime - startTime).TotalMilliseconds, MidpointRounding.AwayFromZero);
            return unixTime.ToString();
        }
        /// <summary>
        /// 检验区块是否有效
        /// </summary>
        /// <param name="newBlock">新生成的区块数据</param>
        /// <param name="oldBlock">旧的区块数据</param>
        /// <returns>有效返回 TRUE,无效返回 FALSE</returns>
        public static bool IsBlockValid(Block newBlock, Block oldBlock)
        {
            if (oldBlock.Index + 1 != newBlock.Index) return false;
            if (oldBlock.Hash != newBlock.PrevHash) return false;
            if (CalculateHash(newBlock) != newBlock.Hash) return false;
            return true;
        }
        /// <summary>
        /// 如果新的区块链比当前区块链更新,则切换当前区块链为最新区块链
        /// </summary>
        /// <param name="newBlockChain">新的区块链</param>
        public static void SwitchChain(List<Block> newBlockChain)
        {
            if (newBlockChain.Count > _blockChain.Count)
            {
                _blockChain = newBlockChain;
               
            }
        }
       
        /// <summary>
        /// 校验 Hash 是否有效
        /// </summary>
        /// <param name="hashStr">Hash 值</param>
        /// <param name="difficulty">难度</param>
        /// <returns></returns>
        public static bool IsHashValid(string hashStr, int difficulty)
        {
             
            var bytes = Enumerable.Range(0, hashStr.Length)
                .Where(n => n % 2 == 0)
                .Select(n => Convert.ToByte(hashStr.Substring(n, 2), 16))
                .ToArray();

            var bits = new BitArray(bytes);

            for (var i = 0; i < difficulty; i++)
            {
                if (bits[i]) return false;
            }

            return true;
        }
       
    }

3、应用: staup.cs 里面添加路由

  app.Map("/BlockChain", _ =>
            {
                _.Run(async context =>
                {
                    if (context.Request.Method == "POST")
                    {
                        // 增加区块链
                        if (BlockGenerator._blockChain.Count == 0)
                        {
                            Block firstBlock = new Block()
                            {
                                Index = 0,
                                TimeStamp = BlockGenerator.CalculateCurrentTimeUTC(),
                                BPM = 0,
                                Hash = string.Empty,
                                PrevHash = string.Empty,
                                Difficulty=1
                            };
                            BlockGenerator._blockChain.Add(firstBlock);
                            await context.Response.WriteAsync(JsonConvert.SerializeObject(firstBlock));
                        }
                        else
                        {
                            
                            // int.TryParse(context.Request.Form["BPM"][0], out int bpm);
                            var form = await context.Request.ReadFormAsync();
                            int.TryParse(form["BPM"][0], out int bpm);
                            Block oldBlock = BlockGenerator._blockChain.Last();
                            Block newBlock = BlockGenerator.GenerateBlock(oldBlock, bpm);
                            if (BlockGenerator.IsBlockValid(newBlock, oldBlock))
                            {
                                List<Block> newBlockChain = new List<Block>();
                                foreach (var block in BlockGenerator._blockChain)
                                {
                                    newBlockChain.Add(block);
                                }
                                newBlockChain.Add(newBlock);
                                BlockGenerator.SwitchChain(newBlockChain);
                                await context.Response.WriteAsync(JsonConvert.SerializeObject(newBlock));
                            }
                            else
                            {
                                await context.Response.WriteAsync(JsonConvert.SerializeObject(new { msg="无效的区块链"}));
                            }
                            
                        }
                    }
                });
            });
            app.Map("/BlockChains", _ =>
            {
                _.Run(async context =>
                {
                    await context.Response.WriteAsync(JsonConvert.SerializeObject(BlockGenerator._blockChain));
                });
            });

4、验证 测试 使用postman ,记得第二次请求一定要提交一个BPM 的参数 也可以自己修改程序 自动生成

 

5、大家有疑问可以相互讨论下;

看图: 有些难度小的一下子就计算出来,如果难度大的就要继续计算;

猜你喜欢

转载自www.cnblogs.com/zxs-onestar/p/12218137.html
今日推荐