第四期 简介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
}
- 运行结果没有比较好的展示方式。这里我们只截取一部分。建议大家可以把代码考下来跑一跑。
- 如果你已经看过之前的篇章,相信这代码的原理你已经了然于胸了。下面我们只给出一些注意事项。
- 我们给出的5项数据只是一个简单举例,并没有完全列举生成区块哈希时参与的所有数据。
- 我们为了简便将blockId设为了string类型,并不代表区块id一定是字符串类型的。
- 这里的哈希难度是我们认为设定的,并不是真实哈希难度的生成方法。真是的哈希难度是由很复杂的数学模型实现的,是会根据当前全网算力自动调整的。
- OK。到此挖矿的真相已经大白了。不知道大家有没有豁然开朗的感觉呢?。。。接下里我们就相约一起探索更多区块链的内容吧!
有疑问加站长微信联系(非本文作者)