#yyds干货盘点#【愚公系列】2023年02月 .NET/C#知识点-区块链概念和实现

时间:2022-07-13 00:40:38

前言

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

一、区块链的实现

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; }
}

#yyds干货盘点#【愚公系列】2023年02月 .NET/C#知识点-区块链概念和实现

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;
        }
    }
}

#yyds干货盘点#【愚公系列】2023年02月 .NET/C#知识点-区块链概念和实现

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);
    }
}

#yyds干货盘点#【愚公系列】2023年02月 .NET/C#知识点-区块链概念和实现 2、运行 #yyds干货盘点#【愚公系列】2023年02月 .NET/C#知识点-区块链概念和实现

[{
	"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个区块链就像链条一样头尾相连。