工作量证明

一. 简介

工作量证明(Proof Of Work,简称POW),简单来讲就是证明你完成了某一项工作。
维基百科的解释:工作量证明系统是一种防止服务攻击及其它服务滥用的经济方式,它要求服务请求方完成某些工作——通常意味着需要请求方计算机完成一定计算量。这种方案的一个关键特征是不对成性:对请求方来说,所需要做的工作有较大难度;但对于服务提供方来说,工作量的验证却比较容易。
工作量证明中包含了两层含义:

  1. 工作者需要完成的工作必须有一定的量,这个量由工作验证者给出;
  2. 验证者可以迅速的检验工作量是否达标,注意这里的检验完成过程必须简单;

区块链的一个关键点就是,一个人必须经过一系列困难的工作,才能将数据放入到区块链中。正是这种困难的工作,才使得区块链是安全和一致的。此外,完成这个工作的人也会获得奖励(这也就是通过挖矿获得币)。

在比特币中,这个工作的目的是为了找到一个块的哈希,同时这个哈希满足了一些必要条件。这个哈希,也就充当了证明的角色。因此,寻求证明(寻找有效哈希),就是实际要做的事情。

二. 技术原理

2.1 哈希(hash)函数

工作量证明最常用的技术原理是哈希函数。哈希有以下几个关键特性:

  1. 无法从一个哈希值恢复原始数据
  2. 对于特定的数据,只能有一个哈希,并且这个哈希是唯一的
  3. 即使是仅仅改变输入数据中的一个字节,也会导致输出一个完全不同的哈希

由于输入散列函数H()的任意值n,会对应到一个H(n)结果,而n只要变动一个比特,就会引起雪崩效应(avalanche effect),所以几乎无法从H(n)反推回n,因此借由指定查找H(n)的特征,让用户进行大量的穷举运算,就可以达成工作量证明。

在区块链中,哈希被用于保证一个块的一致性。哈希算法的输入数据包含了前一个块的哈希,因此使得不太可能去修改链中的一个块:因为如果一个人想要修改前面一个块的哈希,那么他必须要重新计算这个块以及后面所有块的哈希。

我们若指定H(n)的16进制值的前四值,求n,这样统计上平均约要运行16的4次方次H(n)散列运算,才会得到答案,但验算只要进行一次就可以了。如果想要增加难度,那就增加指定的位数即可。以SHA256函数举例,假设我们要处理数据Hello World,并找出H(n)前四值为0000的n,如果从Hello World0开始加上一个十进制数ASCII进行穷举猜测,到Hello World107105时才会得到匹配条件的H(n):

>>> import hashlib
>>> ss = 'Hello World107105'.encode()
>>> hashlib.sha256(ss).hexdigest()
'0000bfe6af4232f78b0c8eba37a6ba6c17b9b8671473b0b82305880be077edd9'

而验算时只要将Hello World107105代入SHA256函数一次即可。

2.2 哈希现金(HashCash)

哈希现金是一种工作量证明机制,在比特币之前,哈希现金被用于垃圾邮件的过滤。哈希现金(hashcash )的灵感来自于这样一个想法,即一些数学结果难于发现而易于校验。比特币使用的原理就类似于HashCash。与邮件应用程序中的hashcash相比,比特币加密电子货币网络采用了不同的基于哈希的工作量证明,以实现比特币的竞争挖掘。

