Go实现区块链(一)---基本原型

1.区块链数据结构图

图1-1

2.简易版区块结构 Block

//区块结构
type Block struct {
        //GO语言首字母大写外部可以访问
    Hase          []byte //hase值
    Data          []byte //交易数据
    PrevBlockHash []byte //存储前一个区块的Hase值
    Timestamp     int64  //生成区块的时间
}

3.区块体的Hash值的生成方式

采用sha256对区块体数据进行二次加密,从而构成区块链上要得到下一个区块的hash值,是要通过计算才能得出新的hash

Hash = sha256(Data+PrevBlockHash+Timestamp)
//生成区块hase值
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[:]
}

4.构造一个新的区块体函数方法

每次生成新的区块都要计算一下hash值。

//生成一个新的区块方法
func NewBlock(data string, prevBlockHash []byte) *Block{
    block := &Block{Timestamp:time.Now().Unix(), Data:[]byte(data), PrevBlockHash:prevBlockHash, Hash:[]byte{}}
    block.SetHash()
    return block
}

5.区块链Blockchian

区块链是一种==有序、反向链接链表==的数据结,构如图1-1。这意味着块按照插入顺序存储,并且每个块都链接到前一个块。该结构允许快速获取链中的最新块,并通过其哈希(有效)获取块。

在Golang中,这个结构可以通过使用数组和地图来实现:数组可以保持有序散列(数组在Go中排序),并且映射可以保持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)
}

6.创世块

我们知道区块链中必须有一个创世块,也就是我们数组中的第一个元素,下面分别在block和Blockchian将定义一个创世块的方法。

//创世块方法
func  NewGenesisBlock() *Block {
    return NewBlock("Genesis Block", []byte{})
}

// 创建创世块
func NewBlockchain() *Blockchain {
    //go语言&表示获取存储的内存地址
    return &Blockchain{[]*Block{NewGenesisBlock()}}
}

7.创建一个main演示区块查看区块信息

func main() {
    //创世块
    bc :=block.NewBlockchain()
    //添加第2块
    bc.AddBlock("Send 1 BTC to even")
    //添加第3块
    bc.AddBlock("Send 2 more BTC to even")
        //迭代数组里面的数据
    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: 865d72643b2e266ec4ec47613090cb98d1944f8bd388907dc4376332f06f4e21

Prev. hash: 865d72643b2e266ec4ec47613090cb98d1944f8bd388907dc4376332f06f4e21
Data: Send 1 BTC to even
Hash: fe7f424421604eed708a1276ae75f70521ecf355bb9a3c4400a7cc0565016d02

Prev. hash: fe7f424421604eed708a1276ae75f70521ecf355bb9a3c4400a7cc0565016d02
Data: Send 2 more BTC to even
Hash: fcd625b2c35ff8cbe24fda49a43a6c8cd2723a4275631ecc813025f6f10fbc87


Process finished with exit code 0

资料

推荐阅读更多精彩内容