简介

POW是proof-of-work的缩写,中译为:工作量证明,是比特币中采用的共识机制,也被许多公有区块链系统所采用(比如以太坊)。工作量证明机制基础是哈希运算,因此要理解pow首先要明白哈希函数(比特币大量采用了sha256,以及rimped160)。

本篇文章重点介绍pow共识算法的原理,不具体介绍比特币的相关细节。

什么是哈希函数?

哈希运算是密码学的重要组成部分,一般用来保护数据的完整性。给定一段消息,通过哈希函数可以将消息映射为固定长度的哈希值(比如sha256,将任意长度的消息映射为256位的哈希值)。哈希函数具有两个重要的特点:“无碰撞“和”不可逆“。

1. 所谓不可逆,就是当你知道x的HASH值,无法求出x;因此哈希函数在数学上是一种单向函数。
2. 所谓无冲突,就是当你知道x,无法求出一个y, 使x与y的HASH值相同。简单来说就是,无法找到一个不同的消息y,使得y的哈希值与x的哈希值相同。(当然,因为消息的比特空间 << 所求哈希值的比特空间,因此其实这样的y是存在的,只是这样的y很难找,只是一个概率上的不可能)

哈希函数的应用

从哈希函数的特性我们可以看出,当x被改变时,x所对应的哈希值也会发生改变,因此可以通过一段消息的哈希值是否改变来间接反应消息是否被修改,也就是我们说的数据完整性验证。(当然这个一般还要也公钥密码体制相结合来使用,这里不解释公钥密码体制,自行google)。

### 在比特币中的使用

比特币主要使用了sha256哈希函数,有三个用途:

1. 比特币地址是公钥的两次sha256运算结果

2. 保证每笔交易的完整性

3. pow工作量证明机制的基础

比特币共识算法

pow工作量证明机制,我们从“工作量”和“证明”两个概念上来理解pow。

1. 什么是工作量?

比特币一直被人诟病做了大量无意义的运算,耗费了巨量的电能。这里的运算就是比特币共识机制中的工作量,而这个运算就是哈希运算。具体是下面的运算:

 SHA256(SHA256(Block_Header))

这里的Block_Header可以简单理解为:一堆比特币交易txs + 一个随机数数nonce。在生成比特币区块的时候,我们可以认为txs是固定的,因此pow可以简化为:选取随机数nonce,然后求SHA256(SHA256(txs || nonce)),我们下面把这个计算叫做POWHash。

这个不断重复选取随机数nonce,计算POWHash的过程什么时候结束呢?在比特币中POWHash的前n位为0的时候,我们认为找到了一个有效的nonce,然后就可以生成比特币区块并广播给其他的矿工。这里的n是一个可调节的数,比特币中没生成2016个块,会重新调整n,n越大有效的POWHash越难计算,相反越容易。

2. 怎么证明?

pow中的证明值得是验证nonce是否有效,同样是计算SHA256(SHA256(txs || nonce)),不过这里的txs和nonce都是已知的,我们把运算结果记为POWHash‘,我们只需要验证POWHash’是否满足前n为0,就可以证明这个区块是不是一个有效的比特币区块。

通过分析我们发现,如果要伪造交易(修改txs),需要重新找到一个nonce,因此对于非法修改区块,需要重新进行大量哈希运算来找到一个有效的nonce。由于每个区块都包含前一个区块的hash值,因此后面所有的区块都需要重新进行调整。因此修改比特币中的交易信息是计算上不可能的。

--------------------------------Talk is cheap, show me your code-------------------------------

下面是简单的pow实现,仅供参考

var (

 target, _ = new(big.Int).SetString("ffffffffffffffff", ) //64bits

)

func pow(merkelRootHash, previousHash []byte, difficulty int, h hash.Hash) {

 target = target.Rsh(target, uint(difficulty))

 //variable to computed. 1. from the beginning 0, 2. random a nounce. Here we choose 1.

 nounce := new(big.Int).SetInt64()

 for {

  //time stamp

  now := fmt.Sprintf("%v", time.Now())

  var header []byte

  header = append(header, []byte(now)...)

  header = append(header, previousHash...)

  header = append(header, merkelRootHash...)

  header = append(header, nounce.Bytes()...)

  h.Write(header)

  res := new(big.Int).SetBytes(h.Sum(nil)[:]) //substract first 8*8 bits from sha256

  if res.Cmp(target) <  {

     fmt.Printf("%b\n", nounce) //found a valid nonce, print it.

     break

  }

  nounce.Add(nounce, new(big.Int).SetUint64())

 }

}

----------------------------------End Line-------------------------------------------------


共识算法之POW的更多相关文章

  1. [转帖][区块链]共识算法(POW,POS,DPOS,PBFT)介绍和心得

    [区块链]共识算法(POW,POS,DPOS,PBFT)介绍和心得 置顶 2017-03-12 18:31:19 乐扣老师lekkoliu 阅读数 127953  收藏 更多 分类专栏: 技术管理 区 ...

  2. Bystack的高TPS共识算法

    共识算法是分布式系统保证节点数据状态一致性的方法,在区块链的共识算法分POW(工作量证明)和POS(权益证明)两大类.第一类POW模式是在公链项目中运用的最广泛应用的共识算法,比特币长达10年的运行已 ...

  3. [区块链] 共识算法之争(PBFT,Raft,PoW,PoS,DPoS,Ripple)

    近几天对区块链中几种常见的共识机制(PBFT,Raft,PoW,PoS,DPoS,Ripple)进行了总结.尽量使用简单易懂语言,篇幅较大,想了解的可以只读每个算法介绍中前边的原理.本篇文章主要参考& ...

  4. Pow共识算法

    谈到哈希算法,每个程序员都不陌生,但是谈到比特币共识算法PoW,如果没有接触过的技术人员可能觉得应该会很复杂,毕竟全球的比特币节点数量如此庞大,达成共识的算法应该不会很简单.但其实如果你已掌握哈希算法 ...

  5. 区块链知识博文1: 共识算法之争(PBFT,Raft,PoW,PoS,DPoS,Ripple)

    注:这是本人读到的关于共识算法最全和最好的分享博文,系统的介绍了拜占庭容错技术以及共识算法的原理和常用共识算法,原文链接请见后. 目录 一.拜占庭容错技术(Byzantine Fault Tolera ...

  6. 区块链共识机制(POW、POS、DPOS等)的优缺点

    一.POW:工作量证明机制 基本原理: 第一代共识机制,比特币的基础.理解起来,很简单,就是“按劳取酬”,你付出多少工作量,就会获得多少报酬(比特币等加密货币).在网络世界里,这里的劳动就是你为网络提 ...

  7. go-ethereum源码分析 PartII 共识算法

    首先从共识引擎-Engine开始记录 Engine是一个独立于具体算法的共识引擎接口 Author(header) (common.Address, error) 返回打包header对应的区块的矿工 ...

  8. (二)区块链的共识算法:PoS 及其 例子 代码 实现

    作者:林冠宏 / 指尖下的幽灵 掘金:https://juejin.im/user/587f0dfe128fe100570ce2d8 博客:http://www.cnblogs.com/linguan ...

  9. 区块链共识机制:POW、POS、DPOS、PBFT、POOL

    共识机制作为区块链的关键技术之一,在业务吞吐量.交易速度.不可篡改性.准入门槛等等方面发挥重要的作用. 区块链是去中心化的,没有中心记账节点,所以需要全网对账本达成共识.目前有POW.POS.DPOS ...

随机推荐

  1. Django手册

    Django教程 Python一直是我最喜欢的语言,在Django和Tornado之间我选择了前者,没有特别的原因,网上人云亦云的,肯定不会有一方离另一方差很远,我就直接去看了看Github上两个项目 ...

  2. drf4 视图与路由组件

    APIView和View的区别 不管是View还是APIView最开始调用的都是as_view() APIView继承了View, 并且执行了View中的as_view()方法,最后把view返回了, ...

  3. B - Dropping tests

    In a certain course, you take n tests. If you get ai out of bi questions correct on test i, your cum ...

  4. Android Studio中的大量findViewById

    一. 分析 在Android Studio中开发时,findViewById是用的最多的函数之一.经常需要对返回的view进行类型转换,输入麻烦.代码丑陋. 本文提供两种方案来解决这个问题: 1.安装 ...

  5. 关于 redis的操作

    1.修改配置文件 redis.conf是redis的配置文件,redis.conf在redis源码目录. 注意修改port作为redis进程的端口,port默认6379.如果需要搭建redis集群,千 ...

  6. 优化版小程序canvas,增加失败逻辑,及完善文字

    wxml <view class="shareBox" style="backgound:{{isShow ? '#000' : '#fff'}}" wx ...

  7. Javascript百学不厌 - 模块模式

    记录自己觉得重要又可能忘记的东西 用模块模式产生安全的对象: var serial_maker = function () { var preifx = ''; var seq = 0; return ...

  8. kill 结束进程

    kill 支持的信号 kill -1 重启进程 kill -9 终止进程 pkill 和 killall 的区别在于pkill 可以踢终端用户 pkill  -9  -t tty1

  9. Appium同时连接多台手机进行测试(多线程)

    作为测试小白,当时遇到了N多问题: 开启多线程后,发现app启动后,用例就停止了:且启动app对应的手机不能正确对应,用例中是A手机跑A用例,结果启动了B手机跑A用例报错. 主要原因:Appium S ...

  10. Typescript 学习笔记六:接口

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...