> 文章列表 > Fabric 超级账本学习【9】基于Go语言自己手动实现简单区块链

Fabric 超级账本学习【9】基于Go语言自己手动实现简单区块链

Fabric 超级账本学习【9】基于Go语言自己手动实现简单区块链

文章目录

    • 项目结构
      • block.go
      • blockchain.go
      • server.go 封装接口供简单调用
    • 区块链中区块写入数据
    • 读取区块链中的区块数据

项目结构

Fabric 超级账本学习【9】基于Go语言自己手动实现简单区块链

block.go

package coreimport ("crypto/sha256""encoding/hex""time"
)type Block struct {Index         int64  // 区块编号Timestamp     int64  // 区块时间戳PrevBlockHash string // 上一个区块哈希值Hash          string // 当前区块哈希Data          string // 区块数据
}func calculateHash(b Block) string {blockData := string(b.Index) + string(b.Timestamp) + b.PrevBlockHash + b.DatahashInBytes := sha256.Sum256([]byte(blockData))return hex.EncodeToString(hashInBytes[:])
}func GenerateNewBlock(preBlock Block, data string) Block {newBlock := Block{}newBlock.Index = preBlock.Index + 1newBlock.PrevBlockHash = preBlock.HashnewBlock.Timestamp = time.Now().Unix()newBlock.Data = datanewBlock.Hash = calculateHash(newBlock)return newBlock
}func GenerateGenesisBlock() Block {preBlock := Block{}preBlock.Index = -1preBlock.Hash = ""return GenerateNewBlock(preBlock, "Genesis Block")
}

blockchain.go

package coreimport ("fmt""log"
)type Blockchain struct {Blocks []*Block
}func NewBlockchain() *Blockchain {genesisBlock := GenerateGenesisBlock()blockchain := Blockchain{}blockchain.AppendBlock(&genesisBlock)return &blockchain
}func (bc *Blockchain) SendData(data string) {preBlock := bc.Blocks[len(bc.Blocks)-1]newBlock := GenerateNewBlock(*preBlock, data)bc.AppendBlock(&newBlock)
}func (bc *Blockchain) AppendBlock(newBlock *Block) {if len(bc.Blocks) == 0 {bc.Blocks = append(bc.Blocks, newBlock)return}if isValid(*newBlock, *bc.Blocks[len(bc.Blocks)-1]) {bc.Blocks = append(bc.Blocks, newBlock)} else {log.Fatal("invalid block")}
}func (bc *Blockchain) Print() {for _, block := range bc.Blocks {fmt.Printf("Index: %d\\n", block.Index)fmt.Printf("PrevHash: %s\\n", block.PrevBlockHash)fmt.Printf("CurrHash: %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.PrevBlockHash != oldBlock.Hash {return false}if calculateHash(newBlock) != newBlock.Hash {return false}return true
}

server.go 封装接口供简单调用

package mainimport ("encoding/json""go-blockchain/core""io""net/http"
)var blockchain *core.Blockchainfunc run() {http.HandleFunc("/blockchain/get", blockchainGetHandler)http.HandleFunc("/blockchain/write", blockchainWriteHandler)http.ListenAndServe("localhost:8080", nil)
}func blockchainGetHandler(w http.ResponseWriter, r *http.Request) {//bytes, err := json.MarshalIndent(Blockchain, "", "  ")bytes, error := json.Marshal(blockchain)if error != nil {http.Error(w, error.Error(), http.StatusInternalServerError)return}io.WriteString(w, string(bytes))
}func blockchainWriteHandler(w http.ResponseWriter, r *http.Request) {blockData := r.URL.Query().Get("data")blockchain.SendData(blockData)blockchainGetHandler(w, r)
}func main() {blockchain = core.NewBlockchain()run()
}

向区块链中区块写入数据

http://localhost:8888/blockchain/write?data=Fabric 超级账本学习【9】基于Go语言自己动手实现区块链

Fabric 超级账本学习【9】基于Go语言自己手动实现简单区块链

读取区块链中的区块数据

http://localhost:8888/blockchain/get

Fabric 超级账本学习【9】基于Go语言自己手动实现简单区块链

搞笑GIF图片