1.新建文件夹命名为blockchain,在此文件夹下分别创建两个文件一个为block.go另一个为chain.go如下图所示:
2.写入代码:
block.go
package blockchainimport ("bytes""crypto/sha256""encoding/gob""log""strconv""time"
)type Block struct {Index int64TimeStamp int64Data []bytePrevBlockHash []byteHash []byte
}func (b *Block) setHash() {timestamp := []byte(strconv.FormatInt(b.TimeStamp, 10))index := []byte(strconv.FormatInt(b.Index, 10))headers := bytes.Join([][]byte{timestamp, index, b.Data, b.PrevBlockHash}, []byte{})hash := sha256.Sum256(headers)b.Hash = hash[:]
}
func (b *Block) SerializeToBytes() []byte {var result bytes.Bufferencoder := gob.NewEncoder(&result)err := encoder.Encode(b)if err != nil {log.Panic(err)}return result.Bytes()}
func (b *Block) DeserializeFromBytes(d []byte) *Block {var block Blockdecoder := gob.NewDecoder(bytes.NewReader(d))err := decoder.Decode(&block)if err != nil {log.Panic(err)}return &block
}
func NewBlock(index int64, data, prevBlockHash []byte) *Block {block := &Block{index, time.Now().Unix(), data, prevBlockHash, []byte{}}block.setHash() //设置当前区块Hashreturn block
}// NewGenesisBlock 生成创世区块,区块链第一个结点
func NewGenesisBlock() *Block {return NewBlock(0, []byte("first block"), []byte{})
}
chain.go
package blockchain
// Blockchain 区块链结构定义
type Blockchain struct {
Blocks []*Block
}
// AddBlock 添加一个区块到区块链,上链
func (bc *Blockchain) AddBlock(data string) {
prevBlock := bc.Blocks[len(bc.Blocks)-1]
newBlock := NewBlock(prevBlock.Index+1, []byte(data), prevBlock.Hash)
bc.Blocks = append(bc.Blocks, newBlock)
}
// NewBlockchain 生成一个新的区块链实例
func NewBlockchain() *Blockchain {
return &Blockchain{[]*Block{NewGenesisBlock()}}
}
3.在外部main.go中调用blockchain这个包
package mainimport ("block/blockchain""fmt"
)func main() {fmt.Println("go语言最简区块链原理测试")fmt.Println("_____________________________")bc := blockchain.NewBlockchain()bc.AddBlock("这是第一个区块的内容")bc.AddBlock("这是第二个区块的内容")bc.AddBlock("某班级上课;202x年x月x日,实到xx人")for _, block := range bc.Blocks {fmt.Printf("Index :%d\n", block.Index)fmt.Printf("TimeStamp: %d\n", block.TimeStamp)fmt.Printf("Data: %s\n", block.Data)fmt.Printf("Hash: %x\n", block.Hash)fmt.Printf("PrevHash: %x\n", block.PrevBlockHash)fmt.Println("_____________________________")}
}
运行结果