在.Net Core中构建一个基本的区块链

介绍

区块链技术是比特币的基础,比特币是世界上最流行的加密货币。随着比特币的普及,区块链的曝光率也很高。人们现在也开始在非加密货币类型的应用程序中使用区块链。看看中本聪(Satoshi Nakamoto,区块链的创始人)的比特币白皮书,你可能会对比特币的运作方式感到困惑。今天,我将从零开始构建一个区块链,以帮助大家理解区块链的机制。

什么是Blockchain ?

Blockchain是一个数据库。什么是数据库?数据库是有组织的数据集合。或者,你可以说,存储数据的数据结构。因此,区块链只是一个存储数据的数据结构。就像这个名字所暗示的,将会有一串积木。

Chain of Blocks

下面是基本区块链的架构图。

这个基本的区块链有一个由块组成的链表。每个块都具有以下属性。

索引

时间戳

先前的哈希码(散列)

哈希码

数据

第一个块是一个特殊的块:起源块。起源块是唯一没有先前的块且不包含数据的块。

实现

我们将为这个数据结构添加两个类:Block和BlockChain区块链。

Block:

public class Block  
{  
 public int Index { get; set; }  
 public DateTime TimeStamp { get; set; }  
 public string PreviousHash { get; set; }  
 public string Hash { get; set; }  
 public string Data { get; set; }  
 
 public Block(DateTime timeStamp, string previousHash, string data)  
    {  
        Index = 0;  
        TimeStamp = timeStamp;  
        PreviousHash = previousHash;  
        Data = data;  
        Hash = CalculateHash();  
    }  
 
 public string CalculateHash()  
    {  
        SHA256 sha256 = SHA256.Create();  
 
 byte[] inputBytes = Encoding.ASCII.GetBytes($"{TimeStamp}-{PreviousHash ?? ""}-{Data}");  
 byte[] outputBytes = sha256.ComputeHash(inputBytes);  
 
 return Convert.ToBase64String(outputBytes);  
    }  
}  

BLOCKCHAIN:

public class Blockchain  
{  
 public IList<Block> Chain { set;  get; }  
 
 public Blockchain()  
    {  
        InitializeChain();  
        AddGenesisBlock();  
    }  
 
 
 public void InitializeChain()  
    {  
        Chain = new List<Block>();  
    }  
 
 public Block CreateGenesisBlock()  
    {  
 return new Block(DateTime.Now, null, "{}");  
    }  
 
 public void AddGenesisBlock()  
    {  
        Chain.Add(CreateGenesisBlock());  
    }  
 
 public Block GetLatestBlock()  
    {  
 return Chain[Chain.Count - 1];  
    }  
 
 public void AddBlock(Block block)  
    {  
        Block latestBlock = GetLatestBlock();  
        block.Index = latestBlock.Index + 1;  
        block.PreviousHash = latestBlock.Hash;  
        block.Hash = block.CalculateHash();  
        Chain.Add(block);  
    }  
}  

有了这两个类之后,我们可以创建新的区块链的实例。

我们可以给它添加区块。

下面列出代码:

Blockchain phillyCoin = new Blockchain();  
phillyCoin.AddBlock(new Block(DateTime.Now, null, "{sender:Henry,receiver:MaHesh,amount:10}"));  
phillyCoin.AddBlock(new Block(DateTime.Now, null, "{sender:MaHesh,receiver:Henry,amount:5}"));  
phillyCoin.AddBlock(new Block(DateTime.Now, null, "{sender:Mahesh,receiver:Henry,amount:5}"));  
 
Console.WriteLine(JsonConvert.SerializeObject(phillyCoin, Formatting.Indented));  

区块链信息将被序列化为JSON,输出在控制台。

验证

使用区块链的优点之一是数据安全性。数据安全性是指通过加密方法和数据本身的非集中式存储来防止篡改旧数据和改变保护新数据的方法。然而,区块链只是一种数据结构,在这种结构中,数据可以像这样轻松地进行更改。

  1. phillyCoin.Chain[1].Data = "{sender:Henry,receiver:MaHesh,amount:1000}";

因此,我们需要一种验证数据的方法。这就是为什么我在代码中添加了一个IsValid方法。

public bool IsValid()  
{  
 for (int i = 1; i < Chain.Count; i++)  
    {  
        Block currentBlock = Chain[i];  
        Block previousBlock = Chain[i - 1];  
 
 if (currentBlock.Hash != currentBlock.CalculateHash())  
        {  
 return false;  
        }  
 
 if (currentBlock.PreviousHash != previousBlock.Hash)  
        {  
 return false;  
        }  
    }  
 return true;  
}  

