POW共识算法-简单的模拟

生成区块代码

package Block

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

//go代码模拟POW挖矿
//区块结构体
type Block struct {
    Index int //区块高度
    TImeStamp string //时间戳
    Diff int //挖矿难度,实际是动态变换
    PreHash string //上一个区块的hash值
    HashCode string //本身hash值
    Nonce int //改变生成hash值的值 控制挖矿是否成功
    Data string //交易信息
}

//生产区块hash值
func GenerateBlockHashValue(block Block)string{
    //区块信息做拼接
    var hashData = strconv.Itoa(block.Index)+block.TImeStamp+
        block.Data+strconv.Itoa(block.Diff)+strconv.Itoa(block.Nonce)
    //hash算法
    var hash = sha256.New()
    hash.Write([]byte(hashData))
    //将字节转换成16进制的字符串
    return hex.EncodeToString(hash.Sum(nil))
}

//创始区块,第一个区块
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
}

//产生新区块
func GenerateNextBlock(data string,oldBlock Block)Block{
    var newBlock Block
    newBlock.Data = data
    newBlock.TImeStamp = time.Now().String()
    //暂时设定为0.nonce应该由矿工操作处理
    newBlock.Nonce = 0
    newBlock.PreHash = oldBlock.HashCode
    //暂时手动设定
    newBlock.Index = oldBlock.Index+1
    newBlock.Diff = oldBlock.Diff

    //POW成功后,带有0000的hash值
    Mine(newBlock.Diff,&newBlock)

    return newBlock
}

//挖矿,实际上寻找符合难度的hash值 diff:难度
func Mine(diff int,block *Block){
    for  {
        //生成hash
        var hash = GenerateBlockHashValue(*block)
        //判断是否符合难度 前面四个零
        if strings.HasPrefix(hash,strings.Repeat("0",diff)) {
            fmt.Println(hash)
            fmt.Println(block.Nonce)
            fmt.Println("挖矿成功")
            block.HashCode = hash
            return
        }else {
            fmt.Println(hash)
            block.Nonce ++
        }
    }
}

组成区块链代码

package BlockChain

import (

    "fmt"
    "POW/Block"
)

//通过链表形式维护区块练中的业务
type Node struct {
    NextNode *Node //指向下一个区块的指针
    Block *Block.Block //本身数据信息
}

//创建头节点
func CreateHeaderNode(block *Block.Block)*Node{
    var headerNode *Node = new(Node)
    headerNode.NextNode = nil
    headerNode.Block = block
    return headerNode
}

//添加节点,当挖到框,添加区块
func AddNode(block *Block.Block,node *Node)*Node{
    var newNode *Node = new(Node)
    newNode.NextNode = nil
    newNode.Block = block
    node.NextNode = newNode
    return newNode
}

//遍历链表
func ShowNodes(node *Node){
    n:= node
    for  {
        if n.NextNode == nil {
            fmt.Println(n.Block)
            break
        }else{
            fmt.Println(n.Block)
            n = n.NextNode
        }
    }
}

测试

package main

import (
    "POW/Block"
    "POW/BlockChain"
)

func main() {
    var first = Block.GenerateFirstBlock("创始区块")
    var second = Block.GenerateNextBlock("第二个区块",first)

    //创建链表
    var header = BlockChain.CreateHeaderNode(&first)
    //将区块放入区块链中
    BlockChain.AddNode(&second,header)

    //遍历
    BlockChain.ShowNodes(header)
}

你可能感兴趣的:(POW共识算法-简单的模拟)