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

原创
2018/03/13 11:39
阅读数 118

对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

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
1 评论
0 收藏
0
分享
返回顶部
顶部