block.go
package main
import (
"time"
"bytes"
"crypto/sha256"
)
type Block struct {
//版本
Version int64
//前区块的哈希值
PrevBlockHash []byte
//当前区块的哈希值,为了简化代码
Hash []byte
//梅克尔根
MerKelRoot []byte
//时间戳
TimeStamp int64
//难度值
Bits int64
//随机值
Nonce int64
//交易信息
Data []byte
}
func NewBlock(data string,prevBlockHash []byte) *Block{
var block Block
block = Block {
Version:1,
PrevBlockHash:prevBlockHash,
MerKelRoot: []byte{},
TimeStamp:time.Now().Unix(),
Bits:1,
Nonce:1,
Data:[]byte(data)}
block.SetHash()
return &block
}
func (block *Block)SetHash(){
tmp := [][]byte{
IntToByte(block.Version),
block.PrevBlockHash,
block.MerKelRoot,
IntToByte(block.TimeStamp),
IntToByte(block.Bits),
IntToByte(block.Nonce),
block.Data}
data := bytes.Join(tmp,[]byte{})
hash := sha256.Sum256(data)
block.Hash = hash[:]
}
func NewGenesisBlock() *Block{
return NewBlock("Genesis Block",[]byte{})
}
blockChain.go
package main
type BlockChain struct {
blocks []*Block
}
func NewBlockChain() *BlockChain{
block := NewGenesisBlock()
return &BlockChain{blocks:[]*Block{block}}
}
func (bc *BlockChain)AddBlock(data string){
preBlockHash := bc.blocks[len(bc.blocks)-1].Hash
block := NewBlock(data,preBlockHash)
bc.blocks = append(bc.blocks,block)
}
utils.go
package main
import (
"encoding/binary"
"bytes"
"os"
"fmt"
)
func IntToByte(num int64) []byte{
//func Write(w io.Writer, order ByteOrder, data interface{}) error {
var buffer bytes.Buffer
err := binary.Write(&buffer, binary.BigEndian, num)
CheckErr("IntToBye", err)
return buffer.Bytes()
}
func CheckErr(pos string, err error) {
if err != nil {
fmt.Println("error , pos :", pos, err)
os.Exit(1)
}
}
main.go
package main
import "fmt"
func main(){
bc := NewBlockChain()
bc.AddBlock("A send B 1 btc")
bc.AddBlock("B send C 1 btc")
for _,block :=range bc.blocks{
fmt.Printf("version:",block.Version)
fmt.Printf("preBlockHash",block.PrevBlockHash)
fmt.Printf("Hsah: %x\n",block.Hash)
fmt.Printf("data: %s\n",block.Data)
}
}