前言
区块链是一种分布式数据库,使用密码学技术进行安全的数据记录和验证。它可以被用来创建可信赖的记录,并确保记录不可篡改。区块链的原理其实是一个又一个区块组成的链条。每一个区块中保存了一定的信息,它们按照各自产生的时间顺序连接成链条。这个链条被保存在所有的服务器中,只要整个系统中有一台服务器可以工作,整条区块链就是安全的。这些服务器在区块链系统中被称为节点,它们为整个区块链系统提供存储空间和算力支持。如果要修改区块链中的信息,必须征得半数以上节点的同意并修改所有节点中的信息,而这些节点通常掌握在不同的主体手中,因此篡改区块链中的信息是一件极其困难的事。相比于传统的网络,区块链具有两大核心特点:一是数据难以篡改、二是去中心化。基于这两个特点,区块链所记录的信息更加真实可靠,可以帮助解决人们互不信任的问题。
一、区块链的实现
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个区块链就像链条一样头尾相连。