当前位置: 首页 > article >正文

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

文章目录

    • 项目结构
      • 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, 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语言自己动手实现区块链

在这里插入图片描述

读取区块链中的区块数据

http://localhost:8888/blockchain/get

在这里插入图片描述


http://www.kler.cn/a/9274.html

相关文章:

  • Three.js教程:旋转动画、requestAnimationFrame周期性渲染
  • 基于html+css的盒子内容旋转
  • 【智能算法】蚁群算法及Matlab实现 —— TSP问题
  • CountDownLatch:Java中的同步工具
  • Python基础-03 语句
  • 数学分析:多元微积分1
  • 【每日随笔】社会上层与中层的博弈 ( 技术无关、没事别点进来看 | 社会上层 | 上层与中层的保护层 | 推荐学习的知识 )
  • chatGPT所在地区不支持怎么解决-需要下载ChatGPT吗
  • NGK BeCu8·11铜合金板材
  • ES6新特性--Set与Map与ES7新特性--空值运算符与?. 操作符
  • RuoYi若依项目部署实战
  • 自学大数据第14天NoSQL~MongoDB及其命令
  • Web 攻防之业务安全:Response状态值修改测试(修改验证码返回值为 true)
  • 【Kubernetes 企业项目实战】11、掌握 Kubernetes Kustomize 技术从入门到企业实战(下)
  • 蓝桥杯基础12:BASIC-3试题 字母图形
  • 从Hive源码解读大数据开发为什么可以脱离SQL、Java、Scala
  • 2023年PMP报考时间安排攻略!
  • ARM 编译器 Arm Compiler for Embedded 6 相关工具链简介
  • 内核dpc定时器
  • Python 虚拟环境迁移到其他电脑