【工程实践】利用go语言写一个简单的Pow样例

本篇博客的主要内容是用go写一个简单的Proof-of-Work共识机制,不涉及到网络通信环节,只是一个本地的简单demo。开发IDE用的是JB Golang。

整个项目的文件结构如下:

PoWdemo
│  main.go
│
├─Block
│      block.go
│
└─BlockChain
        blockChain.go

首先是block.go文件,这个文件记录了有关区块的结构体以及对应的操作函数,详细代码如下:

package Block

import (
	"crypto/sha256"
	"encoding/hex"
	"strconv"
	"strings"
	"time"
)


//
//  Block
//  @Description: Block information
//
type Block struct{
	Index int
	TimeStamp string
	Diff int
	PreHash string
	HashCode string
	Nonce int
	Data string
}

//
//  GenerateFirstBlock
//  @Description : generating the genesis block
//  @param data : data of genesis block
//  @return Block : genesis block
//
func GenerateFirstBlock(data string) Block{
	var firstBlock Block
	firstBlock.Index = 1
	firstBlock.TimeStamp = time.Now().String()
	firstBlock.Diff = 4
	firstBlock.Nonce = 0
	firstBlock.Data = data
	firstBlock.HashCode = generateBlockHashValue(firstBlock)

	return firstBlock
}

//
//  generateBlockHashValue
//  @Description : calculate the hash of a block
//  @param block : the aim block
//  @return string : hash of the aim block
//
func generateBlockHashValue(block Block) string{
	var hashData = strconv.Itoa(block.Index) + block.TimeStamp + strconv.Itoa(block.Diff) + strconv.Itoa(block.Nonce) +
		block.Data
	var hash = sha256.New()
	hash.Write([]byte(hashData))
	hashed := hash.Sum(nil)
	return hex.EncodeToString(hashed)
}

//
//  GenerateNextBlock
//  @Description : generating the next block
//  @param data : data of next block
//  @param preBlock : the previous block
//  @return : Block
//
func GenerateNextBlock(data string, preBlock Block) Block{
	var newBlock Block
	newBlock.Data = data
	newBlock.Index = preBlock.Index + 1
	newBlock.TimeStamp = time.Now().String()
	newBlock.Nonce = 0
	newBlock.Diff = 6
	newBlock.PreHash = preBlock.HashCode
	newBlock.HashCode = PoW(newBlock.Diff, &newBlock)

	return newBlock
}

//
//  PoW
//  @Description : calculate the hash value that meets the diff conditions
//  @param diff : number of 0 in the prefix of the hash value
//  @param block : aim block
//  @return string : the hash of the aim block that meets the diff conditions
//
func PoW(diff int, block *Block) string{
	for{
		hash := generateBlockHashValue(*block)
		if strings.HasPrefix(hash, strings.Repeat("0",diff)){
			return hash
		} else{
			block.Nonce++
		}
	}
}

其次是blockChain.go文件,该文件记录了区块链所包含的信息,以及生成新区块的函数,详细代码如下:

package BlockChain

import (
	"../Block"
	"fmt"
)

//
//  Node
//  @Description: blockchain
//
type Node struct{
	NextNode *Node
	BlockDate *Block.Block
}

//  the head node of the blockchain
var HeadNode *Node


//
//  CreatHeadNode
//  @Description : creat the head node of blockchain
//  @param block : the head block
//  @return *Node : the pointer of head node
//
func CreatHeadNode(block *Block.Block) *Node{
	var headNode *Node = new(Node)
	headNode.NextNode = nil
	headNode.BlockDate = block
	HeadNode = headNode
	return headNode
}


//
//  AddNode
//  @Description : add a new node into the blockchain
//  @param blockDate : block of the node
//  @param preNode : the previous node
//  @return *Node : the pointer of new node
//
func AddNode(blockDate *Block.Block, preNode *Node) *Node{
	var newNode *Node = new(Node)
	blockDate.PreHash = preNode.BlockDate.HashCode
	newNode.BlockDate = blockDate
	newNode.NextNode = nil
	preNode.NextNode = newNode
	fmt.Println(blockDate.HashCode)
	return newNode
}

//
//  ShowBlockChain
//  @Description : print the information of each block
//  @param headNode : the pointer of head node
//
func ShowBlockChain(headNode *Node){
	for node := headNode; node != nil; node = node.NextNode{
		fmt.Println(node.BlockDate)
	}
}

最后是main.go文件,对区块链进行初始化,并生成新的区块。

package main

import (
	"./Block"
	"./BlockChain"
	"strconv"
)

func main(){
	var headBlock = Block.GenerateFirstBlock("This is the first block!")
	var blockChain = BlockChain.CreatHeadNode(&headBlock)
	
	NodePtr := blockChain
	for i := 0; i<10; i++{
		var newBlock = Block.GenerateNextBlock("This is the " + strconv.Itoa(i) +" block!", headBlock)
		NodePtr = BlockChain.AddNode(&newBlock, NodePtr)
	}
	
	//BlockChain.ShowBlockChain(blockChain)

}

以上就是本篇文章实现的简易Pow样例

posted @ 2021-11-08 13:18  阿菜ACai  阅读(114)  评论(0编辑  收藏  举报