go 创建简单的区块链

项目主要有几本部分组成

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()

}

在这里插入图片描述

阅读更多
换一批

没有更多推荐了,返回首页