在区块链系统中,分散式网络中各节点,需要透过共识机制去决定以哪个节点所生成区块为系统中的新区块,而工作量证明 Proof-Of-Work (POW) 就是其中一种.
顾名思义,工作量证明就是用来证明你做了一定量的工作,可用工作成果来证明完成相应的工作量.
简单来说,在现实生活中,你通过了完成一系列课程得到的课程证书,其他人也可以从你这张证书中知道你是曾经完成了这一系列的课程.
第一个POW 应用是1996年 Adam Back 开发的 "Hashcash" 应用,它采用工作量证明共识机制来过滤垃圾邮件,微软也将其应用在 Hotmail Exchange Outlook 等电邮服务上.具体做法是要求所有收到的邮件都使用强 POW 附件.此系统使得垃圾邮件发送者在大量发送邮件时在经济成本上不可行,但却允许个人在需要的时候互相发送信息.时至今日这种算法也被赋予新的意义,即以"挖矿"形式作为比特币安全核心.
工作量证明(POW)共识机制算法采用了SHA-256 运算 Hash 值,特点是难以运算,却容易验证.
我们知道改变 Hash 值的原始数据中的任何一部分,所产生的 Hash值也会随之变化,因此我们只需在运算 Hash 值时,加入一个不断改变的随机数,亦总是可以计算出以 0 开头的 Hash 值.所以要找到符合要求的区块 Hash 值,则需要经过进行大量运算,运算时间取决于节点的运算速度.当某个节点提供出一个符合要求的 Hash值,就说明该节点确实经过了大量的尝试运算.当然,并不能代表说已进行了多少次运算的次数,因为寻找符合要求 Hash值是一个概率事件.
换言之,当节点拥有占全网 N%的算力时,该节点即有 N/100的概率找到符合要求的 Hash值.
看以下的例子就会清楚:
我们首先确定一个字符串:"Samson's blog-:" 及验证结果的条件:在这个字符串后增加一个叫个Nonce整体值(随机数),然后对整个字符串进行SHA-256 运算,运算出正确的Hash值结果,且符合难度值,是以"000开头的".如果运算出来的Hash值不符合要求,则通过递增Nonce的值,重新运算.
按照以上的条件,我们经过运算了1577次后找到符合条件(前3位为0)的Hash值.
那为什么条件是以000开头,那0000,00000开头可以吗?
前3位为0只是这个例子的设定.其实在比特币在生成区块的过程中,一个符合要求的区块 Hash 是由N个前导零构成的,而零的位数就取决于当时网络中的难度值,也就是说,前导零的位数越多,就代表越难.
SHA-256生成的 Hash值都为256 位元,Hash值是由数字和大小写字母构成的字符串,每一位有62种可能性(可能是 26个大写字母,26个小写字母,10个数字中其中一个),假设任何一个字符出现的概率是均等的,那么第一位为0的概率是1/62,理论上需要尝试 62次Hash运算才会出现一次第一位为0的情况,如果前两2位为0,就得尝试62的平方次Hash运算,以N个0开头就需要尝试62的N次方次运算.
如果要达到以0000开头的 Hash值,理论上要尝试 62^4 = 14776336 次.
如果要达到以00000开头的 Hash值,理论上要尝试 62^5 = 916132832 次.
当然并不是纯粹算有几个前导零就解决了,否则每次难度值的调整就只能以2 的次方倍数来进行,实作上采用小于目标值的方式能更精确地调整难度值.
当节点找到了满足条件的 Hash值,就会立即广播全网打包好的区块,其他节点收到广播的打包区块,之后其他节点怎么验证这个 Hash值?很简单,只需对这个字符串做一次SHA-256 运算,得到Hash值,而且符合难度值,则视为验证通过.
如果验证通过,则代表已经有节点成功打包区块,其他节点就停止不再为当前区块打包,而是转为接纳这个区块,并加入到自己的账本中,然后参与下一区块的竞争(挖矿).
如果验证不通过,将代表节点广播的打包区块有问题,可能是区块被修改或者其他违规行为,其他节点将直接扔掉这个区块,这个区块则无法记录到总账本中,而该节点所消耗的运算成本就浪费了.正正因为这样,所有节点都自觉自律地遵守共识机制,从而保障了整个系统账本唯一性及安全.
在区块链采用POW共识机制的应用中,比特币是其中最具有代表性的.
而比特币共识协议则主要是由 工作量证明 和 最长链机制 两部分组成.
在比特币区块链系统中,不断有交易产生,而且每隔一个时段(10分钟,其他区块链系统并不一定相同)系统就会将就会将某个节点(服务器)在这段时间的交易记录打包生成一个区块,再追加到最长的区块链中并给予该节点奖励(新区块奖励及交易费收益).但是,区块链中有这么多个节点,加上吸引的奖励,引致大家争相记账,从而会出现记账记录不同的问题,哪最后到底是以哪个节点为准呢?
比特币系统引入工作量证明来解决这个问题,规则如下:
1. 一段时间内(10分钟左右)只有一个节点可以记账成功;
2. 通过工作量证明竞争获得唯一记账权;
3. 其他节点复制记账结果;
不过在进行工作量证明之前,记账节点会做进行如下准备工作:
1. 收集广播中还没有被记录账本的原始交易信息;
2. 检查每个交易信息中付款地址有没有足够的余额;
3. 验证交易是否有正确的签名;
4. 把验证通过的交易信息进行打包记录;
5. 添加一个奖励交易:给自己的地址增加 12.5 比特币;
6. 如果节点争夺记账权成功的话,就可以得到 12.5 比特币的奖励;
为什么是奖励是 12.5 比特币?
中本聪所开发的比特币系统只会发行2100万个比特币,为鼓励外界开发储存及处理比特币交易的区块,系统提供了挖掘区块的奖励,区块奖励从2009 年开始每个区块可获得50个比特币的奖励,但此一奖励区块回报每产出21万个区块减半一次,即每四年减半,2013年到2016年6月则是25个比特币,2016年7月9日区块奖励再度折半到12.5个比特币,估计到2021年时会再度折半到6.25个,在2022 年中就会挖出超过90%,因为比特币最小单位是0.00000001(10^-8)元,所以2140 年之后区块奖励就会小于最小单位,也就是挖矿奖励只有剩下手续费,同时将不再有新的比特币产生,最终流通中的比特币将总是略低于2100万个.这也是比特币系统中避免货币发行太多或太快,用来抑制通货膨胀的机制.
工作量证明关键的三个要素分别是工作量证明函数,区块及难度值.
3. 难度值(Difficulty)-这道题的所需要的计算量;
区块的大致结构如图所示:
比特币的区块由区块头及该区块所包含的交易列表组成,而拥有80字节固定长度的区块头(当中亦包括上一个区块的 Hash值),就是用于比特币工作量证明的输入数据.
因此,为了使区块头能体现区块所包含的所有交易,在区块的构造过程中,需要将该区块要包含的交易列表,通过Merkle Tree算法生成Merkle Root Hash,并以此作为交易列表的摘要存到区块头中.
1. 发行新的比特币(在达到发行总数之前,比特币上限为 2100万个);
现实例子:金矿消耗资源将黄金注入流通经济.比特币通过"挖矿"完成相同的事情,只不过消耗的是运算时间及能源.
难度值是节点(矿工)们在挖矿时候的重要的参考指标,它决定了矿工大约需要经过多少次 Hash 运算才能产生一个符合要求的区块.比特币区块大约每10分钟生成一个,如果要在不同的全网算力条件下,新区块的产生保持都基本这个速率,难度值必需根据全网算力的变化进行相应的调整.
简单而言,难度值被设定在无论挖矿能力如何,新区块产生速率都保持在10分钟一个.
难度值的调整是在每个完整节点中独立自动发生的.
每2016个区块,所有节点都会按统一的公式自动调整难度值,这个公式是由最新 2016 个区块的花费时长与期望时长(期望时长为20160分钟即两周,是按每10分钟一个区块的产生速率计算出的总时长)比较得出的,根据实际时长与期望时长的比值,进行相应调整(或变难或变易).
换言之,如果区块产生的速率比10分钟快则增加难度,比10分钟慢则降低难度.
这个公式可以总结为如下形式:
同时比特币工作量证明需要有一个目标值,计算公式如下:
所谓挖到矿就是猜到一个 Nonce 值让该区块的摘要值小于一个会根据难度而线性调整的目标值,这就是工作量证明机制(Proof-of-Work)
POW设计最初是希望大家能使用分散的运算资源,让每个比特币的参与者都可以使用自动的电脑进行挖矿,以公平参与来获得比特币奖励.
个人矿工用一般桌机(使用 CPU)就能挖到矿;
利用显卡的绘图处理器(Graphic Processing Unit GPU)可以加速数十到数百倍;
矿池:矿工联合起来组成矿池进行挖矿,收益将以矿工的算力按百分比来分成;
每次找到符合条件的 Hash值,继而生成新区块难度值就会随增时间而增加,也造成生成新区块的时间亦大大增加,因此大规模运算会消耗庞大的电力能源,而且在运算上的目的只是为了运算出POW,非常浪费.
由于工作量证明需要消耗大量的算力,同时比特币大约 10分钟 才会产生一个区块,区块大小只有 1MB,仅仅能够包含 3,4000 笔交易,平均下来每秒只能够处理 5~7(个位数)笔交易,所以比特币网络的拥堵状况非常严重,区块确认的时间难以确认.
比特币,应该说是区块链应用中,分散式这个概念很重要,由于贪婪而诞生的具备庞大算力的矿池,令到先行的少数人拥有庞大且集中的算力,从而令后来者无法公法参与,将令到原来分散化的比特币网络中的"无关键中心化"逐渐失去特性,即使分叉,这个问题仍不能有效解决.最大矿池最高已经超过40%杂凑率,而且前两大矿池合起来也常常超过51%.若是前两大矿池联手作弊就能主导区块链的生成,甚至制造不实的交易资讯,造成信心破产,系统就会崩解.
4. 新的区块链必须找到一种不同的散列算法,否则就会面临比特币的算力攻击;
5. 容易产生分叉,需要等待多个确认;
6. 永远没有最终性,需要检查点机制来弥补最终性;
2. 节点间无需交换额外的信息即可达成共识;
3. 破坏系统需要投入极大的成本;
正正是因为它的缺点:工作明证明的成本太高,这也是为何我先说缺点再说优点的原因之一;
用现有的硬件计算十亿哈希,消耗0.1至1焦耳的能量.因此,全球每秒钟使用约十亿瓦(GW /秒)创建一种有效的工作量证明.尽管电力成本在全球范围内变化,但是这个过程每小时消耗的能源价值也能够占到约$ 50000.但是,这虽然是极大的浪费,但却是必需的.因为是为了阻止攻击者轻易伪装成数以百万计的节点,并控制网络.在没有其它选择的情况下,透过这种工作量证明的"浪费"从而获得一种"无关键中心化","半匿名"的而允许所有人都能够几乎免费即时发送现金到其它人的全球货币网络来说,这个代价可能是值得的.在2009年的当时,工作量证明确实是唯一的选择.
总括来说,工作量证明共识机制是目前唯一接受了实战检验的公有链算法,虽然其缺点浪费算力,但其实这种"浪费"也是达到分散化的效果而言是必需的,至于算力中心化确实是个大问题;工作量证明背后的规则,流程等都是在实战区块链的开发及了解其他共识机制前要非常清楚了解的,这对理解区块链来说是一个很重要的基础知识.