zoukankan      html  css  js  c++  java
  • Go语言实现区块链挖矿基于POW共识

    Go语言实现区块链挖矿基于POW共识

    注释都已经标注上了

    代码如下:

    package main
    
    import (
    	"time"
    	"strconv"
    	"crypto/sha256"
    	"encoding/hex"
    	"fmt"
    	"strings"
    )
    
    //通过代码,实现PoW挖矿
    
    //定义区块
    type Block struct {
    	//上一个区块的哈希
    	PreHash string
    	//当前区块的哈希
    	HashCode string
    	//时间戳
    	TimeStamp string
    	//难度系数
    	Diff int
    	//交易信息
    	Data string
    	//区块高度
    	Index int
    	//随机值
    	Nonce int
    }
    
    //第一个区块:创世区块
    func GenerateFirstBlock(data string) Block {
    	//创建第一个Block
    	var firstblock Block
    	firstblock.PreHash = "0"
    	firstblock.TimeStamp = time.Now().String()
    	//暂设为4
    	firstblock.Diff = 4
    	//交易信息
    	firstblock.Data = data
    	firstblock.Index = 1
    	firstblock.Nonce = 0
    	//通过sha256得到自己的哈希
    	firstblock.HashCode = GenerationHashValue(firstblock)
    	return firstblock
    }
    
    //生成区块的哈希值
    func GenerationHashValue(block Block) string {
    	//按照比特币的写法,将区块的所有属性拼接后做哈希运算
    	//int转为字符串
    	var hashdata = strconv.Itoa(block.Index) + strconv.Itoa(block.Nonce) +
    		strconv.Itoa(block.Diff) + block.TimeStamp
    	//算哈希
    	var sha = sha256.New()
    	sha.Write([]byte(hashdata))
    	hashed := sha.Sum(nil)
    	return hex.EncodeToString(hashed)
    }
    
    
    //产生新的区块
    func GenerateNextBlock(data string, oldBolock Block) Block {
    	//产生一个新的区块
    	var newBlock Block
    	newBlock.TimeStamp = time.Now().String()
    	//难度系数
    	newBlock.Diff = 5
    	//高度
    	newBlock.Index = 2
    	newBlock.Data = data
    	newBlock.PreHash = oldBolock.HashCode
    	newBlock.Nonce = 0
    
    	//创建pow()算法的方法
    	//计算前导0为4个的哈希值
    	newBlock.HashCode = pow(newBlock.Diff, &newBlock)
    	return newBlock
    }
    
    //pow算法
    func pow(diff int, block *Block) string {
    	//实现不停地去挖矿
    	for {
    		//认为是挖了一次矿了
    		hash := GenerationHashValue(*block)
    		//挖矿过程的哈希打印
    		//fmt.Println(hash)
    		//判断哈希值前导0是否为diff个0
    		//strings.Repeat:判断hash是否有diff个0,写1,就判断为有多少个1
    		if strings.HasPrefix(hash, strings.Repeat("0", diff)) {
    			//挖矿成功
    			fmt.Println("挖矿成功")
    			return hash
    		} else {
    			//没挖到
    			//随机值自增
    			block.Nonce++
    		}
    	}
    }
    func main() {
    	//测试创建创世区块
    	var firstBlock = GenerateFirstBlock("创世区块")
    	fmt.Println(firstBlock)
    	fmt.Println(firstBlock.Data)
    
    	//需要生成下一个区块
    	secondBlock := GenerateNextBlock("第二区块", firstBlock)
    	fmt.Println(secondBlock)
    
    	thirdBlock := GenerateNextBlock("第三区块", secondBlock)
    	fmt.Println(thirdBlock)
    }
    
    
    
  • 相关阅读:
    php 导出csv文件
    dns 服务器配置
    ettercap ARP dns 欺骗
    for循环内 执行$ajax(){}
    js 如何生成二维数组
    jquery读取csv文件并用json格式输出
    echo 换行
    cmd命令运行php,php通过cmd运行文件
    Git 常用命令整理
    图像裁剪插件
  • 原文地址:https://www.cnblogs.com/xwxz/p/14504550.html
Copyright © 2011-2022 走看看