下面簡單的描述區塊鏈的實現:
block.go
package main
import (
"time"
"crypto/sha256"
"bytes"
)
//定義塊結構
type Block struct{
Version int64
PrevBlockHash []byte
Hash []byte
TimeStamp int64
TargetBits int64
Nonce int64
MerKelRoot []byte
Data []byte
}
//設定創建塊的方法
func NewBlock(data string, prevBlockHash []byte) *Block{
block := &Block{
Version:1,
PrevBlockHash:prevBlockHash,
//Hash:
TimeStamp:time.Now().Unix(),
TargetBits:10,
Nonce:5,
MerKelRoot:[]byte{},
Data:[]byte(data),
}
block.SetHash() //設置區塊的哈希值
return block
}
// 添加哈希值
func (block *Block)SetHash(){
tmp := [][]byte{
//實現int類型轉換爲byte類型的工具函數
IntToByte(block.Version),
block.PrevBlockHash,
IntToByte(block.TimeStamp),
block.MerKelRoot,
IntToByte(block.Nonce),
block.Data,
}
//將區塊的各個字段鏈接成一個切片,使用【】byte{}進行鏈接,目的是避免污染源區塊的信息
data := bytes.Join(tmp,[]byte{})
//對區塊進行sha256哈希算法,返回值爲[32]byte數組,不是切片
hash := sha256.Sum256(data)
block.Hash = hash[:]//由數組轉換爲切片
}
// 創世塊的創建,它的錢一個去魁岸的哈希值爲空
func NewGenesisBlock() *Block{
return NewBlock("Genesis Block!",[]byte{})
}
blockchain.go
package main
import "os"
//定義區塊鏈條
type BlockChain struct{
blocks []*Block
}
// 創建區塊鏈,並且添加創世塊
func NewBlockChain() *BlockChain{
return &BlockChain{[]*Block{
NewGenesisBlock(),
}}
}
//添加區塊
func (bc *BlockChain)AddBlock(data string){
//簡單校驗
if len(bc.blocks) <= 0 {
os.Exit(1)
}
//根據上一區塊,創建新的區塊
lastblock := bc.blocks[len(bc.blocks)-1]
prevBlockHash := lastblock.Hash
block := NewBlock(data, prevBlockHash)
//添加到區塊鏈當中
bc.blocks = append(bc.blocks, block)
}
utils
package main
import (
"bytes"
"encoding/binary"
"fmt"
"os"
)
func IntToByte(num int64)[]byte{
var buffer bytes.Buffer
err := binary.Write(&buffer, binary.BigEndian, num)
//if err != nil{
// fmt.Println("IntToByte err occur:",err)
// os.Exit(1)
//}
CheckErr(err)
return buffer.Bytes()
}
func CheckErr(err error){
if err != nil{
fmt.Println("err occur:",err)
os.Exit(1)
}
}
main.go
package main
import "fmt"
func main(){
bc := NewBlockChain()
bc.AddBlock("班長轉給老師一枚比特幣")
bc.AddBlock("班長又轉給老師一枚比特幣")
for i, block := range bc.blocks{
fmt.Println("====block num:", i)
fmt.Printf("Data:%s\n", block.Data)
fmt.Println("Version:",block.Version)
fmt.Printf("PrevHash:%x\n",block.Version)
fmt.Printf("Hash:%x\n",block.TimeStamp)
fmt.Printf("TimeStamp:%d\n",block.TimeStamp)
fmt.Printf("MerKel:%x\n",block.MerKelRoot)
fmt.Printf("Nonce:%d\n",block.Nonce)
}
}
最後,在gopath路徑下,編譯運行查看效果。