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() }