介绍
区块链技术是比特币的基础,比特币是世界上最流行的加密货币。随着比特币的普及,区块链的曝光率也很高。人们现在也开始在非加密货币类型的应用程序中使用区块链。看看中本聪(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,输出在控制台。
验证
使用区块链的优点之一是数据安全性。数据安全性是指通过加密方法和数据本身的非集中式存储来防止篡改旧数据和改变保护新数据的方法。然而,区块链只是一种数据结构,在这种结构中,数据可以像这样轻松地进行更改。
因此,我们需要一种验证数据的方法。这就是为什么我在代码中添加了一个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从事软件开发已经超过十年了。他在新泽西理工大学拥有计算机科学硕士学位。作为一名技术实践者,他总是对所有的新技术感到兴奋。