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

这篇具有很好参考价值的文章主要介绍了【区块链】Go 实现简单区块链。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

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

(1)创建 Block
(2)创建 Blockchain
(3)创建 Http server

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

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

一、创建 Block

  • 创建 Block 文件
  • 创建 Block 结构体与相关函数
package core  
  
import (  
   "crypto/sha256"  
   "encoding/hex"   "time")  
  
type Block struct {  
   Index         int64  // 区块编号  
   Timestamp     int64  // 区块时间戳  
   PrevBlochHash string // 上一个区块哈希值  
   Hash          string // 当前区块哈希值  
  
   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/get
  • http://localhost:8888/blockchain/write?data=Send 1 BTC to Me

参数 data 的内容可自定义文章来源地址https://www.toymoban.com/news/detail-403033.html

// 网页显示效果
{
	"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"
		}
	]
}

到了这里,关于【区块链】Go 实现简单区块链的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【设计模式】使用 go 语言实现简单工厂模式

    最近在看《大话设计模式》,这本书通过对话形式讲解设计模式的使用场景,有兴趣的可以去看一下。 第一篇讲的是 简单工厂模式 ,要求输入两个数和运算符号,得到运行结果。 这个需求不难,难就难在类要怎么设计,才能达到可复用、维护性强、可拓展和灵活性高。 运

    2024年02月05日
    浏览(32)
  • Go 语言实现归并排序算法的简单示例(附上源码)

    以下是使用 Go 语言实现归并排序算法的简单示例: 在这个例子中, mergeSort 函数接收一个整数切片,使用递归的方式进行归并排序。 merge 函数用于合并两个已排序的切片。在 main 函数中,我们定义了一个示例数组,调用 mergeSort 函数对其进行排序,并输出结果。 归并排序算

    2024年01月21日
    浏览(29)
  • Go语言使用net/http实现简单登录验证和文件上传功能

         最近再看Go语言web编程,go语言搭建Web服务器,既可以用go原生的net/http包,也可以用gin/fasthttp/fiber等这些Web框架。本博客使用net/http模块编写了一个简单的登录验证和文件上传的功能,在此做个简单记录。 目录 1.文件目录结构 2.编译运行 3.用户登录  4.文件上传 5.mime/m

    2024年02月11日
    浏览(34)
  • 【微信小程序】如何获得自己当前的定位呢?本文利用逆地址解析、uni-app带你实现

    目录 前言 效果展示 一、在腾讯定位服务配置微信小程序JavaScript SDK 二、使用uni-app获取定位的经纬度 三、 逆地址解析,获取精确定位 四、小提示 在浏览器搜索腾讯定位服务,找到官方网站,利用微信或者其他账号注册登录,登录后如下图操作 点进去之后,可以看到如下图

    2024年01月19日
    浏览(66)
  • go语言--区块链学习(一)

    温馨跳转链接:模块二:go语言–区块链学习(二)-CSDN博客 1.1 密码介绍 1.1.1 为什么要加密 ? 保护隐私和数据安全:在信息传输过程中,不加密的数据可以被未经授权的人员截获和查看,这可能导致个人隐私泄露、商业机密被窃取或者敏感数据被篡改。通过加密数据,可以

    2024年01月21日
    浏览(34)
  • GO语言-生成区块链账户地址

    持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第19天,点击查看活动详情 为了收款方便,用户需要对外公布一个地址,这个地址其实是公钥经过一系列变化得来的。比如:比特币公钥到地址的变化过程,一个公钥经过SHA256+RIPEMD160两次叠加运算得到公钥

    2024年01月23日
    浏览(37)
  • Go语言Blockchain与区块链

    区块链技术是一种分布式、去中心化的数字账本技术,它允许多个节点共同维护一个共享的、有序的、不可篡改的数据库。区块链技术的核心概念是通过加密技术和分布式共识算法来确保数据的安全性、完整性和可靠性。 Go语言是一种静态类型、垃圾回收、并发简单的编程语

    2024年02月20日
    浏览(31)
  • 使用Go语言搭建区块链基础

    随着区块链技术的发展,越来越多的人开始关注并使用这一技术,其中,比特币和以太坊等区块链项目正在成为人们关注的焦点。而Go语言作为一种高效、简洁的编程语言,越来越多的区块链项目也选择使用Go语言来搭建其底层基础。本文将介绍如何使用Go语言搭建区块链的基

    2024年02月04日
    浏览(26)
  • GO语言凭什么是区块链的首选语言

    区块链的火热也带动了GO语言开发者的突增,那凭什么GO语言会成为最主要的区块链构建语言之一。我认为这得益于GO语言的性能、抽象度、简单性和现代性。并且,当下最成功、最流行的go-ethereum和Fabric都是使用GO语言实现的,在这两个的带领下,为了减少开发时间和成本,

    2024年01月15日
    浏览(28)
  • Go语言的Blockchain与区块链

    区块链技术是一种分布式、去中心化的数字账本技术,它允许多个节点在网络中共享和同步数据。区块链技术的核心概念是将数据以链式结构存储,每个数据块(block)包含前一个数据块的哈希值,形成一条链。这种结构使得数据的完整性和不可篡改性得到保障。 Go语言是一种静

    2024年04月10日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包