本文译自 Building Blockchain in Go. Part 1: Basic Prototype
简介
区块链是21世纪最革命性的技术之一,仍然在不断发展,其潜力尚未充分实现。本质上,区块链只是一种分布式记录数据库。但使其独特的是,它不是私有数据库,而是公共数据库,即每个使用它的人都拥有其全部或部分副本。新的记录只能在数据库的其他维护者同意的情况下添加。此外,正是区块链使加密货币和智能合约成为可能。
在这一系列的文章中,我们将构建一个基于简单区块链实现的简化加密货币。
区块
让我们从“区块链”中的“区块”部分开始。在区块链中,存储有价值信息的是区块。例如,比特币区块存储交易,这是任何加密货币的本质。除此之外,一个区块还包含一些技术信息,如其版本、当前时间戳和前一区块的哈希值。 在本文中,我们不打算按照区块链或比特币规范实现区块,而是使用其简化版本,仅包含重要信息。以下是其结构:
|
|
Timestamp
是当前时间戳(区块创建时的时间),Data
是包含在区块中的实际有价值的信息,PrevBlockHash
存储前一区块的哈希值,而Hash
是区块的哈希值。在比特币规范中,Timestamp、PrevBlockHash和Hash构成区块头,形成一个独立的数据结构,而交易(在我们的情况中是Data)是另一个独立的数据结构。出于简化考虑,我们在这里将它们混合在一起。
那么我们如何计算哈希值呢?哈希值的计算方式是区块链的一个非常重要的特性,正是这个特性使得区块链具有安全性。问题在于计算哈希是一项计算上困难的操作,即使在高速计算机上也需要一些时间(这就是为什么人们购买强大的GPU来挖掘比特币的原因)。这是一种有意的架构设计,使得添加新区块变得困难,从而防止它们在添加后被修改。我们将在未来的文章中讨论并实现这一机制。
目前,我们将简单地取区块字段,连接它们,然后对连接的组合计算SHA-256哈希值。让我们在SetHash方法中完成这个操作:
|
|
接下来,遵循Golang的约定,我们将实现一个简化区块创建过程的函数:
|
|
区块链
现在让我们来实现一个区块链。在其本质上,区块链只是一种具有特定结构的数据库:它是一个有序的、反向链接的列表。这意味着区块按照插入顺序存储,并且每个区块链接到前一个区块。这种结构允许快速获取链中的最新区块,并(高效地)通过其哈希获取区块。
在Golang中,可以通过使用数组和哈希表(map)来实现这种结构:数组将保持有序的哈希值(在Go中数组是有序的),而map(哈希表)将保持哈希值到区块的映射(map是无序的)。但对于我们的区块链原型,我们将只使用数组,因为目前我们不需要通过哈希值获取区块。
|
|
这是我们的第一个区块链!我从没想过会这么容易😉
现在让我们可以向其中添加块:
|
|
就是这样!还是有点不够。。
要添加一个新区块,我们需要一个已经存在的区块,但是在我们的区块链中还没有区块!在任何区块链中,必须至少有一个区块(被称为创世块)。让我们实现一个创建这样一个区块的方法:
|
|
现在,我们可以实现一个使用创世块创建区块链的函数:
|
|
让我们检查一下区块链是否正常工作:
|
|
输出:
|
|
就是这样!
结论
我们构建了一个非常简单的区块链原型:它只是一个区块数组,每个区块都与前一个区块相连接。然而,实际的区块链要复杂得多。在我们的区块链中,添加新区块是轻松而快速的,但在真实的区块链中,添加新区块需要一些工作:在获得添加区块权限之前,必须执行一些繁重的计算(这个机制被称为工作量证明 Proof-of-Work PoW)。此外,区块链是一个分布式数据库,没有单一的决策者。因此,新区块必须得到网络其他参与者的确认和批准(这个机制被称为共识)。而且,在我们的区块链中还没有交易!
在未来的文章中,我们将涵盖这些特性中的每一个。