go实现区块链[2]-整合默克尔树+POW

栏目: Go · 发布时间: 5年前

内容简介:merkleTree.goproofofwork.go:

添加merkleRoot

merkleTree.go

package main

import "crypto/sha256"


//默克尔树节点
type MerkleTree struct{
	RootNode *MerkleNode
}

//默克尔根节点
type MerkleNode struct{
	Left *MerkleNode
	Right *MerkleNode
	Data []byte
}
//生成默克尔树中的节点,如果是叶子节点,则Left,right为nil ,如果为非叶子节点,根据Left,right生成当前节点的hash
func NewMerkleNode(left,right *MerkleNode,data []byte) *MerkleNode{
	mnode := MerkleNode{}

	if left ==nil && right==nil{
		mnode.Data = data
	}else{
		prevhashes := append(left.Data,right.Data...)
		firsthash:= sha256.Sum256(prevhashes)
		hash:=sha256.Sum256(firsthash[:])
		mnode.Data = hash[:]
	}

	mnode.Left = left
	mnode.Right = right

	return &mnode
}

//构建默克尔树
func NewMerkleTree(data [][]byte) *MerkleTree{
	var nodes []MerkleNode
	//构建叶子节点。
	for _,datum := range data{
		node:= NewMerkleNode(nil,nil,datum)
		nodes =  append(nodes,*node)
	}
	//j代表的是某一层的第一个元素
	j:=0
	//第一层循环代表 nSize代表某一层的个数,每循环一次减半
	for nSize :=len(data);nSize >1;nSize = (nSize+1)/2{
		//第二条循环i+=2代表两两拼接。 i2是为了当个数是基数的时候,拷贝最后的元素。
		for i:=0 ; i<nSize ;i+=2{
			i2 := min(i+1,nSize-1)

			node := NewMerkleNode(&nodes[j+i],&nodes[j+i2],nil)
			nodes = append(nodes,*node)
		}
		//j代表的是某一层的第一个元素
		j+=nSize

	}

	mTree := MerkleTree{&(nodes[len(nodes)-1])}
	return &mTree
}

根据交易创建merkleROOT

func (b*Block) createMerkelTreeRoot(transations []*Transation){
	var tranHash [][]byte

	for _,tx:= range transations{

		tranHash = append(tranHash,tx.Hash())
	}

	mTree := NewMerkleTree(tranHash)

	b.Merkleroot =  mTree.RootNode.Data
}

测试merkle


func TestCreateMerkleTreeRoot(){
	//初始化区块
	block := &Block{
		2,
		[]byte{},
		[]byte{},
		[]byte{},
		1418755780,
		404454260,
		0,
		[]*Transation{},
	}



	txin := TXInput{[]byte{},-1,nil}
	txout := NewTXOutput(subsidy,"first")
	tx := Transation{nil,[]TXInput{txin},[]TXOutput{*txout}}

	txin2 := TXInput{[]byte{},-1,nil}
	txout2 := NewTXOutput(subsidy,"second")
	tx2 := Transation{nil,[]TXInput{txin2},[]TXOutput{*txout2}}

	var Transations []*Transation

	Transations = append(Transations,&tx,&tx2)

	block.createMerkelTreeRoot(Transations)

	fmt.Printf("%x\n",block.Merkleroot)
}

增加挖矿逻辑

proofofwork.go:

package main

import (
	"math/big"
	"bytes"
	"crypto/sha256"
)

type  ProofOfWork struct{
	block * Block
	tartget * big.Int
}
const targetBits = 16


func NewProofofWork(b*Block) * ProofOfWork{

	target := big.NewInt(1)
	target.Lsh(target,uint(256-targetBits))
	pow := &ProofOfWork{b,target}
	return pow
}

func (pow * ProofOfWork) prepareData(nonce int32) []byte{

	data := bytes.Join(
		[][]byte{
			IntToHex(pow.block.Version),
			pow.block.PrevBlockHash,
			pow.block.Merkleroot,
			IntToHex(pow.block.Time),
			IntToHex(pow.block.Bits),
			IntToHex(nonce)},
		[]byte{},
	)
	return data
}

func (pow * ProofOfWork) Run() (int32,[]byte){

		var nonce int32
		var secondhash [32]byte
		nonce = 0
		var currenthash big.Int

		for  nonce < maxnonce{


			//序列化
			data:= pow.prepareData(nonce)
			//double hash
			fitstHash := sha256.Sum256(data)
			secondhash = sha256.Sum256(fitstHash[:])
		//	fmt.Printf("%x\n",secondhash)


			currenthash.SetBytes(secondhash[:])
			//比较
			if currenthash.Cmp(pow.tartget) == -1{
				break
			}else{
				nonce++
			}
		}


		return nonce,secondhash[:]
}

func (pow * ProofOfWork) Validate() bool{
	var hashInt big.Int

	data:=pow.prepareData(pow.block.Nonce)

	fitstHash := sha256.Sum256(data)
	secondhash := sha256.Sum256(fitstHash[:])
	hashInt.SetBytes(secondhash[:])
	isValid:= hashInt.Cmp(pow.tartget) == -1

	return isValid
}

测试:

func TestPow(){
	//初始化区块
	block := &Block{
		2,
		[]byte{},
		[]byte{},
		[]byte{},
		1418755780,
		404454260,
		0,
		[]*Transation{},
	}

	pow:=NewProofofWork(block)

	nonce,_:= pow.Run()

	block.Nonce = nonce

	fmt.Println("POW:",pow.Validate())

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

论因特网

论因特网

[美] 休伯特·L.德雷福斯 / 喻向午、陈硕 / 河南大学出版社 / 2015-5 / 32.00

本书是与日俱增的关于因特网利弊之文献的重要补充。 ——《哲学评论》 关于因特网种种承诺的一次清晰辨析……以哲学家的眼光审视一个影响我们所有人的问题。 ——《普遍存在》杂志 ……一场精心设计的论战……我们需要更多德雷福斯这样的老师,将网络融入依 然具有深邃人性的课程。 ——亚当•莫顿(出自《泰晤士报文学增刊》) 在互联网世界,不管你是菜鸟,还是浸淫其中已久—......一起来看看 《论因特网》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具