4641b7780aa099ccd7270634638fd297
给自己的区块链添加POW-工作量证明

对POW不太熟悉的同学可以参考这篇文章:https://xiaozhuanlan.com/topic/0492176583

准备工作:

  1. 单向加密:单向加密以人类可读的文本(明文)作为输入,比如“666”这个字符串,再通过一个数学函数产生出难以辨认的输出(密文)。
  2. 挖矿:比特币的产出是通过给予“获胜矿工”奖励来实现,为了获取比特币奖励矿工之间会进行竞争。这个过程之所以被称为“挖矿”。

为什么要挖矿?

相信同学们上篇文章已经按照步骤实现了基础的区块链功能,但是有没有发现,很容易就生成一个区块,如果是这样的话,稀缺性就非常低,没有什么价值,所以我们需要添加生成区块的难度,而且要随着时间的推移,难度系数越来越高。这样保证了一定的付出后才能获取区块,这个付出在这里就是对一个数学问题求解,完成这个问题后才能获取这个区块。

挖矿挖的是什么?

是求一个数学问题的解,需要先理解SHA-256算法也叫哈希算法,这个算法是把给定的文本经过函数计算后得出一个256位的文本,例如:“老铁666” 经过计算后得出哈希值:
7bde6d3ea9a23cf15b0e01fd223649a9f9db10ea7b18150b04ce5dc18c191fcb
同学们可以试试,找个在线SHA-256加密的网站,同样的文本,结果是一样的。
看到这里,有的同学就会思考:“一个哈希值是不是可以像身份证号,代表唯一的一个人?”没错,这就是它的特性之一,唯一性,还有一个特性是几乎不可能逆向求解,谁能看出“7bde6d3ea9a23cf15b0e01fd223649a9f9db10ea7b18150b04ce5dc18c191fcb”这样一个字符串是代表“老铁666”
小总结一下:
1. 哈希值具有唯一性
2. 在给定明文和哈希值的前提下,可以很容易的验证哈希值是否正确,只需按照同样的SHA-256算法对明文重新求一下哈希值,然后比较两个哈希值是否一致即可。
3. 单独给出一个哈希值,几乎不可能推断出它的明文,具有私密性
那我们要挖的其实就是这个哈希值,加上一定的条件,这个条件就是哈希值的前2位都是0,这时有同学会问了:“刚才不是说是唯一的吗?‘老铁666’怎么让它前2位是0啊”,是这样 同学,在代码中我们会添加一个随机数和区块的其它信息,再加上你的明文,一起去算一个哈希值,如果前两位不是0,那就换个随机数,其它信息不变,再算,直到算出来为止,这些你做的计算就是你的工作量证明,如下图:

然后我们刷新浏览器看到如下结果:

这样就生成一个有工作量证明的区块。

代码实现:

看到这里,该码代码了,但是我们先思考一下,在上篇的基础之上,我们需要添加哪些新功能:
1. 一个变量,来控制哈希值前面几位是0,也叫难度系统
2. 一个函数:判断是否是符合要求的哈希值
3. 在原来的生成区块函数中添加一个循环来计算

判断是否是符合要求的哈希值

func isHashValid(hash string, difficulty int) bool {
    prefix := strings.Repeat("0", difficulty)
    return strings.HasPrefix(hash, prefix)
}

go语言中strings的Repeat方法非常方便

生成区块函数改造:

func generateBlock(oldBlock Block, Content string) Block {
    var newBlock Block

    t := time.Now()
    newBlock.Index = oldBlock.Index + 1
    newBlock.Timestamp = t.String()
    newBlock.Content = Content
    newBlock.PrevHash = oldBlock.Hash
    newBlock.Difficulty = difficulty

    for i := 0; ; i++ {
        hex := fmt.Sprintf("%x", i)
        newBlock.Nonce = hex
        if !isHashValid(calculateHash(newBlock), newBlock.Difficulty) {
            fmt.Println(calculateHash(newBlock), " 继续算!")
            continue
        } else {
            fmt.Println(calculateHash(newBlock), " 中!")
            newBlock.Hash = calculateHash(newBlock)
            break
        }

    }
    return newBlock
}

总结:

介绍了工作证明的原理,SHA256的特性唯一性,私密性,为我们的区块链添加了工作量证明机制,下一篇会介绍如何生成多个节点的区块链。
代码在:https://github.com/sunqichao/blockchainPOW

参考:https://medium.com/@mycoralhealth/code-your-own-blockchain-in-less-than-200-lines-of-go-e296282bcffc

© 著作权归作者所有
这个作品真棒,我要支持一下!
介绍区块链开发知识,不谈投资,只谈技术,内容包括: 1. 区块链介绍 a. 概念,原理 ...
3条评论

直接copy跑的代码,只生产了Index0, 没有产生Index1,应该是我哪里姿势不对,初学者,还望大神指教。

#1楼 @咖啡上次 使用postman向本机地址发一个post参数{"content":"100"}

前一篇文章里有介绍参数的步骤 https://xiaozhuanlan.com/topic/0751823649

top Created with Sketch.