文章目录
项目结构 block.go blockchain.go server.go 封装接口供简单调用
向区块链中区块写入数据 读取区块链中的区块数据
项目结构
block.go
package core
import (
"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. Data
hashInBytes := sha256. Sum256 ( [ ] byte ( blockData) )
return hex. EncodeToString ( hashInBytes[ : ] )
}
func GenerateNewBlock ( preBlock Block, data string ) Block {
newBlock := Block{ }
newBlock. Index = preBlock. Index + 1
newBlock. PrevBlockHash = preBlock. Hash
newBlock. Timestamp = time. Now ( ) . Unix ( )
newBlock. Data = data
newBlock. Hash = calculateHash ( newBlock)
return newBlock
}
func GenerateGenesisBlock ( ) Block {
preBlock := Block{ }
preBlock. Index = - 1
preBlock. Hash = ""
return GenerateNewBlock ( preBlock, "Genesis Block" )
}
blockchain.go
package core
import (
"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 main
import (
"encoding/json"
"go-blockchain/core"
"io"
"net/http"
)
var blockchain * core. Blockchain
func 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, 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语言自己动手实现区块链
读取区块链中的区块数据
http://localhost:8888/blockchain/get