区块链概念 That You Must Know 第四期(4)

第四期 简介go语言下挖矿难度的代码实现(4)

卡酷少

Wechat:13260325501

之前的都讲完了,因为代码太多导致文章比较长。所以新增了一片。在这最后的最后,我们将把挖矿的过程最终展示在大家面前。建议大家也将代码在goland里实际跑一跑,会更有感觉。

挖矿难度的代码实现

  • 话不多说,直接给代码实现。

/*
代码逻辑:
    第一步:导库
    第二步:声明并将各项值初始化,共5个数据:blockId(区块id),preHash,timeStamp(区块诞生时间),data,nounce(不明白为什么需要这些数据的同学可以找回第四期(2)篇看一下)
    第三步:声明并创建一个哈希对象,shaObj
    第四步:迭代调用函数isValidHashDifficulty来判断哈希值有效与否。迭代中将nounce值以自增1的方式变化,再每次配合其他信息去生成当前哈希。
*/

package main

import (
    "fmt"
    //第1步
    "crypto/sha256"
)

func main() {
    //第2步
    var (
        blockId    = "100"
        preHash    = "0000fedaa499741317a18f1ad626f933776ad24822cb422634978bfe8005c94b"
        timeStamp = "Thu, 26 Apr 2018 03:30:54 GMT"
        data       = "A -> B 100"
        nonce      = 0  //将nounce初始化为0   (此处注意:nounce为int类型,但是在哈希时算数运算符两边的数据类型必须一致,所以要在字符串拼接时转换类型)
        hashString = "" //将当前hash初始化为空字符串
    )
    //第3步
    shaObj := sha256.New()
    //第4步
    for !isValidHashDifficulty(hashString, 4) {
        nonce++
        input := blockId + preHash + timeStamp + data + string(nonce)
        shaObj.Write([]byte(input))
        hashString = fmt.Sprintf("%x", shaObj.Sum(nil));
        fmt.Println(hashString)//这里打印每次用于匹配的哈希值只是为了将挖矿的过程形象展示,并没有额外含义,写不写都可以
    }
    //当生成有效哈希时,挖矿成功,迭代停止。
    //现实中挖矿时不用停止,继续挖下一个节点即可。
}

func isValidHashDifficulty(h string, difficulty int) bool {
    b := len(h) // 64
    var i int
    for i = 0; i < b; i++ {
        if h[i] != '0' {
            break
        }
    }
    return i >= difficulty
}
  • 运行结果没有比较好的展示方式。这里我们只截取一部分。建议大家可以把代码考下来跑一跑。

《区块链概念 That You Must Know 第四期(4)》

  • 如果你已经看过之前的篇章,相信这代码的原理你已经了然于胸了。下面我们只给出一些注意事项。
  1. 我们给出的5项数据只是一个简单举例,并没有完全列举生成区块哈希时参与的所有数据。
  2. 我们为了简便将blockId设为了string类型,并不代表区块id一定是字符串类型的。
  3. 这里的哈希难度是我们认为设定的,并不是真实哈希难度的生成方法。真是的哈希难度是由很复杂的数学模型实现的,是会根据当前全网算力自动调整的。
  • OK。到此挖矿的真相已经大白了。不知道大家有没有豁然开朗的感觉呢?。。。接下里我们就相约一起探索更多区块链的内容吧!
    原文作者:kakushao
    原文地址: https://segmentfault.com/a/1190000014817719
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