go语言区块链实战实现简单的区块与区块链

 更新时间:2021年10月29日 15:07:49   作者:小生凡一  
这篇文章主要为大家介绍了go语言区块链的实战学习,来实现简单的区块与区块链示例过程,有需要的朋友可以借鉴参考下,希望能够有所帮助

区块链实战

字节 字段 说明
4 版本 区块版本号,表示本区块遵守的验证规则
32 父区块头哈希值 前一区块的Merkle树根的哈希值,同样采取SHA256计算
32 Merkle根 该区块中交易的Merkle树根的哈希值,同样采用SHA256计算
4 时间戳 该区块产生的近似时间,精确到秒的UNIX时间戳,必须严格大于前11各区块的时间的中值,同时全节点也会拒接那些超过自己两个小时的时间戳的区块
4 难度目标 该区块工作量证明算法的难度目标,已经使用特定算法编码
4 Nonce 未来找到满足难度目标所设定的随机数,为了解决32为随机数在算力飞升的情况下不够用的问题,规定时间戳和coinbase交易信息均改变,以此扩展nonce的位数

注意:区块不存储hash值,节点接受区块后独立计算并存储在本地。

Version 1

区块相关:

​ 1.定义一个区块的结构Block

​ a.区块头:6个字段

​ b.区块体:字符串表示data

2.提供一个创建区块的方法

​ NewBlock(参数)

区块链相关

定义一个区块链结构BlockChain

​ Block数组

提供一个创建BlockChain()的方法

​ NewBlockChain()

提供一个添加区块的方法

​ AddBlock(参数)

block.go文件

package main
import (
	"bytes"
	"crypto/sha256"
	"time"
)
/*
1.定义一个区块的结构Block
​a.区块头:6个字段
​b.区块体:字符串表示data
*/
//区块
type Block struct {
	Version int64   //版本
	PerBlockHash []byte //前一个区块的hash值
	Hash []byte //当前区块的hash值,是为了简化代码
	MerKelRoot []byte  //梅克尔根
	TimeStamp int64  //时间抽
	Bits int64  //难度值
	Nonce int64 //随机值
//区块体
	Data []byte  //交易信息
}

/*
提供一个创建区块的方法
NewBlock(参数)
*/
func NewBlock(data string ,prevBlockHash []byte) *Block {
	var block Block
	block = Block{
		Version:      1,
		PerBlockHash: prevBlockHash,
		//Hash:         []byte{},   	//区块不存储hash值,节点接受区块后独立计算并存储在本地。
		MerKelRoot:   []byte{},
		TimeStamp:    time.Now().Unix(),
		Bits:         1,
		Nonce:        1,
		Data:         []byte(data),
	}
	block.SetHash()  //填充Hash
	return &block
}
func (block *Block) SetHash() {
	// 源码里面是要传二维切片 func Join(s [][]byte, sep []byte) []byte
	tmp :=[][]byte{
		IntToByte(block.Version),
		block.PerBlockHash,
		block.MerKelRoot,
		IntToByte(block.TimeStamp),
		IntToByte(block.Bits),
		IntToByte(block.Nonce),
	}
	data:=bytes.Join(tmp,[]byte{})    //之后再计算hash
	hash := sha256.Sum256(data)
	block.Hash = hash[:]  //变切片
}
//创始块
func NewGensisBlock() *Block{
	return NewBlock("Genesis Block!",[]byte{})
}

blockChain.go文件

package main
/*
1. 定义一个区块链结构BlockChain
   Block数组
*/
type BlockChain struct {
   blocks []*Block
}
/*
2. 提供一个创建BlockChain()的方法
   NewBlockChain()
*/
func NewBlockChain() *BlockChain {
   block := NewGensisBlock()
   return &BlockChain{blocks:[]*Block{block}}  //创建只有一个元素的区块链,初始化
}
/*
3. 提供一个添加区块的方法
   AddBlock(参数)
*/
func (bc *BlockChain)AddBlock(data string)  {
   PerBlockHash := bc.blocks[len(bc.blocks)-1].Hash  //这一个区块的哈希是前一块的哈希值
   block := NewBlock(data,PerBlockHash)
   bc.blocks = append(bc.blocks,block)
}

utils.go文件

package main

import (
   "bytes"
   "encoding/binary"
   "fmt"
   "os"
)

func IntToByte(num int64) []byte {
   //func Write(w io.Writer, order ByteOrder, data interface{}) error {
   var buffer bytes.Buffer
   err := binary.Write(&buffer, binary.BigEndian, num)
   CheckErr("IntToByte",err)
   return buffer.Bytes()
}