IsValid方法将检查两件事情。

  • 每个块的散列以查看该块是否被更改
  • 前一个块的散列,以查看该块是否被更改并重新计算

然后,在数据篡改和数据篡改之后,我们调用IsValid,查看是否存在任何数据问题。

Console.WriteLine($"Is Chain Valid: {phillyCoin.IsValid()}");  
 
Console.WriteLine($"Update amount to 1000");  
phillyCoin.Chain[1].Data = "{sender:Henry,receiver:MaHesh,amount:1000}";  
 
Console.WriteLine($"Is Chain Valid: {phillyCoin.IsValid()}");  

当攻击者重新计算被篡改块的散列时,情况如何?

phillyCoin.Chain[1].Hash = phillyCoin.Chain[1].CalculateHash();  

验证结果仍然是假的,因为验证不仅要查看当前块,还要查看到前一个块的链接。

现在,当攻击者重新计算所有当前块和以下块的散列时,该如何处理呢?

Console.WriteLine($"Update the entire chain");  
phillyCoin.Chain[2].PreviousHash = phillyCoin.Chain[1].Hash;  
phillyCoin.Chain[2].Hash = phillyCoin.Chain[2].CalculateHash();  
phillyCoin.Chain[3].PreviousHash = phillyCoin.Chain[2].Hash;  
phillyCoin.Chain[3].Hash = phillyCoin.Chain[3].CalculateHash();   

在重新计算所有块之后,验证就会通过。但是,由于区块链是一个分散的系统,所以它只在一个节点上传递。对一个节点进行篡改很容易,但是对系统中的所有节点进行篡改是不可能的。

总结

区块链是一系列的块。它使用密码学来确保数据的完整性。您可以在Visual Studio 2017中打开并运行示例代码。这是我的“在.net Core中构建区块链”系列的第一篇文章。

作者:

Henry He从事软件开发已经超过十年了。他在新泽西理工大学拥有计算机科学硕士学位。作为一名技术实践者,他总是对所有的新技术感到兴奋。

原文发布于微信公众号 - 程序你好(codinghello)

原文发表时间:2018-06-14

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏华仔的技术笔记

Spectrum光谱链共识算法的分析

Spectrum(光谱链)是SmartMesh生态下的公链,承载去中心化Mesh网络实现万物互联dapp的底层公链。由Payment Channel的建构的Sm...

10530
来自专栏转载gongluck的CSDN博客

拉丁猪文字游戏

拉丁猪文字游戏——这是一个英语语言游戏。基本规则是将一个英语单词的第一个辅音音素的字母移动到词尾并且加上后缀-ay(譬如“banana”会变成“anana-ba...

432100
来自专栏GIS讲堂

Openlayers2中统计图的实现

在前文中,介绍了Arcgis for js和Openlayers3中统计图的实现,在本文,书接上文,介绍在Openlayers2中,统计图的实现。

15630
来自专栏杂烩

分布式服务框架之Dubbo整合Spring项目(二)

11420
来自专栏函数式编程语言及工具

Akka(35): Http:Server side streaming

   在前面几篇讨论里我们都提到过:Akka-http是一项系统集成工具库。它是以数据交换的形式进行系统集成的。所以,Akka-http的核心功能应该是数据交换...

23650
来自专栏ASP.NET MVC5 后台权限管理系统

ASP.NET MVC5+EF6+EasyUI 后台管理系统(53)-工作流设计-我的批阅

前言:由于工作原因工作流一直没时间更新,虽然没有更新,但是批阅和申请差不多,改变一下数据的状态字段就行,有几个园友已经率先完成了 说句实话,一个工作流用文章表达...

369110
来自专栏.net core新时代

Spire.Doc组件读取与写入Word

  之前写了一篇开源组件DocX读写word的文章,当时时间比较匆忙选了这个组件,使用过程中还是有些不便,不能提前定义好模版,插入Form表单域进行替换。最近无...

297100
来自专栏技术之路

wcf webHttpBinding Post 大数据量提交 ios c#客户端

一直在为安卓和苹果写服务,刚开始的时候全用的Get请求用url传所有的参数,由于url长度的限制大的数据量 无法传到服务器,提交图片什么的就更不用说了,后来用的...

240100
来自专栏游戏杂谈

基于SOUI开发一个简单的小工具

Duilib 很久不维护了,而很多不同的分支,似乎都不太维护。微信 Windows 的版本是基于 Duilib 进行开发的,说明应该还是很广泛的。

46130
来自专栏数据结构与算法

BZOJ3262: 陌上花开(cdq分治)

第一行为N,K (1 <= N <= 100,000, 1 <= K <= 200,000 ), 分别表示花的数量和最大属性值。

14820

扫码关注云+社区

领取腾讯云代金券