区块链中的密码学(3):密码学Hash算法和挖矿

接上文:

区块链中的密码学(1):提升密码学的认知

区块链中的密码学(2):密码学基本介绍

​谈及挖矿,首选浮现在脑海中的应该是:

但区块链中的挖矿其实这样的:

机架上排满矿机,不停地在做运算,而且是是在做Hash运算。有人称这种挖矿为能源黑产,把电能转化为数字货币。那我们今天就来谈谈Hash算法和POW共识算法的关系。

01 Hash算法

谈及Hash,我们要区分普通的Hash算法和密码学中的Hash算法。

普通的Hash算法,一般也称之为散列表或哈希表,属于一种基本的数据结构。一般用于实现O(1)的查询条件之中, 涉及哈希函数的选取和解决哈希碰撞问题。

它的应用十分广泛,像C++标准库中的hashmap, Java中的HashMap,Python中的dict,都采用Hash算法实现。另外想很多缓存产品, memecached, redis都是hash算法的大规模应用。

而密码学中的Hash算法,可以用一个公式来描述:

摘要/散列值/指纹 = hash(消息)

算法的输入是消息,或者一堆二进制内容。最终输出的是固定长度的一个二进制串,可称之为摘要,散列值,指纹等。hash算法也有很多种。密码学的hash算法有五大重要特征:

  1. 消息是输入相同,输出值相同,而且所有的输出都是等长;

  2. 不管输入多长,运算速度快;

  3. 算法具备单向性,极难通过输出值获取输入值;

  4. 输入信息一旦被修改,即使很轻微的修改,输出值也不一样;

  5. 不存在hash碰撞。也就是很难找到两个不同的消息,他们的输出值是一样的;

密码学Hash算法很多,比如MD4, SHA。但MD5被中国的王小云教授证明是不安全的,所以目前使用广泛的是SHA族类算法。比特币中使用的是SHA-256算法。

我们可以演示一下Python中使用SHA-256的过程:

 % pythonPython 3.7.3 (default, Nov 15 2019, 04:04:52)>>> import hashlib>>> hashlib.sha256("hello world!".encode('utf-8')).hexdigest()'7509e5bda0c762d2bac7f90d758b5b2263fa01ccbc542ab5e3df163be08e6ca9'>>> hashlib.sha256("hello world".encode('utf-8')).hexdigest()'b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9'>>> hashlib.sha256("hello world, bitcoin ethereum consusus".encode('utf-8')).hexdigest()'39a0a566f63869830e769533c4efabd31cba7cf624cd23e67638a25354fa5c10'
 
密码学的Hash算法的特性决定了它的应用范围,经常被用于身份验证,文件指纹,消息防篡改等各个方面。

下面,我们讲跟区块链极其相关的一种应用,HashCash。

02 HashCash

HashCash我们在文章《从区块技术的发展历史看区块链是什么?》中提到,由Adam Back设计,具体论文见:http://www.hashcash.org/papers/hashcash.pdf。Adam Back在今天的区块链行业仍然具有巨大的影响力。他是Blockstream公司的创始人和CEO,比特币核心开发者大部分都是Blockstream公司的雇员。

HashCash最早出现是为了解决网络中的资源被大量滥用,特别是垃圾邮件泛滥。怎么办呢?

HashCash的思路很简单,在发邮件前能不能先干点小活儿,做对了我才接收你的邮件。这个活儿不能太重,但至少要占用发送方的一些资源。

这个流程其实大家应该很熟悉:

12306占用的是人的注意力,HashCash是CPU的算力,他的方式是:

  1. 在电子邮件的消息头中,增加一个 hashcash 戳记(hashcash stamp)散列值;

  2. 该散列中包含收件人地址,发送时间,salt,该散列值特别之处在于它至少前20位必须是0才是一个合法的hashcash戳记

  3. 为了得到合法的散列值,发送者必须经过许多次尝试(改变salt值)才能获得。

 HashCash背后的设计思路就是希望基于的数学难题,希望你做一些的工作,也就是付出CPU的计算代价(这个概念很重要,比特币中这个也是关键),得到正确的结果,才能获取某些资源(比方说往你的邮箱发送垃圾邮件)。

Hash算法速度相对快,输入数据相差一点点,都会导致散列值千差万别的特性,被Adam Back选中。用cash代表付出算力之后的资源回报,用词非常精当,特别延用到比特币中作为POW共识算法的核心,才合适不过。

