创建自己区块链之v1

下面简单的描述区块链的实现:

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路径下,编译运行查看效果。

猜你喜欢

转载自blog.51cto.com/13914991/2308615
v1
今日推荐