1. 程式人生 > >創建區塊鏈之v1

創建區塊鏈之v1

its != time ret type pen truct prev 函數

下面簡單的描述區塊鏈的實現:

block.go

package main

import (
    "time"
    "crypto/sha256"
    "bytes"
)

//定義塊結構
type Block struct{
    Version int64
    PrevBlockHash []byte
    Hash []byte
    TimeStamp int64
    TargetBits  int64
    Nonce int64
    MerKelRoot []byte

    Data []byte
}

//設定創建塊的方法
func NewBlock(data string, prevBlockHash []byte) *Block{
    block := &Block{
        Version:1,
        PrevBlockHash:prevBlockHash,
        //Hash:
        TimeStamp:time.Now().Unix(),
        TargetBits:10,
        Nonce:5,
        MerKelRoot:[]byte{},
        Data:[]byte(data),
    }
    block.SetHash() //設置區塊的哈希值
    return block
}

// 添加哈希值
func (block *Block)SetHash(){
    tmp := [][]byte{
        //實現int類型轉換為byte類型的工具函數
        IntToByte(block.Version),
        block.PrevBlockHash,
        IntToByte(block.TimeStamp),
        block.MerKelRoot,
        IntToByte(block.Nonce),
        block.Data,
    }
    //將區塊的各個字段鏈接成一個切片,使用【】byte{}進行鏈接,目的是避免汙染源區塊的信息
    data := bytes.Join(tmp,[]byte{})

    //對區塊進行sha256哈希算法,返回值為[32]byte數組,不是切片
    hash := sha256.Sum256(data)
    block.Hash = hash[:]//由數組轉換為切片
}

// 創世塊的創建,它的錢一個去魁岸的哈希值為空
func NewGenesisBlock() *Block{
    return NewBlock("Genesis Block!",[]byte{})
}

blockchain.go

package main

import "os"

//定義區塊鏈條
type  BlockChain struct{
    blocks []*Block
}

// 創建區塊鏈,並且添加創世塊
func NewBlockChain() *BlockChain{
    return &BlockChain{[]*Block{
        NewGenesisBlock(),
    }}
}

//添加區塊
func (bc *BlockChain)AddBlock(data string){
    //簡單校驗
    if len(bc.blocks) <= 0 {
        os.Exit(1)
    }

    //根據上一區塊,創建新的區塊
    lastblock := bc.blocks[len(bc.blocks)-1]
    prevBlockHash := lastblock.Hash
    block := NewBlock(data, prevBlockHash)

    //添加到區塊鏈當中
    bc.blocks = append(bc.blocks, block)
}

utils

package main

import (
    "bytes"
    "encoding/binary"
    "fmt"
    "os"
)

func IntToByte(num int64)[]byte{
    var buffer  bytes.Buffer
    err := binary.Write(&buffer, binary.BigEndian, num)
    //if err != nil{
    //  fmt.Println("IntToByte err occur:",err)
    //  os.Exit(1)
    //}
    CheckErr(err)
    return buffer.Bytes()
}

func CheckErr(err error){
    if err != nil{
        fmt.Println("err occur:",err)
        os.Exit(1)
    }
}

main.go

package main

import "fmt"

func main(){
    bc := NewBlockChain()
    bc.AddBlock("班長轉給老師一枚比特幣")
    bc.AddBlock("班長又轉給老師一枚比特幣")

    for i, block := range bc.blocks{
        fmt.Println("====block num:", i)
        fmt.Printf("Data:%s\n", block.Data)
        fmt.Println("Version:",block.Version)

        fmt.Printf("PrevHash:%x\n",block.Version)
        fmt.Printf("Hash:%x\n",block.TimeStamp)
        fmt.Printf("TimeStamp:%d\n",block.TimeStamp)
        fmt.Printf("MerKel:%x\n",block.MerKelRoot)
        fmt.Printf("Nonce:%d\n",block.Nonce)

    }

}

最後,在gopath路徑下,編譯運行查看效果。

創建區塊鏈之v1