03 比特币挖矿

以比特币为代表的区块链技术称之为分布式账本。既然是账本,就存在非常核心的问题,账房先生在哪里?谁来负责记账呢?

在传统的中心化应用中,处理这个问题很简单,在应用的账户系统系统里面,设置不同的权限即可,把这种核心权限赋予极少部分的人来处理。

但比特币是一个纯粹的P2P系统,每个节点的权限和地位都是一样的,相当于很多人要一起决策一件事情,这个过程在区块链里面称之为共识(Consensus),共识的机制也就成称之为共识算法。

中本聪在设计比特币算法的时候,受到HashCash的启发,采取工作量证明的方式来实现记账过程,参与记账的节点,称之为矿工。工作量证明在比特币白皮书中明确提到,具体见:

https://github.com/ConsensusDev/whitepaper/blob/master/bitcoin.md(整理了各种版本),有详细的描述。

矿工合并收到的交易形成一个完整的区块,区块头由一些字段构成,其中最后一个字段nonce是可变的,矿工不断修改nonce的值,并计算整个区块头的hash值,当hash值小于某个目标值的时候,才算记账成功,本区块是一个合法区块,广播到全网,矿工获得记账奖励。目标值跟难度值相关联。难度值越大,目标值越小(hash值前面的0越多),挖矿难度越高。

核心寻找nonce的过程类似于下面一段代码:

def proof_of_work(header, difficulty_bits):      # calculate the difficulty target      target = 2 ** (256-difficulty_bits)       for nonce in xrange(max_nonce):             hash_result = hashlib.sha256(str(header)+str(nonce)).hexdigest()             # check if this is a valid result, below the target             if long(hash_result, 16) < target:                   print "Success with nonce %d" % nonce                   print "Hash is %s" % hash_result                   return (hash_result,nonce)        print "Failed after %d (max_nonce) tries" % nonce        return nonce

完整的代码见:

https://github.com/ConsensusDev/code/blob/master/pow/proof_of_work.py

运算难度随难度的增加指数增加,笔者电脑为2018年款的macbook,截取一些运算结果如下:

Difficulty: 1048576 (20 bits)Starting search...Success with nonce 237723Hash is 000005720acd8c7207cbf495e85733f196feb1e3692405bea0ee864104039350Elapsed Time: 0.5485 secondsHashing Power: 433381 hashes per secondDifficulty: 2097152 (21 bits)Starting search...Success with nonce 687438Hash is 000003a6eeee97491a9183e4c57458172edb6f9466377bf44afbd74e410f6eefElapsed Time: 1.5282 secondsHashing Power: 449829 hashes per secondDifficulty: 4194304 (22 bits)Starting search...Success with nonce 1759164Hash is 0000008bb8f0e731f0496b8e530da984e85fb3cd2bd81882fe8ba3610b6cefc3Elapsed Time: 3.9695 secondsHashing Power: 443166 hashes per secondDifficulty: 8388608 (23 bits)Starting search...Success with nonce 14214729Hash is 000001408cf12dbd20fcba6372a223e098d58786c6ff93488a9f74f5df4df0a3Elapsed Time: 32.6874 secondsHashing Power: 434868 hashes per secondDifficulty: 16777216 (24 bits)Starting search...Success with nonce 24586379Hash is 0000002c3d6b370fccd699708d1b7cb4a94388595171366b944d68b2acce8b95Elapsed Time: 55.3770 secondsHashing Power: 443981 hashes per second

我们这里只阐述了核心的挖矿过程,更详细的流程描述可以见:《精通比特币》一书。随着比特币价格的一路走高,越来越多的矿工加入算力军备竞赛,目前整个算力也达到恐怖的110.18 EH/s。比特币网络本身随着算力的变化,动态调整难度值。比特币网络的运行10年的难度曲线如下:

当然比特币网络也是这场算力竞争中最大的收益者,算力越大,系统越安全,越能形成最大的共识,因而让比特币的市值长期超过整个数字货币市场的50%。

密码学Hash算法在区块链技术中运用广泛,除了挖矿,在区块打包中也大放异彩,区块链不可篡改的算法保障就是Hash算法决定的。下次探讨这个问题,敬请期待。

发布了6 篇原创文章 · 获赞 2 · 访问量 921

猜你喜欢

转载自blog.csdn.net/noding2001/article/details/104236106