用Go语言构建自己的区块链
2019-01-06 本文已影响0人
百炼
date[2019-01-06]
注意:
当main包里面有多个go文件时,使用go build *.go
运行,当然最好的办法是main
包里面就保留一个go
文件。
用Go语言构建自己的区块链
package blockchain_core
import (
"crypto/sha256"
"encoding/hex"
"time"
)
type Block struct {
Index int64 //区块编号
Timestamp int64 //区块时间
PrevBlockHash string //上一个区块的哈希值
Hash string //当前区块的哈希值
Data string //区块数据
}
func calculateHash(b Block) string {
blockData := string(b.Index) + string(b.Timestamp) + b.PrevBlockHash + b.Data
hashInBytes := sha256.Sum256([]byte(blockData))
return hex.EncodeToString(hashInBytes[:])
}
func GenerateNewBlock(preBlock Block, data string) Block {
newBlock := Block{}
newBlock.Index = preBlock.Index + 1
newBlock.PrevBlockHash = preBlock.Hash
newBlock.Timestamp = time.Now().Unix()
newBlock.Data = data
newBlock.Hash = calculateHash(newBlock)
return newBlock
}
func GenerateGenesisBlock() Block {
preBlock := Block{}
preBlock.Index = -1
preBlock.Hash = ""
return GenerateNewBlock(preBlock, "Genesis Block")
}
package blockchain_core
import (
"fmt"
"log"
)
type Blockchain struct {
Blocks []*Block
}
func (bc *Blockchain) Print() {
for _, block := range bc.Blocks {
fmt.Printf("Index:%d\n", block.Index)
fmt.Printf("Prev.Hash:%s\n", block.PrevBlockHash)
fmt.Printf("Curr.Hash:%s\n", block.Hash)
fmt.Printf("Data: %s\n", block.Data)
fmt.Printf("Data: %d\n\n", block.Timestamp)
}
}
func NewBlockchain() *Blockchain {
genesisBlock := GenerateGenesisBlock()
blockchain := Blockchain{}
blockchain.AppendBlock(&genesisBlock)
return &blockchain
}
func (bc *Blockchain) SendData(data string) {
preBlock := bc.Blocks[len(bc.Blocks)-1]
newBlock := GenerateNewBlock(*preBlock, data)
bc.AppendBlock(&newBlock)
}
func (bc *Blockchain) AppendBlock(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 isValid(newBlock, oldBlock Block) bool {
if newBlock.Index-1 != oldBlock.Index {
return false
}
if newBlock.PrevBlockHash != oldBlock.Hash {
return false
}
if calculateHash(newBlock) != newBlock.Hash {
return false
}
return true
}
package main
import "blockchain.core"
func main() {
bc := blockchain_core.NewBlockchain()
bc.SendData("Send 1 BTC to Jacky")
bc.SendData("Send 1 EOS to Jack")
bc.Print()
}