快捷搜索:  as

如何打造出一个简化版本的加密货币

第一部分:根基原型

简介

区块链是二十一世纪最具革命性的技巧之一,它正在赓续成熟,它的诸多潜力正在慢慢实现中。本色上来看,区块链只不过是一个散播式的数据库。之以是区块链独特,是由于它并不是一个私稀有据库,而是一个公开的数据库,即,每一个应用它的人拥有这个数据库的整个或者至少一部分。任何一个新的数据记录,只能在多半数据库持有者(掩护者)的多半批准之后被加入数据库。正因如斯,区块链使得加密泉币以及智能合约成为可能。

在这个系列文章中,我们将打造一个简化版本的加密泉币,它将基于一个简化版本的区块链实现。

区块(Block)

让我们先从区块开始。在区块链里,代价信息存储在区块之中。比如,比特币的区块存储买卖营业记录,而买卖营业记录是任何加密泉币的核心。除此之外,区块里还包孕有技巧信息,比如它的版本号,当前的光阴戳,以及上一个区块的哈希(Hash)。

在这篇文章中,我们所实现的并不是像比特币那样完备的区块链,而是一个简化版本的区块链,它只含有最基础的核心信息。差不多是这样:

type Block struct {

Timestamp int64

Data []byte

PrevBlockHash []byte

Hash []byte}

TImestamp 是当前的光阴戳(即,区块被创建的光阴),Data 是区块中包孕的代价信息,PrevBlockHash 存储的是上一个区块的哈希,而Hash 保存的是当前区块的哈希。在比特币的标配中,TImestamp、PrevBlockHash、Hash是区块的头部数据(Block headers),构成一个零丁的数据布局;而买卖营业记录(TransacTIons,在我们这个版本中便是 Data),是别的一个零丁的数据布局。而我们在这里为了简化,把数据布局混在了一路。

那我们若何谋略哈希呢?谋略哈希的要领是区块链的紧张特性之一,也恰是这个特点使得区块链如斯安然。关键在于,谋略哈希是一个谋略起来很艰苦的事情,它必要光阴,哪怕是在很快的谋略机上(这便是为什么人们要买比 CPU 谋略能力更刁悍 GPU 以致专门的 ASIC 芯片做矿机的 缘故原由)。这是有意如斯设计的,这么做的结果是,往区块链(数据库)里添加新的区块(数据)有必然的艰苦,以此包管一旦新的数据被加入,以后很难窜改。今后的文章里会进一步评论争论并实现这个机制。

现在呢,我们只必要罢区块里的各个字段关联起来,并在此根基上谋略出一个 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

}

就这么简单。

区块链(Blockchain)

现在,让我们来实现区块链。本色上来看,区块链只不过是一个特定布局的数据库,它是一个有序的,反向链接的列表(back-linked list)。这就意味着说,区块是按照插入的顺序排列的,每个区块都链接到上一个区块。这样的布局,使得应用者可以很快地在区块链中得到最新的区块,也可以很有效率地经由过程区块的哈希得到某个区块。

在 Golang 中,这种布局可以用数组(Array)与数图(Map) 实现:数组用来掩护有序哈希(在 Go 说话中,数组是有序的);数图(Map) 用来掩护 hash → block 对。不过,在我们的区块链原型中,我们只必要数组就可以了,由于我们暂时不必要经由过程哈希获取区块。

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)

}

这就完事儿了?或者……?

为了添加新的区块,我们必要一个已经存在的区块,可现在我们的区块链里面没有任何区块!于是,在任何区块链中,应该至少有一个区块,这第一个区块,被称为“开创块”(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()

}

}

输出结果是:

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

(竟然)竣工!

结论

我们创建了一个极简的区块链原型:它只不过是一个由区块构成的数组,每个区快链接指向上一个区块。当然,真正的区块链远比这个繁杂的多。在我们的区块链里,添加一个新区块异常快,异常轻易;然则在真正的区块链中添加一个新的区块必要更多的事情:在得到添加区块的容许之前要做很繁重的谋略才行(这个历程被称为工“作证实机制”,即,“Proof-of-Work”,POW)。并且,区块链是一个没有主权的散播式的数据库。是以,任何一个新的区块在被加入之前,必须颠末收集中其它介入者切实着实认与容许(这个机制被称为“共识机制”,“Consensus”)…… 还有,我们的区块链里,还没有任何买卖营业记录呢!

您可能还会对下面的文章感兴趣: