【愚公系列】2023年02月 .NET/C#知识点-区块链概念和实现
2023-06-13 09:17:28 时间
文章目录
前言
区块链是一种分布式数据库,使用密码学技术进行安全的数据记录和验证。它可以被用来创建可信赖的记录,并确保记录不可篡改。区块链的原理其实是一个又一个区块组成的链条。每一个区块中保存了一定的信息,它们按照各自产生的时间顺序连接成链条。这个链条被保存在所有的服务器中,只要整个系统中有一台服务器可以工作,整条区块链就是安全的。这些服务器在区块链系统中被称为节点,它们为整个区块链系统提供存储空间和算力支持。如果要修改区块链中的信息,必须征得半数以上节点的同意并修改所有节点中的信息,而这些节点通常掌握在不同的主体手中,因此篡改区块链中的信息是一件极其困难的事。相比于传统的网络,区块链具有两大核心特点:一是数据难以篡改、二是去中心化。基于这两个特点,区块链所记录的信息更加真实可靠,可以帮助解决人们互不信任的问题。
一、区块链的实现
1.定义区块模型
/// <summary>
/// 区块数据模型
/// </summary>
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; }
}
2.管理区块链
/// <summary>
/// 管理区块链
/// </summary>
public static class BlockGenerator
{
public static List<Block> _blockChain = new List<Block>();
/// <summary>
/// 计算区块 HASH 值
/// </summary>
/// <param name="block">区块实例</param>
/// <returns>计算完成的区块散列值</returns>
public static string CalculateHash(Block block)
{
string calculationStr = $"{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
};
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;
}
}
}
3.使用区块链
1、webapi相关代码
[ApiController]
[Route("[controller]/[action]")]
public class HomeController : ControllerBase
{
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
/// <summary>
/// 设置10个区块
/// </summary>
/// <param name="bpm"></param>
/// <returns></returns>
[HttpPost]
[Route("/BlockChain")]
public string BlockChain(int bpm)
{
// 增加区块链
if (BlockGenerator._blockChain.Count == 0)
{
Block firstBlock = new Block()
{
Index = 0,
TimeStamp = BlockGenerator.CalculateCurrentTimeUTC(),
BPM = 0,
Hash = string.Empty,
PrevHash = string.Empty
};
BlockGenerator._blockChain.Add(firstBlock);
return JsonConvert.SerializeObject(firstBlock);
}
else
{
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);
}
return JsonConvert.SerializeObject(newBlock);
}
}
//提取区块链
[HttpGet]
[Route("/BlockChains")]
public string Validate()
{
return JsonConvert.SerializeObject(BlockGenerator._blockChain);
}
}
2、运行
[{
"Index": 0,
"TimeStamp": "1676908972475",
"BPM": 0,
"Hash": "",
"PrevHash": ""
}, {
"Index": 1,
"TimeStamp": "1676908974139",
"BPM": 1,
"Hash": "fb3fdd06a2175b8531b44680ebbd846a080ba3262819bff8e78fd8fdb37ae5cb",
"PrevHash": ""
}, {
"Index": 2,
"TimeStamp": "1676908975705",
"BPM": 2,
"Hash": "c15d7d8f13cc0a74922ab7435df72c79751bf642c7636d839b41a047c257f9f5",
"PrevHash": "fb3fdd06a2175b8531b44680ebbd846a080ba3262819bff8e78fd8fdb37ae5cb"
}, {
"Index": 3,
"TimeStamp": "1676908980354",
"BPM": 3,
"Hash": "1a9da938bf89d57b3ee18a62b79b9be41424c2552dd1d0bfa15038be4faae504",
"PrevHash": "c15d7d8f13cc0a74922ab7435df72c79751bf642c7636d839b41a047c257f9f5"
}, {
"Index": 4,
"TimeStamp": "1676908981790",
"BPM": 4,
"Hash": "e37b72244f41ecdef2da0ef5ede0971560eec9a5144d935ac74f2ea9ece44b8e",
"PrevHash": "1a9da938bf89d57b3ee18a62b79b9be41424c2552dd1d0bfa15038be4faae504"
}, {
"Index": 5,
"TimeStamp": "1676908983222",
"BPM": 5,
"Hash": "87a91f780299618510befed23da583af035147f21f51e21866d2d0ad412485ee",
"PrevHash": "e37b72244f41ecdef2da0ef5ede0971560eec9a5144d935ac74f2ea9ece44b8e"
}, {
"Index": 6,
"TimeStamp": "1676908984659",
"BPM": 6,
"Hash": "960d8fb0f6c77a20a1b26a870f5a43489f39b2a22b382f413cb870d446afaecc",
"PrevHash": "87a91f780299618510befed23da583af035147f21f51e21866d2d0ad412485ee"
}]
可以看到生成7个区块链就像链条一样头尾相连。
相关文章
- 通过Queue 类解决C#数据并发问题
- [C#.NET 拾遗补漏]09:数据标注与数据校验
- .Net Core3.1 SignalR for WPF Asp.net
- c#操作串口
- 【愚公系列】2023年02月 .NET/C#知识点-委托、匿名方法、Lambda、泛型委托、表达式树的进化史
- 【愚公系列】2023年01月 .NET/C#知识点-LINQ和lambda实现左、右、内链接
- 【愚公系列】2023年02月 .NET/C#知识点-List转成字符串的总结
- dotnet C# 使用 Vortice 创建 Direct2D1 的 ID2D1SolidColorBrush 纯色画刷
- 【100个 Unity实用技能】 | C# 中关于补位的写法 PadLeft,PadRight 函数
- 使用SHA256WithRSA来签名和验签(.NET/C#)详解编程语言
- C#/.NET程序集详解
- NET环境下 MySQL数据库应用实践(.net配合 mysql)
- Net结合MySQL实现强劲的数据库运算(.net 用mysql)
- C#.Net学习笔记(一)
- ASP.NET(C#)String,StringBuilder与StringWriter性能比较
- ASP.NET(C#)定时执行一段代码
- asp.net(c#)实现从sqlserver存取二进制图片的代码
- C#利用ODP.net连接Oracle数据库的操作方法
- C#序列化成XML注意细节
- C#.net格式化时间字符串达到不同的显示效果
- 基于ASP.NET的lucene.net全文搜索实现步骤
- C#.NET字符串比较中忽略符号的方法
- c#中合并DataTable重复行的值
- 深入c#类和结构的区别总结详解
- .net(c#)中的new关键字详细介绍
- c#数据绑定之向查询中添加参数(.Net连接外部数据库)
- C#实现HTTP下载文件的方法