func CheckErr(position string,err error) {
   if err != nil {
      fmt.Println("error ,pos:",position,err)
      os.Exit(1)
   }
}

main.go文件

package main
import "fmt"
func main() {
   bc := NewBlockChain()
   bc.AddBlock("A send B 1BTC")
   bc.AddBlock("B send C 1BTC")
   for _,block := range bc.blocks {
      fmt.Printf("Version : %d\n",block.Version)
      fmt.Printf("PerBlockHash : %x\n",block.PerBlockHash)
      fmt.Printf("Hash : %x\n",block.Hash)
      fmt.Printf("MerKelRoot : %x\n",block.MerKelRoot)
      fmt.Printf("TimeStamp : %d\n",block.TimeStamp)
      fmt.Printf("Bits : %d\n",block.Bits)
      fmt.Printf("Nonce : %d\n",block.Nonce)
      fmt.Printf("Data : %s\n",block.Data)
   }
}

执行结果

以上就是go语言区块链实战实现简单的区块与区块链的详细内容,更多关于go语言实现区块与区块链的资料请关注脚本之家其它相关文章!

相关文章

  • 提升编程技能:学习如何在Go语言中正确格式化时间

    提升编程技能:学习如何在Go语言中正确格式化时间

    想知道如何在Go语言中轻松地格式化时间吗?别再浪费时间了!本文将带你快速入门,让你的代码更加优雅高效,快来学习吧!
    2024-01-01
  • 基于Golang实现Excel表格的导入导出功能

    基于Golang实现Excel表格的导入导出功能

    最近项目开发中有涉及到Excel的导入与导出功能,特别是导出表格时需要特定的格式,所以本文给大家介绍了基于Golang实现Excel表格的导入导出功能,文中通过代码示例和图文介绍的非常详细,需要的朋友可以参考下
    2023-12-12
  • 深入了解Golang中的格式化输出

    深入了解Golang中的格式化输出

    fmt是Go语言中用于控制文本输出的常用标准库,文中将通过示例详细讲解一下Go语言中不同形式的格式化输出,感兴趣的小伙伴可以了解一下
    2022-11-11
  • Go语言协程处理数据有哪些问题

    Go语言协程处理数据有哪些问题

    协程(coroutine)是Go语言中的轻量级线程实现,由Go运行时(runtime)管理。本文为大家详细介绍了Go中的协程,协程不需要抢占式调度,可以有效提高线程的任务并发性,而避免多线程的缺点
    2023-02-02
  • Go语言切片常考的面试真题解析

    Go语言切片常考的面试真题解析

    了解最新的Go语言面试题型,让面试不再是难事,下面这篇文章主要给大家介绍了关于Go语言切片面试常考的一些问题,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-02-02
  • 总结Go语言中defer的使用和注意要点

    总结Go语言中defer的使用和注意要点

    Go语言中的defer关键字实现比较特殊的功能,这篇文章给大家总结了关于Go语言中defer的使用和注意要点,有需要的朋友们可以参考借鉴,下面来一起看看吧。
    2016-09-09
  • Go 1.22中的for循环新特性详解

    Go 1.22中的for循环新特性详解

    在 Go 语言中,for 循环是实现迭代的主要方式,Go 中的 for 循环非常灵活,有多种使用方式,本文将给大家详细的介绍一下Go 1.22中的for循环新特性,感兴趣的朋友可以参考下
    2024-02-02
  • GO中优雅编码与降低圈复杂度详析

    GO中优雅编码与降低圈复杂度详析

    Go语法简单易用,有其他编程经验的开发者,相信学习并快速上手Go语言的开发,多数觉得不困难吧,下面这篇文章主要给大家介绍了关于GO中优雅编码与降低圈复杂度的相关资料,需要的朋友可以参考下
    2022-12-12
  • go select编译期的优化处理逻辑使用场景分析

    go select编译期的优化处理逻辑使用场景分析

    select 是 Go 中的一个控制结构,类似于用于通信的 switch 语句。每个 case 必须是一个通信操作,要么是发送要么是接收。接下来通过本文给大家介绍go select编译期的优化处理逻辑使用场景分析,感兴趣的朋友一起看看吧
    2021-06-06
  • vim配置go语言语法高亮问题的解决方法

    vim配置go语言语法高亮问题的解决方法

    vim配置go语言语法高亮的问题已经遇到过好几次了,每次都是找不到答案,今天小编给大家带来了vim配置go语言语法高亮问题的解决方法,感兴趣的朋友一起看看吧
    2018-01-01

最新评论