精华内容
下载资源
问答
  • 工作量证明

    2018-05-27 19:36:23
    工作量证明(Proof Of Work,简称POW),简单来讲就是证明你完成了某一项工作。维基百科的解释:工作量证明系统是一种防止服务攻击及其它服务滥用的经济方式,它要求服务请求方完成某些工作——通常意味着需要请求方...
        

    一. 简介

    工作量证明(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
    展开全文
  • 工作量证明共识机制

    2021-01-20 13:57:36
    比特币的去中心网络采用的是工作量证明共识机制。 去中心网络之所以需要共识机制,是因为这是一个非基于信任(non-trust-based)的网络,任何人无须许可都可以接入这个网络。并且,这些节点分散在网络条件差异非常大...
  • 2.2 工作量证明

    2018-11-08 15:33:52
    Proof-of-Work 工作量证明 区块里有一个非常关键的点,就是节点必须执行足够多且困难的运算才能将数据新增在区块中。这一困难的运算保证了区块链安全、一致。而为了奖励这一运算,该节点会获得数字货币(如比特币)...

    Proof-of-Work 工作量证明

    区块里有一个非常关键的点,就是节点必须执行足够多且困难的运算才能将数据新增在区块中。这一困难的运算保证了区块链安全、一致。而为了奖励这一运算,该节点会获得数字货币(如比特币)的奖励(从运算到收到奖励的过程,也叫作挖矿)。 
    这一机制和现实生活中也是相似的:人们辛苦工作获取报酬来维持生活,在区块链中,链络中的参与者(比如矿工)辛苦运算来维系这个区块链网络,不断增加新的区块到链络中,然后获取回报。正是因为这些运算,新的区块基于安全的方式加到区块链中,保证了区块链数据库的稳定。 
    是不是发现了什么问题呢?大家都在计算,凭什么怎么证明你做的运算就是对的,且是你的。 
    努力工作并证明(do hard work and prove),这一机制被称为工作量证明。需要多努力呢,需要大量计算机资源,即使使用高速计算机也不能做得快多少。而且,随着时间的推移,难度会越来越大,因为要保证每小时有6个区块的诞生,越到后面,区块越来越少,要保证这个速率,只能运算更多,提高难度。在比特币中,运算的目标是计算出一串符合要求的hash值。而这个hash就是证明。所以说,找到证明(符合要求的hash值)才是实际意义上的工作。 
    工作量证明还有一个重要知识点。也即工作困难,而证明容易。因为如果你的工作困难,而证明也困难,那么你的工作在圈子效率意义就不大,对于需要提供给别人证明的工作,别人证明起来越简单就越好。

    Hash 哈希

    Hash运算是区块链最主要使用的工作算法。哈希运算是指给特殊数据计算一串hash字符的过程。对于一笔数据而言,它的hash值是唯一的。hash函数就是可以把任意大小的数据计算出指定大小hash值的函数。 
    Hash运算有以下几个主要的特点: 
    1. 原始数据不能从hash值中逆向计算得到 
    2. 确定的数据只有一个hash值且这个hash值是唯一的 
    3. 改变数据的任一byte都会造成hash值变动

    Hash运算广泛应用于数据一致性的验证。很多线上软件商店都会把软件包的hash值公开,用户下载后自行计算hash值后验证和供应商的是否一致,就可判断软件是否被篡改过。 
    在区块链中,hash也是用于保证数据的一致性。区块的数据,还有区块的前一区块的hash值也会被用于计算本区块的hash值,这样就保证每个区块是不可变:如果有人要改动自己区块的hash值,那么连他后面的区块hash也要跟着改,这显然是不可能的或者极其困难的(要说服不是自己的区块一同更改很困难)。

    Hashcash 哈希现金

    比特币中的工作证明使用的是Hashcash技术,起初,这一算法开发出来就是用于防止垃圾电子邮件。它的工作主要有以下几个步骤: 
    1. 获取公开的信息,比如邮件的收件人地址或者比特币的头部信息 
    2. 增加一个起始值为0的计数器 
    3. 计算出第1步中的信息+计数器值组合的hash值 
    4. 按规则检测hash值是否满足需求(一般是指定前20位是0) 
    1. 满足 
    2. 不满足则重复3-4步骤 
    这个算法看上去比较暴力:改变计数器值,计算新的hash,检测,增加计数器值,计算新的hash…,所以这个算法比较昂贵。 
    邮件发送者预备好邮件头部信息然后附加用于计算随机数字计数值。然后计算160-bit长的hash头,如果前20bits 
    现在进一步分析区块链hash运算的要求。在原始的hashcash实现中,必须根据头信息算出前20位为0的hash值。而在比特币中,这一规则则是根据时间的推移变动的,因为比特币的设计就是10分钟出一块新区块,即使计算机算力提升或者更多的矿工加入挖矿行列中也不会改变,也就是说,算出hash值,会越来越困难。 
    下面演示这一算法,和上面第一张图一样使用“I like donuts”作为数据,再在数据后加面附加计数器,然后使用SHA256算法找出前面6位为0的hash值。

    而ca07ca就是不停运算找到的计数器值,转换成10进制就是13240266,换言之大概执行了13240266次SHA256运算才找到符合条件的值。

    实现

    上面花了点篇幅介绍了工作量证明的原理。现在我们用Golang来实现。先定24位0的作为挖矿的难度: 
    const targetBits = 24 
    注:在比特币挖矿中,头部中的target bits存储该区块的挖矿难度,但是上面说过随着时间推移难度越来越大,所以这个target大小是会变的,这里不实现target的适配算法,这不影响我们理解挖矿。现在只定义一个常量作为全局的难度。 
    当然,24也是比较随意的,我们只用在内存中占用少于256bits的的空间。差异也要大些,但是也不要太大,太大了就就很难找出来一个合规的hash。 
    然后定义ProofOfWork结构:

    type ProofOfWork struct {
      block  *Block
      target *big.Int
    }
    func NewProofOfWork(b *Block) *ProofOfWork {
      target := big.NewInt(1)
      target.Lsh(target, uint(256-targetBits))
    pow := &ProofOfWork{b, target}
    return pow
    }

    ProofOfWork 有“block”和“target”两个成员。“target”就是上面段落中描述的hashcash的规则信息。使用big.Int是因为要把hash转成大整数,然后检测是否比target要小。

    NewProofOfWork 函数负责初始化target,将1往左偏移(256-targetBits)位。256是我们要使用的SHA-256标准的hash值长度。转换成16进制就是:

    0x10000000000000000000000000000000000000000000000000000000000

    这会占用29位大小的内存空间。

    现在准备创建hash的函数:

    func (pow *ProofOfWork) prepareData(nonce int) []byte {
      data := bytes.Join(
        [][]byte{
          pow.block.PrevBlockHash,
          pow.block.Data,
          IntToHex(pow.block.Timestamp),
          IntToHex(int64(targetBits)),
          IntToHex(int64(nonce)),
        },
        []byte{},
      )
    return data
    }

    这段代码做了简化,直接把block的信息和target、nonce合并在一起。nonce就是Hashcash中的counter,nonce(现时标志)是加密的术语。 
    准备工作都OK了,现在实现PoW的核心算法:

    func (pow *ProofOfWork) Run() (int, []byte) {
      var hashInt big.Int
      var hash [32]byte
      nonce := 0
    fmt.Printf("Mining the block containing \"%s\"\n", pow.block.Data)
      for nonce < maxNonce {
        data := pow.prepareData(nonce)
        hash = sha256.Sum256(data)
        fmt.Printf("\r%x", hash)
        hashInt.SetBytes(hash[:])
    if hashInt.Cmp(pow.target) == -1 {
          break
        } else {
          nonce++
        }
      }
      fmt.Print("\n\n")
    return nonce, hash[:]
    }

    hashInt是hash值的int形式,nonce是计数器。然后执行math.MaxInt64次循环直到找符合target的hash值。为什么是math.MaxInt64次,其实这个例子中是不用的考虑这么大的,因为我们示例中的PoW太小了以致于还不会造成溢出,只是编程上要考虑一下,当心为上。 
    循环体内工作主要是: 
    1. 准备块数据 
    2. 计算SHA-256值 
    3. 转成big int 
    4. 与target比较 
    将上一篇中的NewBlock方法改造一下,扔掉SetHash方法:

    func NewBlock(data string, prevBlockHash []byte) *Block {
      block := &Block{time.Now().Unix(), []byte(data), prevBlockHash, []byte{}, 0}
      pow := NewProofOfWork(block)
      nonce, hash := pow.Run()
    block.Hash = hash[:]
      block.Nonce = nonce
    return block
    }

    新增了nonce作为Block的特性。nonce作为证明是必须要带的。现在Block结构如下:

    type Block struct {
      Timestamp     int64
      Data          []byte
      PrevBlockHash []byte
      Hash          []byte
      Nonce         int
    }

    然后执行 go run *.go

    start: 2018-03-07 14:43:31.691959 +0800 CST m=+0.000721510
    Mining the block containing "Genesis Block"
    0000006f3387b588739cbcfe2cce521fcce27d4306776039e02c2904b116ab9a
    end:  2018-03-07 14:44:32.488829 +0800 CST m=+60.798522580
    elapsed time:  1m0.797798933s
    start: 2018-03-07 14:44:32.489057 +0800 CST m=+60.798750578
    Mining the block containing "Send 1 BTC to Ivan"
    000000e9d5a266faa6a86f56a36ea09212ecad28e524a8b0599589fd5b800d13
    end:  2018-03-07 14:46:32.996032 +0800 CST m=+181.307571128
    elapsed time:  2m0.508818203s
    start: 2018-03-07 14:46:32.996498 +0800 CST m=+181.308036527
    Mining the block containing "Send 2 more BTC to Ivan"
    0000001927685501c59f28c0bda3fdd0472e88d6eec3822b0ab98e5b1c28c676
    end:  2018-03-07 14:46:53.90008 +0800 CST m=+202.211938702
    elapsed time:  20.903900066s

    可以看到生成了前6位都是0的hash字符串,因为是16进制的,就是24一位,共4*6=24位,也就是我们设置的targetBits。从时间上可以看到,计算出hashcash的时间有一定的随机性,多着2分,少则20秒。 
    现在还需要去验证是否是正确的。

    func (pow *ProofOfWork) Validate() bool {
      var hashInt big.Int
      data := pow.prepareData(pow.block.Nonce)
      hash := sha256.Sum256(data)
      hashInt.SetBytes(hash[:])
      isValid := hashInt.Cmp(pow.target) == -1
      return isValid
    }

    可以看到,nonce在验证是要用到的,告诉对方也用我们计算出来的数据进行二次计算,如果对方计算的符合要求,说明我们的计算合法。 
    把验证方法加到main函数中:

    func main() {
      ...
    for _, block := range bc.blocks {
        ...
        pow := NewProofOfWork(block)
        fmt.Printf("PoW: %s\n", strconv.FormatBool(pow.Validate()))
        fmt.Println()
      }
    }

    结果:

    Prev. hash:
    Data: Genesis Block
    Hash: 0000006f3387b588739cbcfe2cce521fcce27d4306776039e02c2904b116ab9a
    PoW: true
    Prev. hash: 0000006f3387b588739cbcfe2cce521fcce27d4306776039e02c2904b116ab9a
    Data: Send 1 BTC to Ivan
    Hash: 000000e9d5a266faa6a86f56a36ea09212ecad28e524a8b0599589fd5b800d13
    PoW: true
    Prev. hash: 000000e9d5a266faa6a86f56a36ea09212ecad28e524a8b0599589fd5b800d13
    Data: Send 2 more BTC to Ivan
    Hash: 0000001927685501c59f28c0bda3fdd0472e88d6eec3822b0ab98e5b1c28c676
    PoW: true

    本章总结 
    本章我们的区块链进一步接近实际的结构:增加了计算难度,这意味着挖矿成为可能。不过还是欠缺了一些特性,比如没有把计算出来的数据持久化,没有钱包(wallet)、地址、交易,以及实现一致性机制。接下来的几篇abc中,我们会持续完善。

     

    展开全文
  • PoW工作量证明

    2019-09-19 14:48:53
    PoW是Proof of Work的缩写,即工作量证明的意思。在《拜占庭将军问题》中介绍过,比特币系统中引入了“工作量”的概念,有意降低了信息传递的效率,让矿工必须完成一定的工作量,才能够在全网广播消息。 (孩子第一...

    链客,专为开发者而生,有问必答!

    此文章来自区块链技术社区,未经允许拒绝转载。
    在这里插入图片描述
    PoW是Proof of Work的缩写,即工作量证明的意思。在《拜占庭将军问题》中介绍过,比特币系统中引入了“工作量”的概念,有意降低了信息传递的效率,让矿工必须完成一定的工作量,才能够在全网广播消息。

    (孩子第一次为我的文章配图,厉害吧)

    以工地的搬砖任务为例,一群工人们(矿工)向火车的车皮(区块)里搬砖,每个工人身边都有一个集装箱,这个集装箱与火车车皮一样大,正好能够装满1000块砖。

    工人们只能往集装箱里搬砖,谁先装满集装箱,就把这个集装箱放到车皮里,领取12.5元的工钱(实际上并不是马上拿走,100节车皮之后才能真正取走)。只有第一个搬完的工人能够获得奖励,在这个集装箱放入车皮的同时,其他工人的集装箱里也装了一些砖头了,全部作废,重新搬砖,继续投入到下一节车皮的竞争中。

    比特币世界里的矿工(工人)也是这样辛苦,这里的矿工是一堆安装了专门芯片的电脑,它们的工作就是进行HASH计算(准确讲是SHA256,高级搬砖工作),谁先算完,写入一个新区块(车皮),得到奖励的12.5个BTC(发行新币),其它矿工则白忙活,继续进行下一轮的竞争。

    因为电脑的计算速度太快,所以要安排上亿次的HASH计算,保证有矿工在10分钟左右能够完成任务。这种工作量,既是一种发行货币的过程,也是一种验证其他人交易的过程,从而保证了整个比特币系统的安全性。

    简化的计算过程

    假设我有一个区块信息是“abcde",要在其后面补一个随机数,使得HASH结果以0开头。我在“区块链生存训练”饭团里介绍过HASH的作用,HASH的加密特性使得原始数据即使发生极其微小的改变,得到的结果也有巨大不同。

    所以我只能一个数一个数地尝试,一直试到随机数5的时候,此时的字符串为”abcde5",SHA256的HASH结果为051f2f…d7b9e1,以0开头,我找到了一个解,我就可以把"abcde5"加到新区块上,拿走12.5个BTC。

    区块链正如其名,是一个区块与另一个区块链接起来而成的,一个区块中用于参与工作量计算的主要有三部分数据(为了说明HASH计算的工作量,我对整个计算过程进行了极大地简化,更详细的细节请自行参考《精通比特币》):

    1)父区块HASH:用于指向父区块,当一个区块一个区块地链接起来后,想篡改一个区块,会影响子区块,再会影响孙区块,从而带来指数级的巨大计算量,从而使篡改几乎不可能。

    2)交易信息指纹:一个区块内通常有几百笔的交易信息,也用HASH算法产生一个指纹(准确地讲是Merkle树,以后再介绍),只占用32个字节。

    3)随机数nonce:矿工所做的事就是找这个nonce,通过不断地尝试变化这个nonce,进行上亿次的HASH计算,得到满足要求的结果。

    假设父区块HASH为“abc",交易HASH值为”de",不断变化nonce,计算HASH值,假设nonce=5时,满足工作量目标(以一个0开头,这个术语以后再解释),获得到了全球共享大账本的记账权,然后将这个区块广播出去。

    其它矿工收到这个区块后,首先要进行验证,验证别人是不是经过了大量计算并满足目标,而这个验证的计算量则非常非常小,0.001秒都不用。

    就像前面说的搬砖一样,搬1000块砖的过程非常辛苦,但其它工人只需扫一眼就知道他是否完成了工作量(因为1000块砖正好装满一个集装箱),其它工人一看集装箱放到了车皮上(产生了新区块),则放弃当前的一箱砖,开始新一轮的工作(下一区块的竞争)。

    小结:

    工作量证明既用于发币,也是验证交易的有效性,保证比特币的安全
    计算过程中不断调整nonce,要进行数亿至万亿次的HASH运算
    先完成计算的获得记账权,写入一个新区块,向外广播
    其它矿工只用非常非常少的计算量就可以完成验证
    竞争失败的矿工,取得最新区块信息,开始新一轮竞争
    我在5月23日开办了“区块链生存训练”饭团,现在成员超过180人,已经讲解了众多概念:比特币地址、Block区块、区块链、确认、Mining挖矿、矿工费、HASH哈希、矿工、工作量证明、私钥、公钥、交易、钱包、PressOne、ICO等等,并且饭团内还有热烈的讨论。有人预测区块链将是未来的价值互联网的基础协议,想要活在未来,就要尽早学习这些内容。

    展开全文
  • 工作量证明挖矿

    2018-09-22 17:39:29
    给予区块难度意义的算法叫做工作量证明(PoW)。 以太坊的工作量证明算法称之为“Ethash” (之前叫做Dagger-Hashimoto)。 算法正式定义为: m代表的是mixHash,n代表的是nonce,Hn代表的是新区块的头(不包含...

    在“区块”这个章节简短的说明了一下区块难度这个概念。给予区块难度意义的算法叫做工作量证明(PoW)。

    以太坊的工作量证明算法称之为“Ethash” (之前叫做Dagger-Hashimoto)。

    算法正式定义为:

    m代表的是mixHash,n代表的是nonce,Hn代表的是新区块的头(不包含需要计算的nonce和mixHash),Hn是区块头的nonce,d是DAG ,就是一个大数据集。

    在”区块”章节,我们讨论了存在于区块头中的多项。其中两项叫做mixHash和nonce。也许你会回忆起:

    PoW函数就是用来估算这两项的。

    mixHash和nonce到底是如何使用PoW函数来计算出来的有点复杂,如果深入了解的话,我们可以另写一篇文章来讲解了。但是在一个高层面上,它大致就是这样计算的:

    会为每个区块计算一个”种子”。每个“时期”的种子都不一样,每个时期是30,000个区块长度。对于第一时期,种子就是32位0的hash值。对于后续的每个时期,种子就是前一个种子hash值的hash值。使用这个种子,节点可以计算一个伪随机“缓存”。

    这个缓存是非常有用的,因为它可以使“轻节点”的概念变成现实,轻节点概念在这篇文章的前面讨论过。轻节点的目的就是让某个节点有能力高效的校验交易而用不着存储整个区块链的数据集。一个轻节点可以仅基于缓存来校验一个交易的有效性,因为缓存可以重新生成需要校验的特定块。

    使用这个缓存,节点可以生成DAG“数据集”,数据集中的每项取决于缓存中少量伪随机选择项。为了成为矿工,你需要要生成全数据集,所有全客户端和矿工都保存这个数据集,并且这个数据集随着时间线性增长。

    然后矿工可以随机抽取数据集中的部分并将它们放入一个数学函数中Hash出一个”mixHash”。矿工会重复生成mixHash直到输出的值小于想要的目标值nonce。当输出的值符合这个条件的时候,nonce就被认为是有效的,然后区块就被添加到链中。

    挖矿作为安全机制

    总的来说,PoW的目的就是以加密安全的方式证明生成的一些输出(也就是nonce)是经过了一定量的计算的。因为除了列举所有的可能性,没有更好的其他方法来找到一个低于要求阈值的nonce。重复应用Hash函数的输出均匀分布,所以我们可以确保,在平均值上,找到满足要求的nonce所需时间取决于难度阈值。难度系数越大,所需时间越长。这样的话,PoW算法就给予难度这个概念的意义了:用来加强区块链的安全。

    我们所说的区块链的安全又是什么意思?这非常简单:我们想要创造一个每个人都信任的区块链。像我们之前在这篇文章中讨论的那样,如果存在超过1条以上的链,用户的信任就会消失,因为他们没有能力合理的确认哪条链才是“有效的”。为了让一群用户接受存储在区块链中的潜在状态,我们需要有一群人信任的一个权威区块链。

    这完完全全就是Pow算法所做的事情:它确保特定的区块链直到未来都一直保持着权威性,让攻击者创造一个新区块来重写某个历史部分(例如清除一个交易或者创建一个假的交易)或者保持一个分叉变得非常困难。为了首先让他们的区块被验证,攻击者需要总是比网络上的其他人要更快的解决掉nonce问题,这样网络就会相信他们的链是最重的链(基于我们之前提到的GHOST协议原则)。除非攻击者拥有超过一半的网络挖矿能力(这种场景也被称为大多数51%攻击 ),要不然这基本上是不可能的。

    挖矿作为财富分配机制

    除了提供一个安全的区块链,PoW同样也是分配财富给那些为提供这个安全而花费自己计算力的人的一种方法。回忆一下,一个矿工挖出一个区块的时候会获得奖励,包括:

    为“获胜”区块提供的5 ether静态区块奖励(马上就会变成3 ether )

    区块中的交易在区块内所消耗的gas

    纳入ommers作为区块的一部分的额外奖励

    为了保证PoW共识算法机制对安全和财富分配的使用是长期可持续的,以太坊努力灌输这两个特性:

    尽可能的让更多的人可访问。换句话说,人们不需要特殊的或者与众不同的硬件来运行这个算法。这样做的目的是为了让财富分配模式变的尽可能的开放,以便任何人都可以提供一些算力而获得Ether作为回报。

    降低任何单个节点(或小组)能够创造与其不成比例的利润可能性。任何可以创造不成比例的利润的节点拥有比较大的影响力来决定权威区块链。这是件麻烦的事情,因为这降低了网络的安全性。

    在区块链网络中,一个与上面两个特性有关的一个问题是PoW算法是一个SHA256哈希函数。这种函数的缺点就是它使用特殊的硬件(也被称之为ASCIs)可以更加快速高效的解决nonce问题。

    为了减轻这个问题,以太坊选择让PoW算法(Ethhash) 提高内存级别难度。意思是此算法被设计为计算出要求的nonce需要大量的内存和带宽。大量内存的需求让电脑平行的使用内存同时计算多个nonce变得极其困难,高带宽的需求让即使是超级电脑同时计算多个nonce也变得十分艰难。这种方式降低了中心化的风险,并为正在进行验证的几点提供了更加公平的竞争环境。

    有一件值得注意的事情是以太坊正在从PoW共识机制渐渐转换为一个叫做“权益证明(PoS)”的共识算法。这就是一个比较野心的话题了,我们希望可以在未来的文章中探索这个话题。

    展开全文
  • 区块链之工作量证明

    2019-09-22 12:01:23
    区块链之工作量证明 在整个区块链中的作用 新的区块依赖工作量证明算法(PoW)| Proof Of Work 来构造 理解 PoW的目标是找出一个符合特定条件的数字,这个数字很难计算出来,但容易验证。 这就是工作量证明的核心...
  • 工作量证明机制(POW)是什么:工作量证明(proof of work)简称POW,是共识机制的一种,可简单理解为一份证明。证明你做过一定量的工作,即通过我查看工作结果就能知道你完成了指定量的工作。比特币挖矿采用的就是...
  • 工作量证明-挖矿

    2021-01-27 11:15:49
    工作量证明-挖矿 1. 定义一个结构(工作量证明) 字段: 区块:block 目标值:target 方法: run计算 功能:找到nonce,从而满足哈希值比目标值小 Sha256(data+nonce变化)<难度值 type ProofOfWork ...
  • 区块链:剖析工作量证明

    万次阅读 2019-04-26 00:26:00
    工作量证明(Proof-of-Work,PoW)一开始发明的时候是用来防止垃圾邮件的。不一会之后,它就被用在电子现金系统中 [作者注1]。 表象之下,PoW 中的挖矿实际上在做的事情就是将动能(电力)转化为一个账本区块。一台...
  • 剖析工作量证明

    2018-11-12 18:35:38
    工作量证明(Proof-of-Work,PoW)一开始发明的时候是用来防止垃圾邮件的。不一会之后,它就被用在电子现金系统中 [作者注1]。 表象之下,PoW 中的挖矿实际上在做的事情就是将动能(电力)转化为一个账本区块。一台...
  • POW-工作量证明机制

    2019-11-22 16:25:06
    工作量证明(Proof Of Work,POW),简单理解就是一份证明,用来确认你做过一定量的工作。检测工作的整个过程通常是极为低效的,而通过对工作的结果进行认证来证明完成了相应的工作量,则是一种非常高效的方式。比如...
  • 基于策略梯度算法的工作量证明中挖矿困境研究
  • 工作量证明算法

    千次阅读 2016-10-20 16:28:50
    [python] view ...区块链中一种工作量证明算法  [python] view plain copy   #!/usr/bin/env python  # example of proof-of-work algorithm  import hashlib  import tim
  • 区块链 - 工作量证明

    2019-11-01 13:18:46
    区块链 – 工作量证明 区块链 – 交易流程与挖矿 区块链 – 矿工的激励 区块链 – 默克尔树(Merkle Tree) 区块链 – 付款确认 区块链 – 处理冲突 区块链 – 用户隐私 区块链 – 防范攻击 区...
  • Go实现Pow工作量证明

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

    千次阅读 2018-05-11 21:58:56
    工作量证明(Proof of Work),顾名思义,即指工作量的证明。PoW机制的基本步骤如下:①节点监听全网数据记录,通过基本合法性验证的数据记录将进行暂存;②节点消耗自身算力尝试不同的随机数,进行指定哈希计算,并...
  • JCryptoNight CryptoNight工作量证明算法的Java本机实现
  • 原文地址 来自 微信公众号区块链大师 POW工作量证明(英文全称为Proof of Work)早在比特币出现之前就已经有人探索,常见的是利用HASH运算的复杂度进行CPU运算实现工作量确定,当然你也可以利用卷积求导、大质数分解...
  • 比特币中的工作量证明 比特币网络中任何一个节点,如果想生成一个新的区块并写入区块链,必须解出比特币网络出的工作量证明的迷题。这道题关键的三个要素是工作量证明函数、区块及难度值。工作量证明函数是这道题的...
  • 什么是工作量证明:1、工作的结果作为数据加入区块链成为一个区块2、完成这个工作的人会获得奖励(这也就是通过挖矿获得比特币)3、整个“努力工作并进行证明”的机制,就叫工作量证明 为什么采用哈希算法:1、不...
  • 工作量证明 VS 权益证明(总结)  工作量证明是最古老、最原始的共识协议,它的十周年纪念日都已经过了。它从 2009 年开始在比特币质押中应用,是最早投入应用的共识协议,它的使用效果非常好。  虽然出现了一些...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,747
精华内容 1,098
关键字:

工作量证明