内容简介:区块链是21世纪最具革命性的技术之一,至今仍在发展,很多潜力尚未完全实现。从本质上讲,区块链只是一个分布式数据库。但是它的独特之处在于它不是私人数据库,而是公共数据库,也就是说,使用它的每个人都有完整或部分数据副本。只有在数据库的其他管理员同意的情况下才能添加新记录。此外,正是由于区块链才使加密货币和智能合约成为可能。在本系列文章中,我们将构建一个基于简单区块链实现的简化加密货币。让我们从“区块链”的“区块”部分开始。在区块链中,区块是用来存储有价值信息的。实际上,交易信息是所有加密货币的价值所在。除此之外
Introduction
区块链是21世纪最具革命性的技术之一,至今仍在发展,很多潜力尚未完全实现。从本质上讲,区块链只是一个分布式数据库。但是它的独特之处在于它不是私人数据库,而是公共数据库,也就是说,使用它的每个人都有完整或部分数据副本。只有在数据库的其他管理员同意的情况下才能添加新记录。此外,正是由于区块链才使加密货币和智能合约成为可能。
在本系列文章中,我们将构建一个基于简单区块链实现的简化加密货币。
Block
让我们从“区块链”的“区块”部分开始。在区块链中,区块是用来存储有价值信息的。实际上,交易信息是所有加密货币的价值所在。除此之外,区块包含一些技术信息,如版本,当前时间戳和前一个块的哈希值。
在本文中,我们不打算实现像比特币规范中描述的那种区块,而是将使用它的简化版本,它只包含重要信息。这是它的样子:
type Block struct {
Timestamp int64
Data []byte
PrevBlockHash []byte
Hash []byte
}
Timestamp字段是当前时间戳(创建区块时),Data字段是区块中包含的实际有价值的信息,PrevBlockHash字段存储前一个区块的哈希值,Hash字段是当前区块的哈希值。在比特币规范中Timestamp, PrevBlockHash, 和 Hash是块头,它形成一个单独的数据结构,Data是另一个数据结构。我们为了简单起见将它们混合在了一起。
那么我们如何计算哈希?哈希计算方法是区块链的一个非常重要的特征,正是这个特征使区块链变得安全。问题在于计算哈希是一个计算上很困难的操作,即使在快速计算机上也需要一些时间(这就是人们购买功能强大的GPU来挖掘比特币的原因)。这是一种有意的架构设计,这使得添加新的区块变得困难,从而防止它们在添加后进行修改。我们将在以后的文章中讨论并实现这种机制。
目前,我们仅取了 Block
结构的部分字段( Timestamp
, Data
和 PrevBlockHash
),并将它们相互拼接起来,然后在拼接后的结果上计算一个 SHA-256,然后就得到了哈希.
Hash = SHA256(PrevBlockHash + Timestamp + Data)
在 SetHash
方法中完成这些操作:
func (b *Block) SetHash() {
timestamp := []byte(strconv.FormatInt(b.Timestamp, 10))
headers := bytes.Join([][]byte{b.PrevBlockHash, b.Data, timestamp}, []byte{})
hash := sha256.Sum256(headers)
b.Hash = hash[:]
}
接下来,遵循Golang约定,我们将实现一个简化创建区块的函数:
func NewBlock(data string, prevBlockHash []byte) *Block {
block := &Block{time.Now().Unix(), []byte(data), prevBlockHash, []byte{}}
block.SetHash()
return block
}
这就是区块!
Blockchain
现在让我们实现一个区块链。从本质上讲,区块链只是一个具有特定结构的数据库:它是一个有序的反向链接列表。这意味着区块以插入顺序存储,并且每个区块都链接到前一个区块。这种结构允许快速获取链中的最新区块并通过其散列(有效地)获得区块。
在 Golang 中,可以通过一个 array 和 map 来实现这个结构:array 存储有序的哈希(Golang 中 array 是有序的),map 存储 hash -> block 对(Golang 中, map 是无序的)。 但是在基本的原型阶段,我们只用到了 array,因为现在还不需要通过哈希来获取区块。
type Blockchain struct {
blocks []*Block
}
这是我们的第一个区块链!我从没想过会这么容易:wink:
现在让我们可以添加块:
func (bc *Blockchain) AddBlock(data string) {
prevBlock := bc.blocks[len(bc.blocks)-1]
newBlock := NewBlock(data, prevBlock.Hash)
bc.blocks = append(bc.blocks, newBlock)
}
结束!不过,就这样就完成了吗?
要添加新的区块,我们需要一个现有的区块,但是我们的区块链中没有区块!因此,在任何区块链中,必须至少有一个区块,这个区块,也就是链中的第一个区块,通常叫做创世区块( genesis block ). 让我们实现一个方法来创建创世区块:
func NewGenesisBlock() *Block {
return NewBlock("Genesis Block", []byte{})
}
现在,我们可以实现一个函数来创建有创世区块的区块链:
func NewBlockchain() *Blockchain {
return &Blockchain{[]*Block{NewGenesisBlock()}}
}
让我们检查下区块链是否正常工作:
func main() {
bc := NewBlockchain()
bc.AddBlock("Send 1 BTC to Ivan")
bc.AddBlock("Send 2 more BTC to Ivan")
for _, block := range bc.blocks {
fmt.Printf("Prev. hash: %x\n", block.PrevBlockHash)
fmt.Printf("Data: %s\n", block.Data)
fmt.Printf("Hash: %x\n", block.Hash)
fmt.Println()
}
}
Output:
Prev. hash: Data: Genesis Block Hash: aff955a50dc6cd2abfe81b8849eab15f99ed1dc333d38487024223b5fe0f1168 Prev. hash: aff955a50dc6cd2abfe81b8849eab15f99ed1dc333d38487024223b5fe0f1168 Data: Send 1 BTC to Ivan Hash: d75ce22a840abb9b4e8fc3b60767c4ba3f46a0432d3ea15b71aef9fde6a314e1 Prev. hash: d75ce22a840abb9b4e8fc3b60767c4ba3f46a0432d3ea15b71aef9fde6a314e1 Data: Send 2 more BTC to Ivan Hash: 561237522bb7fcfbccbc6fe0e98bbbde7427ffe01c6fb223f7562288ca2295d1
Conclusion
我们构建了一个非常简单的区块链原型:它只是一个区块数组,每个区块都与前一个区块连接。实际的区块链显然复杂得多。在我们的区块链中添加新区块很容易而且很快,但在实际区块链中添加新区块需要一些工作:在获得添加区块的权限之前必须执行一些繁重的计算(这种机制称为工作量证明)。此外,区块链是一个没有单一决策者的分布式数据库。因此,必须由网络的其他参与者确认和批准新的区块(该机制称为共识)。我们的区块链中还没有交易!
在以后的文章中,我们将介绍这些功能。
英文原文: https://jeiwan.cc/posts/building-blockchain-in-go-part-1/
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
The Book of CSS3
Peter Gasston / No Starch Press / 2011-5-13 / USD 34.95
CSS3 is the technology behind most of the eye-catching visuals on the Web today, but the official documentation can be dry and hard to follow. Luckily, The Book of CSS3 distills the heady technical la......一起来看看 《The Book of CSS3》 这本书的介绍吧!