欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  科技

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

程序员文章站 2022-03-01 16:28:50
目录区块链实战version 1区块相关:区块链相关区块链实战 字节 字段 说明...

区块链实战

字节 字段 说明
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语言实现区块与区块链的资料请关注其它相关文章!