当前位置:   article > 正文

Go语言实现一个简单的区块链_go语言写个区块链

go语言写个区块链

Go语言实现一个简单的区块链

项目大概结构

创建区块

package core

import (
	"time"
)

type  Block struct {
	Timestamp int64  //时间戳
	Data []byte  //区块信息
	PrevBlockHash []byte  //前一个区块哈希值
	Hash []byte  //自身哈希值
    Nonce int  //工作量证明
}

//创建新区块(传入data信息以及上一个区块的哈希值)
func Newblocks (Data string,PrevBlockHash []byte)   *Block{
	block := &Block{time.Now().Unix(),[]byte(Data),PrevBlockHash,[]byte{},0}  
	pow := NewProfowork(block) 
	n,h := pow.Run()  //工作量证明run方法
	block.Hash = h 
	block.Nonce = n
	return block
}

//创世纪块(第一个块)
func NewGenesisBlock() (*Block) {
   return Newblocks("Genesis Block",[]byte{})
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

生成区块链

package core

type BlockChain struct{
	Blocks []*Block
}

//新区块加入区块链
func (b *BlockChain) AddBlock(data string){
	preB := b.Blocks[len(b.Blocks)-1]
	newB := Newblocks(data,preB.Hash)
	b.Blocks = append(b.Blocks,newB)
}

//创世区块链(唯创世块的区块链)
func NewBlockChain() *BlockChain{
	Newb := NewGenesisBlock()
	a := []*Block{Newb}
	return &BlockChain{a}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

工作量证明

package core

import(
	"crypto/sha256" //哈希算法包
	"log" 
	"bytes"
	"math" 
	"math/big" //大整数(哈希值很大)
	"encoding/binary"

)

var MaxNonce = math.MaxInt64  //最多挖矿math.MaxInt64 次

const Targetbits = 20   //挖矿难度系数 越大越难

//工作量结构体
type Profofwork struct{
	Block *Block
	Target *big.Int
}

// 区块以及目标值
func NewProfowork(b *Block) *Profofwork{
	target := big.NewInt(1)
	target.Lsh(target,uint(256-Targetbits)) //移位运算(256-20)位
	pow := &Profofwork{b,target} 
	return pow
}

// 数据整合成字节换算哈希值
func (p *Profofwork)prepareDate(n int) []byte{
    data := bytes.Join([][]byte{
       p.Block.PrevBlockHash,
	   p.Block.Data,
	   IntToHex(p.Block.Timestamp),
	   IntToHex(int64(Targetbits)),
	   IntToHex(int64(n)),
	},[]byte{},)
	return data
}

// 寻找有效的哈希值(挖矿)
func (p *Profofwork) Run() (int,[]byte){
	var Hashbig big.Int
	var hash [32]byte
	var nonce = 0
	for nonce < MaxNonce{
		data := p.prepareDate(nonce)
		hash = sha256.Sum256(data) //哈希算法生成哈希
		Hashbig.SetBytes(hash[:]) //哈希值转为大整数
//与所移位运算后的大整数比较 小于才算有效哈希 返回哈希值以及循环次数 退出“挖矿”
		if Hashbig.Cmp(p.Target) == -1{   
			break
		}else{
            nonce++
		}
	}
	return nonce,hash[:]  
}

// 校验区块有效与否
func (p *Profofwork) Isvalidata() bool{
   var Hashbig big.Int
   //把记录的循环次数传参
   data := p.prepareDate(p.Block.Nonce)
   hash := sha256.Sum256(data)
   Hashbig.SetBytes(hash[:])
   is :=  Hashbig.Cmp(p.Target)== -1
   return is   
}


//将一个 int64 转化为一个字节数组(byte array)
func IntToHex(num int64) []byte {
	buff:=new(bytes.Buffer)
	err:=binary.Write(buff, binary.BigEndian, num)
	if err !=nil{
		log.Panic(err)
		}

	return buff.Bytes()
	
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84

main.go

package main

import (
	"core"
	"fmt"
)

func main() {
//生成创世纪区块链
	bc := core.NewBlockChain()
//
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/1019818
推荐阅读
相关标签