博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
比特币Pow
阅读量:6418 次
发布时间:2019-06-23

本文共 2819 字,大约阅读时间需要 9 分钟。

想知道更多关于区块链技术知识,请百度【链客区块链技术问答社区】链客,有问必答!!

比特币的出块时间是10分钟左右。每个区块内包含最多8笔交易,这些交易需要被验证和确认,才能实现账户代币的转移。每个挖矿节点做的工作就是去验证和确认这个区块,使区块内的交易得以实现。而他们用的算法就是pow。pow计算的是一个数学运算难题,矿工们首先验证要挖坑区块的合法性,如果合法,他们就开始计算本次挖矿的数学难题,谁第一个做出来并且广播出去,告诉其他矿工我做出来了,你们不用做了。其他矿工们验证你的计算结果和对应的区块,如果大部分的矿工认同你的结果,那么他们将停止挖坑并同步你的数据。区块内的所有交易也就得到认可,实现转账。你的成功挖矿会被比特币激励模块记录,并会给你发送比特币奖励金。

pow算法主要寻找一个随机数(Block里的Nonce值)作为输入,通过改变这个输入,使Block数据不重复变化,Hash函数(一般是sha256)不断计算这个改变后Block的hash值,找出一个特定格式哈希值的过程(即要求有一定数量的前导0),这里找到的值就是当前hash值 < 目标值(Bits),只不过这个比较是在2进制的格式下比较运算的,也就是比较2进制后数字前面0的个数。这个过程就是pow运算过程。而要求的前导0的个数越多,代表难度越大。在将pow算法之前,先学习下区块信息。

区块

如下图所示

从图上可知,比特币区块结构分为区块头和区块体,区块体保存交易的具体信息,由它生成的hash保存在区块头里。其中区块头细分为:

父区块头哈希值:前一区块的哈希值,使用SHA256(SHA256(父区块头))计算。

版本(Version):区块版本号,表示本区块遵守的验证规则 。

时间戳(Timestamp):该区块产生的近似时间,精确到秒的UNIX时间戳,必须严格大于前11个区块时间的中值,同时全节点也会拒绝那些超出自己2个小时时间戳的区块。

目标值(Bits):该区块工作量证明算法的难度目标,已经使用特定算法编码。

随机数(Nonce):为了找到满足难度目标所设定的随机数,为了解决32位随机数在算力飞升的情况下不够用的问题,规定时间戳和coinbase交易信息均可更改,以此扩展nonce的位数。

Merkle根(MerkleRoot):该区块中交易的Merkle树根的哈希值。矿工收到计算过的区块,会跟自己的区块进行比较,其中Merkle root就是比较它们包含的交易是否一样。

区块头里的所有信息拼接成一个新的字节数组,pow函数运算的参数就是这个字节数组。函数运算是采用SHA256(SHA256())计算。

var genesisBlock = wire.MsgBlock{Header: wire.BlockHeader{    Version:    1,    PrevBlock:  chainhash.Hash{},         // 0000000000000000000000000000000000000000000000000000000000000000    MerkleRoot: genesisMerkleRoot,        // 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b    Timestamp:  time.Unix(0x495fab29, 0), // 2009-01-03 18:15:05 +0000 UTC    Bits:       0x1d00ffff,               // 486604799     Nonce:      0x7c2bac1d,               // 2083236893},Transactions: []*wire.MsgTx{&genesisCoinbaseTx},

}

Pow三要素
1.Hash函数:在比特币中使用的是SHA256算法函数,是密码哈希函数家族中输出值为256位的哈希算法。

2.区块头 Hash函数运算需要的参数,也就是区块头的所有信息字节拼接后的字节数组。

3.目标值(Bits) 每一个区块会用一种压缩的格式(被称为“Bits”)来表示实际的16进制的目标值。通过这个值和系统中其他常量可计算出该难度值下的难度目标值。Hash函数运算出来的结果与目标值进行比较大小,如果小,则表示挖坑成功,否则继续运算。比较大小时为使运算速度快速,目标值和hash值都会转换成2进制,所以比较大小就是比较前导0的个数。比特币是每隔2016个区块后调整难度值。

pow挖矿的难度与目标值成反比,如果Bits的实际值增大,那么挖矿容易点;反之,挖矿难度加大。

比特币pow挖矿及共识流程

比特币挖矿的过程如下:

构建一个空区块,称为候选区块

从内存池中打包交易至候选区块
构造区块头,填写区块头的下述字段
  1)填写版本号version字段
  2)填写父区块哈希prevhash字段
  3)用merkle树汇总全部的交易,将merkle root的哈希值填写至merkle root字段
  4)填写时间戳timestamp字段
  5)填写目标值Bits字段
开始挖矿。挖矿就是不断重复计算区块头的哈希值,修改nonce参数,直到找到一个满足条件的nonce值,也就是该nonce值下,hash函数运算出来的hash值 < Bits。当挖矿节点成功求出一个解后把解填入区块头的nonce字段。
这时一个新区块就成功挖出了,然后挖矿节点会做下面这些事:
  1) 按照标准清单检验新区块,检验通过后进行下面的 2)和 3)步骤
  2)立刻将这个新区块发给它的所有相邻节点,相邻节点收到这个新区块后进行验证,验证有效后会继续传播给所有相邻节点。
  3)将这个新区块连接到现有的区块链中,按照如下规则:
    根据新区块的prevhash字段在现有区块链中寻找这个父区块,
    (Ⅰ) 如果父区块是主区块链的“末梢”,则将新区块添加上去即可;
    (Ⅱ) 如果父区块所在的链是备用链,则节点将新区块添加到备用链,同时比较备用链与主链的工作量。如果备用链比主链积累了更多的工作量,节点将选择备用链作为其新的主链,而之前的主链则成为了备用链;
    (Ⅲ) 如果在现有的区块链中找不到它的父区块,那么这个区块被认为是“孤块”。孤块会被保存在孤块池中,直到它们的父区块被节点接收到。一旦收到了父区块并且将其连接到现有的区块链上,节点就会将孤块从孤块池中取出,并且连接到它的父区块,让它作为区块链的一部分
比特币整个网络会通过调整“难度”这个变量来控制生成工作量证明所需要的计算力,使整个网络的计算力大致每10分钟产生一个区块

转载地址:http://jmpra.baihongyu.com/

你可能感兴趣的文章
Maven错误之Missing artifact
查看>>
在Windows 10 系统上启用Hyper V遇到的错误:0x800f0831
查看>>
细数那些足以替代ERC20的以太坊代币协议
查看>>
C++复习(第一节)知识点总结
查看>>
1.安装
查看>>
设计模式——观察者模式
查看>>
想到阿里巴巴从事Python吗?年薪300K不是梦!
查看>>
java堆内存又溢出了,教你一招必杀技
查看>>
Spring Cloud Config环境库
查看>>
springcloud(六):熔断监控Turbine
查看>>
金三银四背后,一个 Android 程序员的面试心得
查看>>
PyCharm入门教程——注释和取消注释代码块
查看>>
人机大战!人工智能轻松打败美国空军
查看>>
request 登入 jenkins 并下载文件
查看>>
JavaScript参数按值传递
查看>>
你了解Spring事物控制特性吗
查看>>
PHP正则匹配汉字(UTF-8和GBK两种编码)
查看>>
OSChina 周五乱弹 —— 人太多,挤到心凉
查看>>
Java实现爬虫(代码后续补充。。。)
查看>>
URL 资源访问授权
查看>>