在本教程中,我将尝试通过帮助你在Go中编写简单的区块链来揭开区块链的广义概念。
在本教程中,你应该能够:
- 理解区块链术语。
- 创建自己的简单区块链。
- 了解什么是区块以及如何创建块。
- 了解如何维护区块链的完整性。
区块链:一种数字分类帐,以较小的集合排列,称为块。这些块通过加密hash相互链接。每个块包含指向前一个块的哈希。区块链对于加密货币很有用,因为它具有去中心化的特性,这意味着存储的数据不在一个位置,而是每个人都可以访问,同时也是任何人都不可信的。
构建一个简单的区块链
在本教程中,我们将为图书馆系统创建一个示例区块链。我们的区块链将存储包含图书结账活动数据的区块。此实现的流程如下:
- 添加一本新书。
- 为书创建Genesis块。
- 将Checkout数据添加到区块链。
这是一个单节点,非复杂的区块链,在运行时将所有内容存储在内存中。
块
在区块链中,块存储有价值的信息。此信息可以是实现区块链的系统所需的交易或一些其他信息,例如交易时间戳或来自前一个块的哈希。我们将继续为每个块定义数据模型,以及构成区块链的结账信息:
package main
// Block contains data that will be written to the blockchain.
type Block struct {
Pos int
Data BookCheckout
Timestamp string
Hash string
PrevHash string
}
// BookCheckout contains data for a checked out book
type BookCheckout struct {
BookID string `json:"book_id"`
User string `json:"user"`
CheckoutDate string `json:"checkout_date"`
IsGenesis bool `json:"is_genesis"`
}
// Book contains data for a sample book
type Book struct {
ID string `json:"id"`
Title string `json:"title"`
Author string `json:"author"`
PublishDate string `json:"publish_date"`
ISBN string `json:"isbn:`
}
从Block
结构中,Pos
保持链中数据的位置。数据是块中包含的有价值信息(在这种情况下是结帐项目)。时间戳保存块创建的当前时间戳。哈希是块的生成哈希。PrevHash
存储前一个块的哈希值。
在定义了Block
结构的情况下,我们需要考虑对块进行哈希。哈希用于以正确的顺序识别和保持块。计算哈希值是区块链的一个非常重要的特征。计算哈希值是一项困难的操作(计算方面)。创建哈希的难度是经过深思熟虑的体系结构设计决策,因为它会增加新块的难度,防止在添加后进行可变操作。
哈希和生成块
我们将从一个简单的哈希方法开始,并编写一个函数calculateHash
来连接块字段并创建一个SHA-256哈希:
func (b *Block) generateHash() {
// get string val of the Data
bytes, _ := json.Marshal(b.Data)
// concatenate the dataset
data := string(b.Pos) + b.Timestamp + string(bytes) + b.PrevHash
hash := sha256.New()
hash.Write([]byte(data))
b.Hash = hex.EncodeToString(hash.Sum(nil))
}
接下来,让我们编写另一个函数CreateBlock
来创建一个新块。
func CreateBlock(prevBlock *Block, checkoutItem BookCheckout) *Block {