最近抽空学习一下区块链的设计原理,正在搭建一个非常简易的模型,上生产的模型肯定复杂的多,不过学习还是由简入难,逐步深入才行,一口吃不成胖子。
我使用的是C#编写的。
区块链的特点:
1.分布式记账,去中心化。
2.挖矿是按照平台规则通过大量计算对于平台算式反向求解的过程。
当前,个人对于区块链的认识:区块链是一条链Chain,这条脸上有若干个数据块Block,每个Block里面都封装了三个部分:上一个块的哈希值PreHash、数据Data、当前块的哈希值ThisHash。
计算哈希值使用Hash256计算,其特点:
1.不同长度的数据经过计算可得定长的字符串。
2.相同数据可以获得相同的Hash值,修改一个一个字符,Hash将大不相同,毫无规律可言,保证暂时的安全性(严谨地说)
测试代码:
1 using System; 2 using System.Collections.Generic; 3 using System.Security.Cryptography; 4 using System.Text; 5 6 namespace TestPrj 7 { 8 class Program 9 { 10 static void Main(string[] args) 11 { 12 Chain chain = new Chain(); 13 14 Block block1 = new Block("转账10元"); 15 chain.AddNewBlock(block1); 16 Block block2 = new Block("转账30元"); 17 chain.AddNewBlock(block2); 18 19 20 //查看当前数据链总共数据快数 21 chain.ViewBlockCount(); 22 23 //查看所有数据链 24 chain.ViewAllBlocks(); 25 26 //验证数据链 27 Console.WriteLine(chain.Validate()); 28 29 //模拟篡改数据 30 chain.Blocks[1].Prehash = ""; 31 32 //验证数据链 33 Console.WriteLine(chain.Validate()); 34 } 35 } 36 } 37 38 //数据块 39 public class Block 40 { 41 //数据 42 private string data; 43 //前一个Block的hash 44 private string prehash; 45 //当前Block的hash 46 private string curhash; 47 public Block(string data) 48 { 49 this.prehash = ""; 50 this.data = data; 51 this.curhash = ""; 52 } 53 54 //注意:这里为了模拟篡改数据专门封装的字段 55 public string Data { get => data; set => data = value; } 56 public string Prehash { get => prehash; set => prehash = value; } 57 public string Curhash { get => curhash; set => curhash = value; } 58 59 //计算当前Block的Hash 60 public string ComputeHash(string prehash) 61 { 62 this.prehash = prehash; 63 return SHA256(this.data + this.prehash); 64 } 65 66 //Hash256计算 67 public string SHA256(string str) 68 { 69 //如果str有中文,不同Encoding的sha是不同的!! 70 byte[] SHA256Data = Encoding.UTF8.GetBytes(str); 71 72 SHA256Managed Sha256 = new SHA256Managed(); 73 byte[] by = Sha256.ComputeHash(SHA256Data); 74 75 return BitConverter.ToString(by).Replace("-", "").ToLower(); 76 } 77 78 //显示Block数据 79 public void ViewInfo() 80 { 81 Console.WriteLine("===="); 82 Console.WriteLine("[prehash]->" + this.prehash); 83 Console.WriteLine("[data]->" + this.data); 84 Console.WriteLine("[hash]->" + this.curhash); 85 } 86 } 87 88 public class Chain 89 { 90 private List<Block> blocks; 91 92 public List<Block> Blocks { get => blocks; set => blocks = value; } 93 94 public Chain() 95 { 96 this.blocks = new List<Block>(); 97 Block genesisBloc = new Block("源数据块"); 98 genesisBloc.Curhash = genesisBloc.ComputeHash("genesis"); 99 AddNewBlock(genesisBloc); 100 } 101 102 public void ViewBlockCount() 103 { 104 Console.WriteLine("当前数据块总数->" + this.blocks.Count); 105 } 106 107 //添加Block 108 public void AddNewBlock(Block newblock) 109 { 110 //空链的情况 111 if (this.blocks.Count == 0) 112 { 113 this.blocks.Add(newblock); 114 newblock.Curhash = newblock.ComputeHash(newblock.Prehash); 115 return; 116 } 117 /*链接新Block*/ 118 //新的Block的prehash是上一个block的curhash 119 newblock.Prehash = this.blocks[this.blocks.Count - 1].Curhash; 120 newblock.Curhash = newblock.ComputeHash(newblock.Prehash); 121 /*添加新Block*/ 122 this.blocks.Add(newblock); 123 } 124 125 //查看所有Block 126 public void ViewAllBlocks() 127 { 128 foreach (var item in this.blocks) 129 { 130 item.ViewInfo(); 131 } 132 } 133 134 //验证Chain 135 public bool Validate() 136 { 137 //无任何数据块的情况 138 if (this.blocks.Count == 0) 139 { 140 Console.WriteLine("[数据链异常]->数据链为空!"); 141 return false; 142 } 143 //只有源数据块的情况 144 else if (this.blocks.Count == 1) 145 { 146 Console.WriteLine("验证完毕!"); 147 return true; 148 } 149 150 //遍历校验标志 151 bool checkBlockSign = true; 152 153 //遍历检查数据块,因为不检查源数据块,下标从1开始 154 for (int checkBlockIndex = 1; checkBlockIndex < this.blocks.Count; checkBlockIndex++) 155 { 156 //检验curhash 157 var checkBlock = this.blocks[checkBlockIndex]; 158 if (checkBlock.Curhash != checkBlock.ComputeHash(checkBlock.Prehash)) 159 { 160 Console.WriteLine("[数据被篡改]->" + checkBlockIndex); 161 checkBlockSign = false; 162 break; 163 } 164 /* //验证prehash 165 if (checkBlock.Prehash != this.blocks[checkBlockIndex - 1].Curhash) 166 { 167 Console.WriteLine("[数据链断裂]->" + checkBlockIndex); 168 checkBlockSign = false; 169 break; 170 }*/ 171 } 172 Console.WriteLine("验证完毕!"); 173 return checkBlockSign; 174 } 175 }
代码运行:
到这里,区块链的基础构建完成了。
因为当前模型的数据结构构建真的不复杂,所以省略了代码构建的分析过程。
【学习是人类进步的阶梯】