写点什么

区块链之共识算法系列——PoW(二)

作者:Regan Yue
  • 2021 年 11 月 12 日
  • 本文字数:1365 字

    阅读完需:约 4 分钟

区块链之共识算法系列——PoW(二)

区块链之共识算法系列——PoW(二)

本文收录于我的专栏:趣讲区块链


本专栏会讲述区块链共识算法以及以太坊智能合约、超级账本智能合约、EOS 智能合约相关知识,还会详细的介绍几个实战项目。如果有可能的话,我们还能一起来阅读以太坊的源码。有兴趣的话我们一起来学习区块链技术吧~


接上一篇区块链之共识算法系列——PoW(一)哦,上一篇我们介绍了什么是 P2P、介绍了一下 PoW 算法是什么,然后说明了区块的结构,并生成了一个创世区块,哦对了,生成哈希值的模块还没有搭建好。我先来搭建这个生成哈希值的模块。

一、生成哈希值

func GneHashValue(block Block) string {   var hashdata = strconv.Itoa(block.Index) + strconv.Itoa(block.Nonce) + strconv.Itoa(block.Diff) +      block.TimeStamp + block.PreHash
var sha = sha256.New() sha.Write([]byte(hashdata)) hashed := sha.Sum(nil) return hex.EncodeToString(hashed)}
复制代码


我们这个区块链是仿的比特币的区块,所以我们要将所有数据拼接在一起然后再求哈希值。这里我们使用的是 sha256 加密算法。这里先使用 sha256.New,这个方法会返回一个 hash.Hash。这个 Hash 实现了 encoding.BinaryMarshaler 和 encoding.BinaryUnmarshaler,可以对哈希的内部状态进行编组和解组。然后使用 Write 将数据写入底层数据流,它会返回写入的字节数或者错误,这里我们不需要它的返回值。Sum 方法我们这的参数是 nil,这就说明我们要将当前的哈希值追加到 nil,并返回生成的一个 slice,这个方法不会改变哈希值的底层状态。EncodeToString 返回 hashed 的十六进制编码。

二、看一看创世区块

我们来看一看创世区块。


func main() {  var firstBlock = GneFirBlock("Regan Yue")  fmt.Println(firstBlock)  fmt.Println(firstBlock.Data)}
复制代码


{ e42d311dd9ba42d8f1907ba60a7c1112c1720ccbdad938aaad91b4990089ece8 2021-11-06 21:34:32.3711993 +0800 CST m=+0.023002101 3 Regan Yue 1 0}Regan Yue
复制代码


我们可以看到,创世区块的数据就保存好了,然后我们来写生成新的区块。

三、生成新区块

func GneNewBlock(data string, oldBlock Block) Block {  var newBlock Block  newBlock.TimeStamp = time.Now().String()  newBlock.Diff = 3  newBlock.Index = 2  newBlock.Data = data  newBlock.PreHash = oldBlock.HashCode  newBlock.Nonce = 0  newBlock.HashCode = pow(newBlock.Diff, &newBlock)
return newBlock}
复制代码


接下来我们要生成一个新的区块,这里区块高度要为 2,新区块的 PreHash 要为前一个区块的哈希值,然后我们计算这个区块的哈希值,这里我们模仿比特币,算前导 0 的个数。


func pow(diff int, block *Block) string {  for {    hashValue := GneHashValue(*block)    fmt.Println(hashValue)    if strings.HasPrefix(hashValue, strings.Repeat("0", diff)) {      //成功      fmt.Println("success")      return hashValue    } else {      block.Nonce++    }
}}
复制代码


这个 strings.HasPrefix 的两个参数都要求是字符串,其中第一个参数是我们要检测的字符串,而第二个参数是前缀,我们要检测这个字符串是否以这个前缀开头。strings.Repeat 就是将字符串重复第二个参数的次数,然后返回一个字符串,如果生成的哈希值前导 0 的个数等于难度值就返回哈希值,否则 Nonce 值变化。



发布于: 2 小时前阅读数: 4
用户头像

Regan Yue

关注

还未添加个人签名 2020.08.12 加入

对Go、Python、网络安全、区块链感兴趣. · 华为云云享专家 · 掘金资讯创作者

评论

发布
暂无评论
区块链之共识算法系列——PoW(二)