• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

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

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

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)
}



鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
svn查看日志出现want to go offline?发布时间:2022-07-10
下一篇:
go语言调度器源代码情景分析之三:内存发布时间:2022-07-10
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap