原文地址  来自 微信公众号 区块链大师

POW工作量证明(英文全称为Proof of Work)早在比特币出现之前就已经有人探索,常见的是利用HASH运算的复杂度进行CPU运算实现工作量确定,当然你也可以利用卷积求导、大质数分解这些复杂的运算来达到工作量证明的目的(HASH只是pow采用一种算法而已,你可以使用大部分需要迭代运算的算法实现POW,其实稍微改一下pow算法就有可能诞生一种山寨币,然后大肆宣传欺骗小白,了解原理后就知道这并没有什么卵用),随着比特币成功后,POW为人们熟知,基于HASH的pow算法常被人误解为是pow的代名词,为了便于解释pow原理本文还是采用HASH算法作为举例。

定义

(Proof-of-work,工作量证明)最早是一个经济学名词,它是指系统为达到某一目标而设置的度量方法。简单理解就是一份证明,用来确认你做过一定量的工作。监测工作的整个过程通常是极为低效的,而通过对工作的结果进行认证来证明完成了相应的工作量,则是一种非常高效的方式

在1999年,Markus Jakobsson and Ari Juels两人将pow概念引入计算机体系,设计系统用以抵挡拒绝服务攻击和网络爬虫,后来在反垃圾邮件中被广泛使用。其设计理念是一个正常用户写一封邮件是需要一定的时间,而发送垃圾邮件者是无法接受这个等待的时间,如果pow系统能够使垃圾邮件发送者需要更多的时间来发送邮件,就可以增大他们的成本,起到抵挡攻击的作用。

pow系统中一定有两个角色,工作者和验证者,他们需要具有以下特点:

  • 工作者需要完成的工作必须有一定的量,这个量由工作验证者给出。

  • 验证者可以迅速的检验工作量是否达标。

  • 工作者无法自己"创造工作",必须由验证者发布工作。

  • 工作者无法找到很快完成工作的办法。

pow历史

工作量证明,是一种应对拒绝服务攻击和其他服务滥用的经济对策。它要求发起者进行一定量的运算,也就意味着需要消耗计算机一定的时间。这个概念由Cynthia Dwork 和Moni Naor 1993年在学术论文中首次提出。而工作量证明(POW)这个名词,则是在1999年 Markus Jakobsson 和Ari Juels的文章中才被真正提出。

哈希运算是一种最常见的工作量证明机制,它是亚当·贝克(Adam Back)在1997年发明的,用于抵抗邮件的拒绝服务攻击及垃圾邮件网关滥用。在比特币之前,哈希现金被用于垃圾邮件的过滤,也被微软用于hotmail/exchange/outlook等产品中(微软使用一种与哈希现金不兼容的格式并将之命名为电子邮戳)。

该机制主要利用HASH运算的复杂度,通过给定的初始值,通过简单的值递增规律,利用HASH碰撞原理,直到找到特定的碰值,可以通过调节碰撞值得长度,实现对于工作量的调节(碰撞值越长,所需要的运算量越大)

哈希现金也被哈尔·芬尼以可重复使用的工作量证明(RPOW)的形式用于一种比特币之前的加密货币实验中。另外,戴伟的B-money、尼克·萨博的比特金(Bit-Gold)这些比特币的先行者,都是在哈希现金的框架下进行挖矿的。

哈希现金扫盲

哈希现金HashCash是最典型的Solution-verification实现,HashCash也是目前应用最为广泛的反垃圾邮件的pow系统。

在HashCash系统中,发件方向邮箱服务器发送的邮件信息中必须包含一段邮件签名,邮件签名中包含有收件人地址、发件时间和一个数字counter,counter需要使邮件签名满足条件:

利用SHA-1散列算法对邮件签名生成一个160-bit长度的哈希值,该哈希值前20位全为0 。此算法利用了散列算法的不可预测性,SHA-1的碰撞概率决定了算法的安全性。

在目前的认知中,发件方除了穷举尝试,无法很快的找到满足条件的签名串。于是发件方在发送邮件之前的工作就是不断地counter++生成新的邮件签名,然后获取SHA-1哈希值,判断前20位是否全为0,如果不是的话重新生成。而对于邮件服务器而言,只需要做一次SHA-1判断生成的签名是否满足条件即可,完全符合POW易于验证的定义。

算法简介

发送方签名:
counter = 0;

while(1) {
result = SHA1(mailAdress + time + counter);
if (result.substring(0, 20) == "00000000000000000000") {
break;
}
counter++;
}
sig = mailAdress + time + counter;
服务端验签:
if (SHA1(sig).substring(0, 20) == "00000000000000000000") {
return true;
}

散列函数如SHA-1是基本均匀分布的,对于我们生成的每一个邮件签名来说,对应的的哈希值在每一位上出现0和1的概率应该是相同的,SHA-1生成的160-bit哈希结果,其所有的可能是 2^160 种,而前20位固定为0的情况有 2^140 种,所以每次生成的邮件签名符合条件的概率为: 2^140 / 2^160 = 1/2^20

问题一,解空间必然存在,解空间的大小为2^140。

问题二,每一次生成邮件签名命中的概率为 1/2^20 ,客户端平均需要运算 2^20 次就能找到正确答案,运算时间为: PerSHA1Time*2^20 。

问题三,服务器端需要丢弃掉已经出现过的答案,同时需要对收件人地址和时间戳做合法性校验即可。

HASH POW原理

工作量证明系统主要特征是客户端需要做一定难度的工作得出一个结果,验证方却很容易通过结果来检查出客户端是不是做了相应的工作。这种方案的一个核心特征是不对称性:工作对于请求方是适中的,对于验证方则是易于验证的。它与验证码不同,验证码的设计出发点是易于被人类解决而不易被计算机解决。

下图表示的是工作量证明的流程:

举个例子,给定的一个基本的字符串"Hello, world!",我们给出的工作量要求是,可以在这个字符串后面添加一个叫做nonce的整数值,对变更后(添加nonce)的字符串进行SHA256哈希运算,如果得到的哈希结果(以16进制的形式表示)是以"0000"开头的,则验证通过。为了达到这个工作量证明的目标。我们需要不停的递增nonce值,对得到的新字符串进行SHA256哈希运算。按照这个规则,我们需要经过4251次计算才能找到恰好前4位为0的哈希散列。

"Hello, world!0" => 1312af178c253f84028d480a6adc1e25e81caa44c749ec81976192e2ec934c64

"Hello, world!1" => e9afc424b79e4f6ab42d99c81156d3a17228d6e1eef4139be78e948a9332a7d8

"Hello, world!2" => ae37343a357a8297591625e7134cbea22f5928be8ca2a32aa475cf05fd4266b7
...
"Hello, world!4248" => 6e110d98b388e77e9c6f042ac6b497cec46660deef75a55ebc7cfdf65cc0b965 "Hello, world!4249" => c004190b822f1669cac8dc37e761cb73652e7832fb814565702245cf26ebb9e6 "Hello, world!4250" => 0000c3af42fc31103f1fdc0151fa747ff87349a4714df7cc52ea464e12dcd4e9

通过这个示例我们对工作量证明机制有了一个初步的理解。有的人会认为如果工作量证明只是这样的一个过程,那是不是只需要记住nonce为4521计算能通过验证就行了?当然不是的,这只是一个个例。

下面,我们将输入简单的变更为"Hello, world+整数值",整数值取1到1000,也就是说,将输入变成一个由1000个值组成的数组:“Hello, world!1、Hello, world!2……Hello, world!1000”。然后对数组中的每一个输入依次进行上面例子中要求的工作量证明——找到前导为4个0的哈希散列。

容易算出,预期大概要进行216次尝试(哈希值的伪随机特性使得我们可以做概率估算),才能得到4个前导0的哈希散列。而统计一下刚才进行的1000次计算的实际计算结果,我们会发现,进行计算的平均次数为66958次,十分接近216(65536)。在这个例子中,数学期望的计算次数,就是我们要求的“工作量”,重复多次进行的工作量证明会是一个符合统计学规律的概率事件。

统计输入的字符串与对应得到目标结果实际使用的计算次数列表如下:


Hello, world!1 => 42153
Hello, world!2 => 2643
Hello, world!3 => 32825
Hello, world!4 => 250
Hello, world!5 => 7300
...
Hello, world!995 => 164819
Hello, world!996 => 178486
Hello, world!997 => 22798
Hello, world!998 => 68868
Hello, world!999 => 46821

比特币体系里的工作量证明机制与上述示例类似,但要比它更复杂一些,以后会另起文章说明

详解POW工作量证明原理的更多相关文章

  1. 淘宝JAVA中间件Diamond详解(2)-原理介绍

    淘宝JAVA中间件Diamond详解(二)---原理介绍 大家好,通过第一篇的快速使用,大家已经对diamond有了一个基本的了解.本次为大家带来的是diamond核心原理的介绍,主要包括server ...

  2. [转帖]万字详解Oracle架构、原理、进程,学会世间再无复杂架构

    万字详解Oracle架构.原理.进程,学会世间再无复杂架构 http://www.itpub.net/2019/04/24/1694/ 里面的图特别好 数据和云 2019-04-24 09:11:59 ...

  3. Go实现Pow工作量证明

    之前使用python编写了一段代码实现了工作量证明机制,近期由于参与以太坊智能合约开发钱包的工作接触到golang语言,所以借此以go来实现Pow(Proof of work). 实现代码如下: // ...

  4. SpringCloud 详解配置刷新的原理 使用jasypt自动加解密后 无法使用 springcloud 中的自动刷新/refresh功能

    之所以会查找这篇文章,是因为要解决这样一个问题: 当我使用了jasypt进行配置文件加解密后,如果再使用refresh 去刷新配置,则自动加解密会失效. 原因分析:刷新不是我之前想象的直接调用conf ...

  5. [转帖]详解Linux系统inode原理--硬链接、软链接、innodb大小和划分等

    详解Linux系统inode原理--硬链接.软链接.innodb大小和划分等 原创 波波说运维 2019-07-17 00:03:00 https://www.toutiao.com/i6713116 ...

  6. RocketMQ详解(一)原理概览

    专题目录 RocketMQ详解(一)原理概览 RocketMQ详解(二)安装使用详解 RocketMQ详解(三)启动运行原理 RocketMQ详解(四)核心设计原理 RocketMQ详解(五)总结提高 ...

  7. 详解PHP的执行原理和流程

    简介 先看看下面这个过程: • 我们从未手动开启过PHP的相关进程,它是随着Apache的启动而运行的: • PHP通过mod_php5.so模块和Apache相连(具体说来是SAPI,即服务器应用程 ...

  8. sed 增删改查详解以及 sed -i原理

    我为什么要详细记录sed命令:     sed 擅长取行.工作中三剑客使用频率最高,本篇文章将对sed命令常用的 增,删,改,查 进行详细讲解,以备以后工作中遗忘了查询,sed命令是作为运维人员来说, ...

  9. Android 异步通信:图文详解Handler机制工作原理

    前言 在Android开发的多线程应用场景中,Handler机制十分常用 今天,我将图文详解 Handler机制 的工作原理,希望你们会喜欢 目录 1. 定义 一套 Android 消息传递机制 2. ...

随机推荐

  1. Python Ethical Hacking - BACKDOORS(8)

    Cross-platform hacking All programs we wrote are pure python programs They do not rely on OS-specifi ...

  2. C++语法小记---运算符重载

    运算符重载 运算符重载的本质也是对已有功能的扩展 运算符重载的本质就是函数重载,只是函数变成了 operator + 运算符 当成员函数和全局函数对运算符进行重载时,优先调用成员函数 运算符重载为成员 ...

  3. 题解 洛谷 P4546 【[THUWC2017]在美妙的数学王国中畅游】

    首先发现有连边和删边的操作,所以我们肯定要用\(LCT\)来进行维护. 接下来考虑如何进行\(LCT\)上的信息合并. \(f=1\),则函数为\(f(x)=sin(ax+b)\) \(f=2\),则 ...

  4. 理解Spring(二):AOP 的概念与实现原理

    目录 什么是 AOP AOP 的基本术语 Spring AOP 的简单应用 Spring AOP 与动态代理 Spring AOP 的实现原理(源码分析) 扩展:为什么 JDK 动态代理要求目标类必须 ...

  5. 使用queue 做一个分布式爬虫(一)

    这个作为调配的 taskMaster.py #!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2018/12/23 15:21 # @au ...

  6. vue图片上传的简单组件

    <template> <div class="rili" id="rili"> <div class="updel&qu ...

  7. 从Python开始学编程|PDF百度网盘免费下载|Python新手入门

    百度网盘免费下载:从Python开始学编程|附PDF免费下载 提取码:7nkf 豆瓣评分: 本书封面: 读者评论: 内容简介  · · · · · · 改编自Vamei博客的<Python快速教 ...

  8. Vue脚手架创建项目出现 (Failed to download repo vuejs-templates/webpack: Response code 404)

    搭建好(脚手架2.X版本)环境像往常一样使用vue init webpack xxxx 创建项目可以是没多久就开始报错了 报错结果就是:vue-cli · Failed to download rep ...

  9. 图解Kubernetes——故障排查指南

    针对越来多的Kubernetes容器云,对Kubernetes集群的故障排查却成了一个棘手问题.本文虫虫给大家以直观图示方式介绍如何排查Kubernetes的故障.该篇是系列文章续——故障排查篇. 概 ...

  10. amazeui 验证按钮扩展

    做一个发送验证码按钮,点击后要60秒之后才能再次点击,利用原有的amazeui样式做的一些扩展,当然主题功能的代码全都是自己写的,也可以脱离amazeUi 自己完成这个功能按钮 代码如下: <! ...