go语言写的案例
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()
}