生成区块代码
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)
}
网友评论