区块链学习(三)区块链实例

1.计算哈希,创建 区块

package core

import (
   "crypto/sha256"
   "encoding/hex"
   "time"
)

type Block struct {
   Index        int64  // 区块编号
   Timestmp     int64  // 区块时间戳
   PreBolckHash string // 上一个区块的哈希值
   Hash         string // 当前区块哈希值
   Data         string // 区块数据
}

// 计算哈希
func CalculateHash(b Block) string {
   // 数据不允许修改
   // 把 数据 包含在hash运算的数值里面, ,任何一个模块数据的修改,都会导致区块链, 链式数据结构的破坏
   blockData := string(b.Index) + string(b.Timestmp) + string(b.PreBolckHash)
   HashInBytes := sha256.Sum256([]byte(blockData))
   return hex.EncodeToString(HashInBytes[:])
}

// 生成新区块
func GenerateNewBlock(preBlock Block, data string) Block {
   newBlock := Block{}
   // 新区块的index = 父区块的index+1
   newBlock.Index = preBlock.Index + 1
   // 哈希值 = 父区块的哈希值
   newBlock.PreBolckHash = preBlock.Hash
   // 新区块的时间戳,==当前时间
   newBlock.Timestmp = time.Now().Unix()
   newBlock.Data = data
   // 新区块的哈希 是计算得来的
   newBlock.Hash = CalculateHash(newBlock)
   return newBlock
}

// 生成创始区块
func GenerateGenesisBlock() Block {
   preBlock := Block{}
   preBlock.Index = -1
   preBlock.Timestmp = time.Now().Unix()
   preBlock.Hash = CalculateHash(preBlock)
   preBlock.Data = "Genesis Block(创始区块)"
   GenerateNewBlock(preBlock, "Genesis Block")
   return preBlock
}

 

链式数据

package core

import (
   "fmt"
   "log"
)

type Blockchain struct {
   // 数组
   Blocks []*Block
}

func NewBlockchain() *Blockchain {
   genesisBlock := GenerateGenesisBlock()
   blockchain := Blockchain{}
   blockchain.ApendBlock(&genesisBlock)
   return &blockchain
}

func (bc *Blockchain) SendData(data string) {
   proBlock := bc.Blocks[len(bc.Blocks)-1]
   newBlock := GenerateNewBlock(*proBlock, data)
   bc.ApendBlock(&newBlock)
}

func (bc *Blockchain) ApendBlock(newBlock *Block) {
   // 防止越界
   if len(bc.Blocks) == 0 {
      bc.Blocks = append(bc.Blocks, newBlock)
      return
   }
   if isValid(*newBlock, *bc.Blocks[len(bc.Blocks)-1]) {
      bc.Blocks = append(bc.Blocks, newBlock)
   } else {
      log.Fatal("invalid block")
   }
}

func (bc *Blockchain) Print() {
   // 下划线表示赋值是忽略的
   for _, block := range bc.Blocks {
      fmt.Printf("Index: %d\n", block.Index)
      fmt.Printf("Prev.Hash: %s\n", block.PreBolckHash)
      fmt.Printf("Curr.Hash: %s\n", block.Hash)
      fmt.Printf("Data: %s\n", block.Data)
      fmt.Printf("Timestmp: %d\n", block.Timestmp)
      fmt.Println("")
   }
}

func isValid(newBlock Block, oldBlock Block) bool {
   if newBlock.Index-1 != oldBlock.Index {
      return false
   }
   if newBlock.PreBolckHash != oldBlock.Hash {
      return false
   }
   if CalculateHash(newBlock) != newBlock.Hash {
      return false
   }
   return true
}

 

启动类

package main

import "./core"

func main() {
   bc := core.NewBlockchain()
   bc.SendData("Send 1 BTC to jacky")
   bc.SendData("Send 1 EOS to jacky")
   bc.Print()
}
上一篇:opendir函数和readdir函数内涵及用法


下一篇:linux磁盘分区