下面简单的描述区块链的实现:
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路径下,编译运行查看效果。
原文地址:http://blog.51cto.com/13914991/2308615
时间: 2024-10-07 22:12:41