(1)

package main

import (
    "bytes"
    "crypto/sha256"
    "encoding/binary"
    "fmt"
    "log"
    "strconv"
    "time"
)

type Block struct {
    Height        int64
    PrevBlockHash []byte
    Data          []byte
    Timestamp     int64
    Hash          []byte
}

func (block *Block) SetHash() {

    //    1. Height []byte

    heightBytes := IntToHex(block.Height)

    fmt.Println("高度 => ", heightBytes)

    //  2. 将时间戳转[]byte

    // 2 ~ 36
    // 1528097970
    timeString := strconv.FormatInt(block.Timestamp, 2)

    fmt.Println("时间转化二进制 => ", timeString)
    timeBytes := []byte(timeString)

    fmt.Println(timeBytes)

    //  3. 拼接所有属性
    blockBytes := bytes.Join([][]byte{heightBytes, block.PrevBlockHash, block.Data, timeBytes}, []byte{})

    // 4. 生成Hash
    hash := sha256.Sum256(blockBytes)

    block.Hash = hash[:]
    fmt.Println("生成hash完成 => ", block.Hash)
}

type BlockChain struct {
    Blocks []*Block
}

//AddBlocktoChain 增加区块到链
func (blc *BlockChain) AddBlocktoChain(data string, height int64, prevHash []byte) {
    block := NewBlock(data, height, prevHash)
    blc.Blocks = append(blc.Blocks, block)
}

func main() {
    blc := CreateBlockchainWithGenesisBlock()
    blc.AddBlocktoChain("peter send bob 100$", blc.Blocks[len(blc.Blocks)-1].Height+1, blc.Blocks[len(blc.Blocks)-1].Hash)
    blc.AddBlocktoChain("bob send alice 150$", blc.Blocks[len(blc.Blocks)-1].Height+1, blc.Blocks[len(blc.Blocks)-1].Hash)
    blc.AddBlocktoChain("alice send bob 50$", blc.Blocks[len(blc.Blocks)-1].Height+1, blc.Blocks[len(blc.Blocks)-1].Hash)
    fmt.Println("区块高度 =>", blc.Blocks[len(blc.Blocks)-1].Height)
}

//NewBlock 创建新块
//参数:数据、高度、上一个的HASH值
func NewBlock(data string, height int64, prevBlockHash []byte) *Block {
    block := &Block{
        height,
        prevBlockHash,
        []byte(data),
        time.Now().Unix(),
        nil,
    }
    block.SetHash()
    return block
}

//CreateGenesisBlock 创建创世区块
func CreateGenesisBlock(data string) *Block {
    return NewBlock(data, 1, []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})
}

//CreateBlockchainWithGenesisBlock 创建带有创世区块的区块链头
func CreateBlockchainWithGenesisBlock() *BlockChain {
    genesisBlock := CreateGenesisBlock("Genesis data(创世块)...")
    fmt.Println("=> 创建genesis block...")
    return &BlockChain{[]*Block{genesisBlock}}
}

//IntToHex 将int64转换为字节数组
func IntToHex(num int64) []byte {
    buff := new(bytes.Buffer)
    err := binary.Write(buff, binary.BigEndian, num)
    if err != nil {
        log.Panic(err)
    }

    return buff.Bytes()
}
原文地址:https://www.cnblogs.com/tinaluo/p/14885235.html