区块链模型原理入门学习2——细化模型

  以上描述中,存在一些非生产情景的理想化设定。

  比如:

  1.没有设计谜题难度平衡

  2.没有加入加密校验数字签证

  3.没有设计个人钱包

  4.广播问题

  ......

 

  代码:

复制代码
  1 using Newtonsoft.Json;
  2 using System;
  3 using System.Collections.Generic;
  4 using System.Diagnostics;
  5 using System.Linq;
  6 using System.Security.Cryptography;
  7 using System.Text;
  8 /*
  9     ZY的区块链简易模型学习
 10     1.1 搭建基础模型(添加数据块、校验数据块)
 11     1.2 加入挖矿机制
 12     1.3 加入挖矿奖励机制
 13  */
 14 namespace TestPrj
 15 {
 16     class Program
 17     {
 18         static void Main(string[] args)
 19         {
 20             Chain chain = new Chain();
 21 
 22             //1.3 到现在 就不能直接生成块了,而是通过矿工领取待验证块进行计算后验证合法后才能链入区块链上
 23             /*            Block block1 = new Block("转账10元");
 24                         chain.AddNewBlock(block1);
 25                         Block block2 = new Block("转账30元");
 26                         chain.AddNewBlock(block2);*/
 27 
 28             //1.3 模拟产生两条转账记录
 29             var transaction1 = new Transaction("address1", "address2", "30");
 30             var transaction2 = new Transaction("address1", "address2", "15");
 31 
 32             //1.3 把转账记录加入到转账记录池中
 33             chain.AddTransactionToPool(transaction1);
 34             chain.AddTransactionToPool(transaction2);
 35 
 36             //1.3 模拟矿工挖矿
 37             chain.MineAndReward("addressminer");
 38 
 39             //查看当前数据链总共数据快数
 40             chain.ViewBlockCount();
 41 
 42             //查看所有数据链
 43             chain.ViewAllBlocks();
 44 
 45             //验证数据链
 46             Console.WriteLine(chain.Validate());
 47 
 48             //模拟篡改数据
 49             chain.Blocks[1].Data = "转账100元";
 50 
 51             //验证数据链
 52             Console.WriteLine(chain.Validate());
 53         }
 54     }
 55 }
 56 
 57 //数据块
 58 public class Block
 59 {
 60     /*    //数据
 61         private string data;*/
 62     //1.3 这里的data 因为存储的是转账记录 所以类型为object
 63     private object data;
 64 
 65     //前一个Block的hash
 66     private string prehash;
 67     //当前Block的hash
 68     private string curhash;
 69     private string count;
 70     //1.3 确认时间
 71     private DateTime time;
 72     public Block(object data)
 73     {
 74         this.prehash = "";
 75         this.data = data;
 76         this.curhash = "";
 77         this.count = "";
 78     }
 79 
 80     //注意:这里为了模拟篡改数据专门封装的字段
 81     public object Data { get => data; set => data = value; }
 82     public string Prehash { get => prehash; set => prehash = value; }
 83     public string Curhash { get => curhash; set => curhash = value; }
 84     public string Count { get => count; set => count = value; }
 85     public DateTime Time { get => time; set => time = value; }
 86 
 87     //计算当前Block的Hash
 88     /*    public string ComputeHash(string prehash)
 89         {
 90             this.prehash = prehash;
 91             return SHA256(this.data + this.prehash);
 92         }*/
 93 
 94     //1.2 计算当前Block符合要求的Hash
 95     public string ComputeBlockPassHash(string prehash, string str = "")
 96     {
 97         this.prehash = prehash;
 98         //return SHA256(this.data + this.prehash + str);
 99         //1.3 这里需要返回的数据
100         //更新时间
101         //[转账记录].jsonString+prehash+str
102         this.Time = DateTimeOffset.UtcNow.DateTime;
103         return SHA256(JsonConvert.SerializeObject(this.data) + prehash + str);
104     }
105 
106     //Hash256计算
107     public string SHA256(string str)
108     {
109         //如果str有中文,不同Encoding的sha是不同的!!
110         byte[] SHA256Data = Encoding.UTF8.GetBytes(str);
111 
112         SHA256Managed Sha256 = new SHA256Managed();
113         byte[] by = Sha256.ComputeHash(SHA256Data);
114 
115         return BitConverter.ToString(by).Replace("-", "").ToLower();
116     }
117 
118     //显示Block数据
119     public void ViewInfo()
120     {
121         Console.WriteLine("====");
122         Console.WriteLine("[prehash]->" + this.prehash);
123         Console.WriteLine("[data]->");
124         if (this.data != null)
125         {
126             foreach (var item in (List<Transaction>)this.data)
127             {
128                 Console.WriteLine(item.ToString());
129             }
130         }
131         Console.WriteLine("[time]->" + this.time.ToLocalTime());
132         Console.WriteLine("[hash]->" + this.curhash);
133     }
134 }
135 
136 public class Chain
137 {
138     private List<Block> blocks;
139 
140     //1.3 转账记录池,用处存储每一笔转账记录
141     private List<Transaction> transactionPool;
142 
143     //1.3 奖励金
144     private string reward = "50";
145 
146     //1.3 困难度
147     private int difficulty = 2;
148     public List<Block> Blocks { get => blocks; set => blocks = value; }
149 
150     public Chain()
151     {
152         this.blocks = new List<Block>();
153         this.transactionPool = new List<Transaction>();
154         Block genesisBloc = new Block(null);
155         genesisBloc.Curhash = genesisBloc.ComputeBlockPassHash("genesis");
156         AddNewBlock(genesisBloc);
157     }
158 
159     public void ViewBlockCount()
160     {
161         Console.WriteLine("当前数据块总数->" + this.blocks.Count);
162     }
163 
164     //添加Block
165     public void AddNewBlock(Block newblock)
166     {
167         //空链的情况
168         if (this.blocks.Count == 0)
169         {
170             this.blocks.Add(newblock);
171             newblock.Curhash = newblock.ComputeBlockPassHash(newblock.Prehash);
172             return;
173         }
174         /*链接新Block*/
175         //新的Block的prehash是上一个block的curhash
176         newblock.Prehash = this.blocks[this.blocks.Count - 1].Curhash;
177 
178         //1.2 加入挖矿计算后,需要符合要求的Hash才能被链入,其中会涉及平均计算时间和设置计算困难度的关系(这里暂时不考虑)
179         //newblock.Curhash = newblock.ComputeHash(newblock.Prehash);
180 
181         /*1.2挖矿计算*/
182         ComputePassHash(newblock, this.difficulty);
183 
184         /*添加新Block*/
185         this.blocks.Add(newblock);
186     }
187 
188     //1.2 获取计算难度
189     public string GetComputeDifficulty(int difficulty)
190     {
191         //这里做简单要求,即根据难度,形成指定数量的0的字符串
192         string passStr = "";
193         for (int setDiffIndex = 0; setDiffIndex < difficulty; setDiffIndex++)
194         {
195             passStr += "0";
196         }
197         return passStr;
198     }
199 
200     //1.2 计算符合要求的哈希值
201     public void ComputePassHash(Block block, int difficulty)
202     {
203         int count = 0;
204         while (true)
205         {
206             count++;
207             //加入参数计算哈希值
208             string checkHash = block.ComputeBlockPassHash(block.Prehash, count.ToString());
209             Console.WriteLine("" + count + "次计算->" + checkHash);
210             //判断计算的哈希值符合相应难度的要求,即前哈希值前四位必须为0才算合格
211             if (checkHash.Substring(0, difficulty).Equals(GetComputeDifficulty(difficulty)))
212             {
213                 block.Curhash = checkHash;
214                 block.Count = count.ToString();
215                 break;
216             }
217         }
218         //模拟挖掘到符合的哈希值
219         Console.WriteLine("经过" + count + "次计算挖掘到->" + block.Curhash);
220 
221         //1.3清空转账记录池
222         //这里屏蔽掉的原因:因为本次学习取到了转账记录池里的全部记录的缘故,清理后会影响后面的显示,好吧..我承认,这就是个小BUG...
223         //this.transactionPool.Clear();
224     }
225 
226     //查看所有Block
227     public void ViewAllBlocks()
228     {
229         foreach (var item in this.blocks)
230         {
231             item.ViewInfo();
232         }
233     }
234 
235     //验证Chain
236     public bool Validate()
237     {
238         //无任何数据块的情况
239         if (this.blocks.Count == 0)
240         {
241             Console.WriteLine("[数据链异常]->数据链为空!");
242             return false;
243         }
244         //只有源数据块的情况
245         else if (this.blocks.Count == 1)
246         {
247             Console.WriteLine("验证完毕!");
248             return true;
249         }
250 
251         //遍历校验标志
252         bool checkBlockSign = true;
253 
254         //遍历检查数据块,因为不检查源数据块,下标从1开始
255         for (int checkBlockIndex = 1; checkBlockIndex < this.blocks.Count; checkBlockIndex++)
256         {
257             //检验curhash
258             var checkBlock = this.blocks[checkBlockIndex];
259             if (checkBlock.Curhash != checkBlock.ComputeBlockPassHash(checkBlock.Prehash, checkBlock.Count))
260             {
261                 Console.WriteLine("[数据被篡改]->" + checkBlockIndex);
262                 checkBlockSign = false;
263                 break;
264             }
265             /*            //验证prehash
266                         if (checkBlock.Prehash != this.blocks[checkBlockIndex - 1].Curhash)
267                         {
268                             Console.WriteLine("[数据链断裂]->" + checkBlockIndex);
269                             checkBlockSign = false;
270                             break;
271                         }*/
272         }
273         Console.WriteLine("验证完毕!");
274         return checkBlockSign;
275     }
276 
277     //1.3 添加转账记录
278     public void AddTransactionToPool(Transaction transaction)
279     {
280         this.transactionPool.Add(transaction);
281     }
282 
283     //1.3挖矿并获取奖励
284     public void MineAndReward(string minerAddress)
285     {
286         //生成奖励转账 因为系统奖励,所以转账人地址是空的
287         var rewardTransform = new Transaction("", minerAddress, this.reward);
288 
289         //把矿工的奖励转账记录也要存进转账池子里
290         this.transactionPool.Add(rewardTransform);
291 
292         //生成block(这里默认h获取转账池里的所有转账记录)
293         var block = new Block(this.transactionPool);
294 
295         //计算合法哈希值
296         AddNewBlock(block);
297     }
298 }
299 
300 //1.3交易记录 转账人 收款人 转账数额 (注意!这里没有转账时间,根据中本聪的论文,转账时间和block生成的时间是统一的,也就是说block被挖到的时候才会创建时间)
301 public class Transaction
302 {
303     //转账方地址
304     public string transferor;
305     //收款方地址
306     public string payee;
307     //转账金额
308     public string money;
309 
310     public Transaction(string transferor, string payee, string money)
311     {
312         this.transferor = transferor;
313         this.payee = payee;
314         this.money = money;
315     }
316     public override string ToString()
317     {
318         return this.transferor + "-" + this.payee + "-" + this.money;
319     }
320 }
复制代码

 

  执行结果:

  到此,奖励机制加入完成了,当然,还有很多地方需要优化和改进。

 【学习是人类进步的阶梯】

 

posted @   MOEGARN游戏工作室  阅读(3)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)
历史上的今天:
2020-02-23 模拟射击文字类游戏(Python)
2020-02-23 模拟射击文字类游戏
点击右上角即可分享
微信分享提示