尽管hashcash使用SHA-1散列,并且要求160个散列位中的前20个为零,但比特币的工作证明使用两个连续的SHA-256散列,并且最初需要至少256个散列位中的前32个为零。然而,比特币网络定期重置难度级别,以保持每小时6块的平均创建速度。截至2017年8月(区块#478608),比特币网络已经要求256个哈希位中的前72个必须为零。

三. 工作量证明

工作量证明的算法可以大概描述为:在一个时间段同时有多台服务器对这一段时间的交易进行打包,打包完成后连带区块Header信息一起经过SHA256算法进行运算。在区块头以及奖励交易coinbase里各有一个变量nonce,如果运算的结果不符合难度要求,那么就调整nonce的值继续运算。如果有某台服务器率先计算出了符合难度值的区块,那么它可以广播这个区块。其他服务器验证没问题后就可以添加到现有区块链上,然后大家再一起竞争下一个区块。这个过程也称为挖矿。

比特币网络中任何一个节点,如果想生成一个新的区块并写入区块链,必须解出比特币网络出的工作量证明的迷题。这道题关键的三个要素是工作量证明函数、区块及难度值。工作量证明函数是这道题的计算方法,区块决定了这道题的输入数据,难度值决定了这道题的所需要的计算量。

3.1 POW函数

和我们上节例子中用到的哈希函数一样,比特币系统中使用的工作量证明函正是SHA256。SHA是安全散列算法(Secure Hash Algorithm)的缩写,是一个密码散列函数家族。这一组函数是由美国国家安全局(NSA)设计,美国国家标准与技术研究院(NIST) 发布的,主要适用于数字签名标准。SHA256就是这个函数家族中的一个,是输出值为256位的哈希算法。到目前为止,还没有出现对SHA256算法的有效攻击。

3.2 区块

比特币的区块由区块头及该区块所包含的交易列表组成。区块头的大小为80字节,由4字节的版本号、32字节的上一个区块的散列值、32字节的Merkle Root Hash、4字节的时间缀(当前时间)、4字节的当前难度值、4字节的随机数组成。区块包含的交易列表则附加在区块头后面,其中的第一笔交易是coinbase交易,这是一笔为了让矿工获得奖励及手续费的特殊交易。区块的大致结构如下:


区块结构

3.3 难度值

难度值(difficulty)是矿工们在挖矿时候的重要参考指标,它决定了矿工大约需要经过多少次哈希运算才能产生一个合法的区块。比特币的区块大约每10分钟生成一个,如果要在不同的全网算力条件下,新区块的产生保持都基本这个速率,难度值必须根据全网算力的变化进行调整。简单地说,难度值被设定在无论挖矿能力如何,新区块产生速率都保持在10分钟一个。

难度的调整是在每个完整节点中独立自动发生的。每2016个区块,所有节点都会按统一的公式自动调整难度,这个公式是由最新2016个区块的花费时长与期望时长(期望时长为20160分钟即两周,是按每10分钟一个区块的产生速率计算出的总时长)比较得出的,根据实际时长与期望时长的比值,进行相应调整(或变难或变易)。也就是说,如果区块产生的速率比10分钟快则增加难度,比10分钟慢则降低难度。
这个公式可以总结为如下形式:

New Difficulty = Old Difficulty * (Actual Time of Last 2016 Blocks / 20160 minutes)

四. 工作量证明的过程

4.1 证明过程

我们可以把比特币矿工解这道工作量证明迷题的步骤大致归纳如下:

  1. 生成Coinbase交易,并与其他所有准备打包进区块的交易组成交易列表,通过Merkle Tree算法生成Merkle Root Hash
  2. 把Merkle Root Hash及其他相关字段组装成区块头,将区块头的80字节数据(Block Header)作为工作量证明的输入
  3. 不停的变更区块头中的随机数即nonce的数值,并对每次变更后的的区块头做双重SHA256运算(即SHA256(SHA256(Block_Header))),将结果值与当前网络的目标值做对比,如果小于目标值,则解题成功,工作量证明完成。

该过程可用下图表示:


工作量证明过程

4.2 计算量分析

Hash值是由数字和大小写字母构成的字符串,每一位有62种可能性(可能为26个大写字母、26个小写字母,10个数字中任一个),假设任何一个字符出现的概率是均等的,那么第一位为0的概率是1/62(其他位出现什么字符先不管),理论上需要尝试62次Hash运算才会出现一次第一位为0的情况,如果前两2位为0,就得尝试62的平方次Hash运算,以n个0开头就需要尝试62的n次方次运算。

五. 代码实现

以下是区块链POW部分代码的精简展示,完整代码可参考地址

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

...
import hashlib
...

class Blockchain(object):
    ...

    def proof_of_work(self, last_proof):
        proof = 0
        while self.valid_proof(last_proof, proof) is False:
            proof += 1
        return proof

    @staticmethod
    def valid_proof(last_proof, proof):
        guess = f'{last_proof}{proof}'.encode()
        guess_hash = hashlib.sha256(guess).hexdigest()
        return guess_hash[:4] == '0000'




参考
  1. Pricing via Processing or Combatting Junk Mail
  2. Learn Blockchains by Building One
  3. Proof-of-work system - Wikipedia
  4. 什么是工作量证明?
  5. Learn Blockchains by Building One
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,525评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,203评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,862评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,728评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,743评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,590评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,330评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,244评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,693评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,885评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,001评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,723评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,343评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,919评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,042评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,191评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,955评论 2 355

推荐阅读更多精彩内容