青州做网站的电话,音乐网站后台模板,wordpress清理软件,Wordpress使用ldap0x00 介绍 区块链#xff08;Blockchain#xff09;是21世纪最具革命性的技术之一#xff0c;目前它仍处于逐渐成熟阶段#xff0c;且其发展潜力尚未被完全意识到。从本质上讲#xff0c;区块链只是一种记录的分布式数据库。但它之所以独特#xff0c;是因为它并不是一个… 0x00 介绍 区块链Blockchain是21世纪最具革命性的技术之一目前它仍处于逐渐成熟阶段且其发展潜力尚未被完全意识到。从本质上讲区块链只是一种记录的分布式数据库。但它之所以独特是因为它并不是一个私有的数据库而是一个公共数据库也就是说每个使用它的人都有一份完整或部分的数据副本。并且只有在数据库的其他持有者同意的情况下才可以向区块链中添加新的记录。此外正是区块链使得加密货币和智能合约成为可能。 在本系列文章中我们将基于区块链构建一种简单的加密货币。 0x01 区块 首先我们从“区块链”中的“区块”介绍开始。在区块链中区块是存储有价值信息的块。例如比特币区块用于存储交易这是任何一种加密货币的本质。除此之外区块还包含一些技术信息比如它的版本、当前时间戳和前一区块的散列值哈希值。 在本文中我们不打算实现区块链或比特币规范中描述的那种区块而是使用它的简化版本即我们将要实现的区块结构中只包含重要的信息。下面代码中为我们的区块结构 type Block struct {Timestamp int64Data []bytePrevBlockHash []byteHash []byte
} Timestamp时间戳是区块创建时刻的时间戳Data是包含在区块中的实际有价值的信息PrevBlockHas存储前一区块的散列值而Hash是当前区块的散列值。在比特币规范中Timestamp、PrevBlockHash和Hash是区块头它们组成了一个单独的数据结构而交易在我们的例子中是Data也是一个单独的数据结构。为了简单起见我们此处将它们混合在一起。 那么如何计算散列值呢散列值的计算方式是区块链的一个十分重要的特性正是该特性使得区块链变得安全。计算一个区块的散列值是一种计算上十分困难的操作即使在快速计算机上也需要一些时间这就是人们会购买强大的GPU来挖比特币的原因。这是一种有意的架构设计它使得添加新的区块变得很困难因此可以防止对已有区块的篡改。我们将在以后的文章中讨论并实现这种机制。 现在我们仅仅使用区块字段连接它们并在连接的组合上计算一个SHA-256散列值。下面我们使用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
} 这样我们就准备好了区块的工作 0x02 区块链 现在我们来实现一个区块链。实质上区块链只是一个包含某些特定结构的数据库它是一种有序的反向链接列表。这意味着区块以插入顺序进行存储并每个区块会链接到前一区块。这个结构能够保证快速获得一个区块链中最新的区块并能够通过区块散列值高效地获取到该区块。 在Golang中可以使用一个数组和一个map来实现这种结构数组用于保存有序的散列在Go中数组是有序的而map用于保存散列-区块对map是无序的。然而对于我们的区块链原型来说我们仅仅使用一个数组因为现在我们不需要通过区块的散列来获得对应的区块。 type Blockchain struct {blocks []*Block
} 这是我们的第一个区块链我从未想过它会这么容易。 现在我们实现添加区块的功能 func (bc *Blockchain) AddBlock(data string) {prevBlock : bc.blocks[len(bc.blocks)-1]newBlock : NewBlock(data, prevBlock.Hash)bc.blocks append(bc.blocks, newBlock)
} 这样就完了么No 为了向区块链中添加一个新区块我们需要确保已经存在了一个区块但是目前我们的区块链中并未存在任何区块。所以在任何区块链中都必须存在至少一个区块区块链中的首个区块称为创世区块。下面我们实现一个方法来创建创世区块 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()}
} 输出结果如下 Prev. hash:
Data: Genesis Block
Hash: aff955a50dc6cd2abfe81b8849eab15f99ed1dc333d38487024223b5fe0f1168Prev. hash: aff955a50dc6cd2abfe81b8849eab15f99ed1dc333d38487024223b5fe0f1168
Data: Send 1 BTC to Ivan
Hash: d75ce22a840abb9b4e8fc3b60767c4ba3f46a0432d3ea15b71aef9fde6a314e1Prev. hash: d75ce22a840abb9b4e8fc3b60767c4ba3f46a0432d3ea15b71aef9fde6a314e1
Data: Send 2 more BTC to Ivan
Hash: 561237522bb7fcfbccbc6fe0e98bbbde7427ffe01c6fb223f7562288ca2295d1 通过上面的结果我们可以确定该区块链可以正常工作。 0x03 结论 本文中我们创建了一个非常简单的区块链原型它仅仅是一个区块数组其中每个区块都有一个链接到前一区块不过实际的区块链要比这复杂得多。在我们的区块链中添加新的区块简单快速但在实际的区块链中添加新区块则需要做一些工作在获取添加区块的权限之前区块添加者或者说节点必须执行一些繁重的计算这种机制称为工作证明Proof-of-WorkPOW。此外区块链是一种分布式数据库所以并没有一个唯一的决策者。因此一个新的区块必须由网络中的其他参与者确认和批准这种机制称为共识机制。最后目前我们的区块链中还没有交易!在后续的文章中我们将逐步讨论这些功能和特点。 下一篇《【区块链Go语言实现】Part 2工作量证明机制POW》中我们将介绍区块链中的工作量证明机制。 英文链接https://jeiwan.cc/posts/building-blockchain-in-go-part-1/转载于:https://www.cnblogs.com/leejack/p/8259723.html