项目主要有几本部分组成
1,创建block
2, 创建blockchain、
3,创建http server
创建block 代码
package core
import (
"crypto/sha256"
"encoding/hex"
"time"
)
type Block struct {
Index int64 // 区块编号
Timestamp int64 //时间戳
Preblockhash string //上一个区块的hash 值
Hash string // 当前区块的hash 值
Data string // 区块数据
}
func calculateHash(b *Block) string {
blockdata:=string(b.Index)+string(b.Timestamp)+b.Preblockhash
hashinbytes:=sha256.Sum256([] byte (blockdata)) //字节数组
return hex.EncodeToString(hashinbytes [:])
}
func Generatenewblock(preblock *Block,data string) *Block{
newblock:=&Block{}
newblock.Index=preblock.Index+1
newblock.Timestamp=time.Now().Unix()
newblock.Preblockhash=preblock.Hash
newblock.Hash=calculateHash(newblock)
newblock.Data=data
return newblock
}
func GenerateGenesisBlock()*Block {
preblock := &Block{}
preblock.Index = -1
preblock.Hash = ""
return Generatenewblock(preblock,"genesis block")
}
创建blockchain
package core
import (
"fmt"
"log"
)
type Blockchain struct{
Block []*Block
}
func Newblockchain() *Blockchain {
genesisblock:=GenerateGenesisBlock()
Blockchain :=Blockchain{}
Blockchain.AppendBlock(genesisblock)
return &Blockchain
}
func (bc *Blockchain) Senddata(data string){
preblock :=bc.Block[len(bc.Block)-1]
newblock:=Generatenewblock(preblock,data)
bc.AppendBlock(newblock)
}
func (bc *Blockchain)AppendBlock (newblock *Block){
if len(bc.Block)==0 {
bc.Block=append(bc.Block,newblock)
return
}
if isvalid(newblock, bc.Block[len(bc.Block)-1]){
bc.Block = append(bc.Block,newblock)
}else {
log.Fatal("invalid block")
}
}
//打印区块链的数据
func (bc *Blockchain) Print(){
for _,block:=range bc.Block{
fmt.Printf("index:%d\n",block.Index)
fmt.Printf("pre.hash:%s\n",block.Preblockhash)
fmt.Printf("curr.hash:%s\n",block.Hash)
fmt.Printf("data:%s\n",block.Data)
fmt.Printf("Timestamp:%d\n",block.Timestamp)
}
}
func isvalid(newblock *Block,oldblock *Block) bool{
if newblock.Index-1!=oldblock.Index{
return false
}
if newblock.Preblockhash!=oldblock.Hash{
return false
}
if calculateHash(newblock)!=newblock.Hash{
return false
}
return true
}
注:1.fmt.Printf(“Timestamp:%d\n”,block.Timestamp) 是数字形式输出,%s 以字符串的形式输出。2.显示无效block ,可能代码中block.哈希函数又问题,或者引用。
####构建http server 对外暴露读写接口
package main
import (
"Blockchain/core"
"encoding/json"
"io"
"net/http"
)
var blockchain *core.Blockchain
func run(){
http.HandleFunc("/blockchain/get",blockchaingethandler)
http.HandleFunc("/blockchain/write",blockchainwritehandler)
http.ListenAndServe("localhost:8888",nil)
}
func blockchaingethandler(w http.ResponseWriter,r *http.Request){
bytes,error:= json.Marshal(blockchain)
if error!=nil{
http.Error(w,error.Error(),http.StatusInternalServerError)
return
}
io.WriteString(w,string(bytes))
}
func blockchainwritehandle(w http.ResponseWriter,r *http.Request){
blockdata:=r.URL.Query().Get("data")
blockchain.Senddata(blockdata)
blockchaingethandler(w,r)
}
func main(){
blockchain=core.Newblockchain()
run()
}