900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > 【区块链】Go 实现简单区块链

【区块链】Go 实现简单区块链

时间:2018-12-08 06:08:07

相关推荐

【区块链】Go 实现简单区块链

本文主要利用 Go 语言对区块链模型进行了简单的实现,通过 GoLand 创建链式结构和一个简单的 http server,对外暴露读写接口,运行 rpc 并以地址访问形式向区块链发送数据和读取数据。

简单区块链的实现大致步骤分为:

(1)创建 Block

(2)创建 Blockchain

(3)创建 Http server

在实现之前,首先通过 GoLand 创建 blockchainDemo 项目,并建立对应的Block.goBlockchain.go以及Server.go文件,具体的目录如下。

一、创建 Block

创建 Block 文件创建 Block 结构体与相关函数

package core import ( "crypto/sha256" "encoding/hex" "time") type Block struct {Index int64 // 区块编号 Timestampint64 // 区块时间戳 PrevBlochHash string // 上一个区块哈希值 Hashstring // 当前区块哈希值 Data string // 区块数据 } // calculateHash 计算哈希值 func calculateHash(b Block) string {blockData := string(b.Index) + string(b.Timestamp) + b.PrevBlochHash + b.Data hashInBytes := sha256.Sum256([]byte(blockData)) return hex.EncodeToString(hashInBytes[:]) } // GenerateNewBlock 创建新区块 func GenerateNewBlock(preBlock Block, data string) Block {newBlock := Block{} newBlock.Index = preBlock.Index + 1 newBlock.PrevBlochHash = preBlock.Hash newBlock.Timestamp = time.Now().Unix() newBlock.Data = data newBlock.Hash = calculateHash(newBlock) return newBlock } // GenerateGenesisBlock 创建世纪区块 func GenerateGenesisBlock() Block {preBlock := Block{} preBlock.Index = -1 preBlock.Hash = "" return GenerateNewBlock(preBlock, "Genesis Block") }

这里需要注意的是,在创建世纪区块时,考虑到对 GenerateNewBlock 函数的复用,因此,创建了一个 preBlock 来辅助世纪块的创建,实际区块链上世纪块前面不存在其他区块,且世纪块以 0 作为索引。

二、创建 Blockchain

创建 Blockchain 文件创建 Blockchain 结构体及相关方法

package core import ( "fmt" "log") type Blockchain struct {Blocks []*Block } // CreateBlockchain 创建区块链 func CreateBlockchain() *Blockchain {genesisBlock := GenerateGenesisBlock() blockchain := Blockchain{} blockchain.AppendBlock(&genesisBlock) return &blockchain } // SendData 向区块链添加数据 func (bc *Blockchain) SendData(data string) {preBlock := bc.Blocks[len(bc.Blocks)-1] newBlock := GenerateNewBlock(*preBlock, data) bc.AppendBlock(&newBlock) } // AppendBlock 向区块链添加新区块 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 isValid(newBlock Block, oldBlock Block) bool {if newBlock.Index-1 != oldBlock.Index {return false } if newBlock.PrevBlochHash != oldBlock.Hash {return false } if calculateHash(newBlock) != newBlock.Hash {return false } return true } // Print 对区块链上的区块内容进行打印 func (bc *Blockchain) Print() {for _, block := range bc.Blocks {fmt.Printf("Index: %d\n", block.Index) fmt.Printf("Prev.Hash: %s\n", block.PrevBlochHash) fmt.Printf("Curr.Hash: %s\n", block.Hash) fmt.Printf("Data: %s\n", block.Data) fmt.Printf("Timestamp: %d\n", block.Timestamp) } }

三、创建 Http server

创建 http server提供 API 访问接口

package main import ( "blockchainDemo/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, err := json.Marshal(blockchain) if err != nil {http.Error(w, err.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.CreateBlockchain() run() }

四、模型测试

在 GoLand 上运行 http server,从代码中可知监听端口为 8888,因此,读写操作对应的地址是:

http://localhost:8888/blockchain/gethttp://localhost:8888/blockchain/write?data=Send 1 BTC to Me

参数 data 的内容可自定义

// 网页显示效果{"Blocks":[{"Index":0,"Timestamp":1674227301,"PrevBlochHash":"","Hash":"90d7d6d9adc8a6dd4eca1e30d8c1a8556a8e3e508da81f30a9e520c2ee7124b0","Data":"Genesis Block"},{"Index":1,"Timestamp":1674227338,"PrevBlochHash":"90d7d6d9adc8a6dd4eca1e30d8c1a8556a8e3e508da81f30a9e520c2ee7124b0","Hash":"1a7c54ce0eaba45d5591640925405d90e74d9da5fa919b4e6eefa2447b2a4fb0","Data":"Send 1 BTC to Me"}]}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。