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