Hi 游客

更多精彩,请登录!

比特池塘 区块链前沿 正文

比特币工作证明与挖矿

天然灵凡
80 0 0
工作证明
" L) h) y* ^8 m9 ]) g" Y工作证明(Proof Of Work,简称POW),顾名思义,即工作量的证明。通常来说只能从结果证明,因为监测工作过程通常是繁琐与低效的。2 W4 t$ a  V9 s# u
比特币在Block的生成过程中使用了POW机制,一个符合要求的Block Hash由N个前导零构成,零的个数取决于网络的难度值。要得到合理的Block Hash需要经过大量尝试计算,计算时间取决于机器的哈希运算速度。当某个节点提供出一个合理的Block Hash值,说明该节点确实经过了大量的尝试计算,当然,并不能得出计算次数的绝对值,因为寻找合理hash是一个概率事件。当节点拥有占全网n%的算力时,该节点即有n/100的概率找到Block Hash。
1 E3 Q8 S& u/ {/ q" i( [' l工作证明机制看似很神秘,其实在社会中的应用非常广泛。例如,毕业证、学位证等证书,就是工作证明,拥有证书即表明你在过去投入了学习与工作。生活大部分事情都是通过结果来判断的。
7 x0 ]) \" E8 M% r4 J. y挖矿
* f& w2 f; n) O& ~* Y挖矿即不断接入新的Block延续Block Chain的过程。
; y7 b  b1 U. ~1 _0 e. z* _* F8 O" F" ~: O; }2 U/ u
挖矿为整个系统的运转提供原动力,是比特币的发动机,没有挖矿就没有比特币。挖矿有三个重要功能:
9 D8 N- v5 a+ W  a" `) ?发行新的货币(总量达到之前)维系货币的支付功能通过算力保障系统安全
+ U8 ?9 d) f4 ^% O金矿消耗资源将黄金注入流通经济,比特币通过“挖矿”完成相同的事情,只不过消耗的是CPU时间与电力。当然,比特币的挖矿意义远大于此。0 h6 v6 b) O: q/ A0 w: k; M

5 N. S9 Z0 Y5 w) \0 A5 lBlock Hash算法8 }5 R: T* \5 n; m
Block头部信息的构成:2 T% S7 O% G! R5 S0 }4 s0 G

! e# s9 n- y: d7 }' C& n下面采用高度为125552的block数据为例,演示block hash的计算过程:
: S& x9 R; d) J$ J/ I! D% {
2 Q+ ?+ m; H' i$ c该计算过程简单明了:首先将数个字段合并成一块数据,然后对这块数据进行双SHA256运算。
7 g2 u( U" [% @! }; g; {% t- C产量调节
# Q  _7 t! Z8 |Block的产量为大约每两周2016个,即每10分钟一块。该规则在每个节点的代码里都固定了。
' h$ O, ?+ W- ~& F) ]: q8 T$ O// 目标时间窗口长度:两周, H1 f3 ^5 z2 e. E
static const int64 nTargetTimespan = 14 * 24 * 60 * 60;+ J6 d, J$ ]* l; V3 P1 {' E7 G/ n
// block频率,每10分钟一块$ g( W$ P) U2 z; Q+ o
static const int64 nTargetSpacing  = 10 * 60;; [% ?; r3 i2 }& [7 E; d
// 每两周的产量2016,也是调节周期
( [8 I1 E7 i: P) W; q8 B( u$ f7 Estatic const int64 nInterval       = nTargetTimespan / nTargetSpacing;
' r, s/ j, c, w5 }) f但由于实际算力总是不断变化的(目前一直是快速上升的),所以需根据最近2016个块的耗费时间来调整难度值,维持每10分钟一个block的频率.2 I; w! q( M& ~# y# ~" D+ b
// Only change once per interval
" S# O+ P# X" \. [5 I+ wif ((pindexLast->nHeight+1) % nInterval != 0) {
" p& f; H/ b" R9 s' N6 u; |2 X    // 未达到周期个数,无需调节5 R& l! u9 Q3 ?$ J5 Q. G
    return pindexLast->nBits;
( r. D2 m) R7 f0 R}! H, S' O# ^+ a/ Q. y- g* c
// Go back by what we want to be 14 days worth of blocks
- L1 b5 @; h  W7 Q* n3 r. Yconst CBlockIndex* pindexFirst = pindexLast;
- l6 w( R) w; Z  [" j8 [9 D- @for (int i = 0; pindexFirst && i pprev;
4 h9 l3 g  f: K* _, [* X' D9 W5 q// 计算本次2016个块的实际产生时间+ q  D% {7 Z2 p1 y6 M/ @3 a
// Limit adjustment step
  {: }7 F# L( G9 _3 o. M5 v0 oint64 nActualTimespan = pindexLast->GetBlockTime() - pindexFirst->GetBlockTime();
2 w0 {$ }6 h/ Z& D# W// 限定幅度,最低为1/4,最高为4倍; W' v6 F3 {3 j
if (nActualTimespan  nTargetTimespan*4). L( A4 v9 R* T, h  s/ z
    nActualTimespan = nTargetTimespan*4;8 s" ]6 g* B- j3 B: a( J- |
// 根据最近2016个块的时间,重新计算目标难度
" z/ N( q/ P7 M3 O( L' i// Retarget
. D6 R# L- `0 _0 MCBigNum bnNew;- a, F. c+ e9 `
bnNew.SetCompact(pindexLast->nBits);
3 m. a6 B0 R; R: L4 w: \bnNew *= nActualTimespan;
0 M2 n$ a; Y; _6 c- \, f9 LbnNew /= nTargetTimespan;
$ H! x9 I6 G0 {+ a6 }1 q+ e* w 4 }) x8 T$ O. @: y% k: f% n
if (bnNew > bnProofOfWorkLimit), T) g$ I. {) R; k
    bnNew = bnProofOfWorkLimit;
# \  d4 q7 o  a 9 A" o+ ^- |0 r: A: R7 S
return bnNew.GetCompact();
7 J9 H' U9 B8 ~7 e/ IBlock字段详解
+ P7 X4 o7 m3 }- S; C5 {& dVersion,版本号,很少变动,一般用于软件全网升级时做标识hashPrevBlock,前向Block Hash值,该字段强制多个Block之间形成链接hashMerkleRoot,交易Hash树的根节点Hash值,起校验作用,保障Block在网络传输过程中的数据一致性,有新交易加入即发生变化Time,Unix时间戳,每秒自增一,标记Block的生成时间,同时为block hash探寻引入一个频繁的变动因子Bits,可以推算出难度值,用于验证block hash难度是否达标Nonce,随机数,在上面数个字段都固定的情况下,不停地更换随机数来探寻
/ l3 L9 [  _* y* W  o( t; Q: H最为关键的字段是hashPrevBlock,该字段使得Block之间链接起来,形成一个巨大的“链条”。Block本是稀松平常的数据结构,但以链式结构组织起来后却使得它们具有非常深远的意义:+ f; n, ~" ?. u. Y+ f, x. W

5 W. Z) i3 r. l1 @% `0 E2 L形成分支博弈,使得算力总是在主分支上角逐算力攻击的概率难度呈指数上升(泊松分布)
7 ^% l, Y' M& Q9 Y- v! x$ q
, Y7 u) h! c" @" e  ^; ^" {) v0 H每个block都必须指向前一个block,否则无法验证通过。追溯至源头,便是高度为零的创世纪块(Genesis Block),这里是Block Chain的起点,其前向block hash为零,或者说为空。8 B% D* G" e$ Q
新block诞生过程
# u' M; h4 b, a9 ~8 [下面是一个简单的步骤描述,实际矿池运作会有区别,复杂一些:
" N( F$ ]2 ?- Z$ p- i节点监听全网交易,通过验证的交易进入节点的内存池(Tx Mem Pool),并更新交易数据的Merkle Hash值更新时间戳尝试不同的随机数(Nonce),进行hash计算重复该过程至找到合理的hash打包block:先装入block meta信息,然后是交易数据对外部广播出新block其他节点验证通过后,链接至Block Chain,主链高度加一,然后切换至新block后面挖矿3 h- h/ }* D; M8 H/ d+ _. c
由于hashPrevBlock字段的存在,使得大家总是在最新的block后面开挖,稍后会分析原因。
) Y- S) |/ p+ g4 c' ]! ^+ h) W+ ~+ Y9 Q" I* i. [) F
主链分叉! d+ Q" Z6 M; e) e# z# \
从block hash算法我们知道,合理的block并不是唯一的,同一高度存在多个block的可能性。那么,当同一个高度出现多个时,主链即出现分叉(Fork)。遇到分叉时,网络会根据下列原则选举出Best Chain:
# O0 w8 ~1 K/ k3 a6 ~" w不同高度的分支,总是接受最高(即最长)的那条分支
# u) j. J( C  X) _; t相同高度的,接受难度最大的
" P- U. r/ o7 }( S高度相同且难度一致的,接受时间最早的5 j1 h3 g, Z( i
若所有均相同,则按照从网络接受的顺序5 G" s, K" q! X4 X& _" Q! |
等待Block Chain高度增一,则重新选择Best Chain9 k1 {0 {/ d3 z
$ S' J) r, D9 c8 x( b
按照这个规则运作的节点,称为诚实节点(Honest Nodes)。节点可以诚实也可以不诚实。
$ V7 ^; e; N" |, M9 h1 s: o3 a分支博弈
1 E$ B( [9 d! y- R# {我们假设所有的节点:
. w3 U( m% Z; z; a0 @, v4 ^9 }都是理性的,追求收益最大化都是不诚实的,且不惜任何手段获取利益
9 w) m8 t2 [$ y- E" o: X
9 A1 d. }* B) k所有节点均独自挖矿不理会其他节点,并将所得收益放入自己口袋,现象就是一个节点挖一个分支。由于机器的配置总是有差别的,那么算力最强的节点挖得的分支必然是最长的,如果一个节点的分支不是最长的,意味其收益存在不被认可的风险(即零收益)。为了降低、逃避此风险,一些节点肯定会联合起来一起挖某个分支,试图成为最长的分支或保持最长分支优势。
3 Q6 D5 o& C/ i6 B' L. V一旦出现有少量的节点联合,那么其他节点必然会效仿,否则他们收益为零的风险会更大。于是,分支迅速合并汇集,所有节点都会选择算力更强的分支,只有这样才能保持收益风险最小。最终,只会存在一个这样的分支,就是主干分支(Best/Main Chain)。
8 i# p% g1 M/ [3 j& g! |对于不诚实节点来说,结局是无奈的:能且只能加入主干挖矿。不加入即意味被抛弃,零收益;加入就是老实干活,按占比分成。, r, r5 ]5 o  U3 x& P% q4 `
Hash Dance
4 Z+ Q, t  a$ g7 {$ ~Block hash的计算是随机概率事件,当有节点广播出难度更高的block后,大家便跑到那个分支。在比特币系统运行过程中,算力经常在分支间跳来跳去,此现象称为Hash Dance。一般情况下,分支的高度为1~2,没有大的故障很难出现高于2的分支。' w8 n/ j, G7 H3 [
Hash Dance起名源于Google Dance.
) [: B, V, u" _  U# [1 Y+ e& \  X: A算力攻击的概率( Z/ G- _  l; o/ a! ?6 {, S
本节内容参考:Bitcoin: A Peer-to-Peer Electronic Cash System0 D: R& @% l( l1 s
算力攻击是一个概率问题,这里作简单叙述:8 o/ E4 A, r; c6 X
p = 诚实节点挖出block概率q = 攻击者挖出block概率,q = 1 - pqz = 攻击者从z个block追上的概率
- d/ Y2 A  [$ z7 g' V; d
8 D: A7 \+ G. t9 U9 Q
5 v5 y/ m6 Q# t
我们假设p>q,否则攻击者掌握了一半以上的算力,那么概率上永远是赢的。该事件(攻击者胜出)的概率是固定,且N次事件之间是相互独立的,那么这一系列随机过程符合泊松分布(Poisson Distribution)。Z个块时,攻击者胜出的期望为lambda:
& e" b& \7 K% B1 p" W0 L7 B" U. [( i
攻击者在攻击时已经偷偷的计算了k个块,那么这k个块概率符合泊松分布(下图左侧部分),若k
; y( z* A6 F- c6 t2 V2 D" i; P$ w2 e/ H7 E2 P- o
展开为如下形式:
! }" }" N" }: Z' l
; V. U( k' _' o# G计算该过程的C语言代码如下:
* {# C8 X9 |( T& G6 `5 z#include 7 |# o" _) h+ g$ Z
double AttackerSuccessProbability(double q, int z)
, H$ s2 F0 ^, t{7 l2 @  K# S9 v. v! t2 h
    double sum    = 1.0;
5 `6 M  w- ^5 f0 G1 ]& k    double p      = 1.0 - q;- G' Q$ W) o- t) q3 Y: S
    double lambda = z * (q / p);
# T4 ~: `2 P, e. R3 [2 {2 U! o    int i, k;
* X1 s' n) t9 \/ D0 U    for (k = 0; k
! T# b, X! ]$ r, M2 E7 }我们选取几个值,结果如下:, y5 `, t  L2 X

6 L$ v2 D6 W5 \' q. f1 h- F可以看到,由于block的链式形式,随着块数的上升,攻击者赢得的概率呈指数下降。这是很多应用等待六个甚至六个以上确认的原因,一旦超过N个确认,攻击者得逞的可能微乎其微,概率值快速趋近零。. _1 T) V! ]$ o. q5 A; x
当攻击者的算力超过50%时,便可以控制Block Chain,俗称51%攻击。, U+ k- [  b. \4 c- t
算力攻击的危害
+ R5 @5 `# U/ J2 Y/ N1 {攻击者算出block后,block&Txs必须能够通过验证,否则其他节点都会拒掉,攻击便无意义。攻击者无法做出下列行为:
8 \8 g9 D& C  G7 _# S2 }# ]偷盗他人的币。消费某个地址的币时,需要对应的ECDSA私钥签名,而私钥是无法破解的。凭空制造比特币。每个block奖励的币值是统一的规则,篡改奖励币值会导致其他节点会拒绝该block。  y( _* r2 H  o- I: f# |
: d$ H7 K  l8 r" P6 ~
唯一的益处是可以选择性的收录进入block的交易,对自己的币进行多重消费(Double Spending)。) x* y7 \* P7 I; ~$ T7 E
过程是这样的:假设现在block高度为100,攻击者给商户发了一个交易10BTC,记作交易A,通常这笔交易会被收录进高度101的block中,当商户在101块中看到这笔交易后,就把货物给了攻击者。此时,攻击者便开始构造另一个高度为101的block,但用交易B替换了交易A,交易B中的输入是同一笔,使得发给商户的那笔钱发给他自己。同时,攻击者需要努力计算block,使得他的分支能够赶上主分支,并合并(Merge)被大家接受,一旦接受,便成功地完成了一次Double Spending。& U( F; f, |; n0 G' \8 `
攻击难度呈指数上升,所以成功的Double Spending通常是一个极小概率事件。
$ g- f; z, o/ P5 t: A5 C2 Q" o- F算力巨头
  W& b( F; T5 n$ H* y; U8 U; Z全网算力的上升对比特币是极其有利的,这是毫无疑问的。但目前大矿池与矿业巨头使得算力高度集中化,这与中本聪所设想的一CPU一票(one-CPU-one-vote)的分散局面背道而驰,或许是他未曾预料的。- U# A9 O( f% i
挖矿是一项专业劳动,最后必然会交给最专业的人或团队,因为这样才能实现资源配置最优,效率最高。普通投资人通过购买算力巨头的股票:1. 完成投资;2. 分享算力红利。看似中心化的背后其实依然是分散的:6 e$ c; d: }4 Q
1.矿业公司的背后是无数分散的投资人9 T. {: f8 ]- G9 R6 U" g2 e9 s
2.矿池背后是无数分散的个体算力
/ n1 E2 x/ E2 D6 ~既得利益使得算力巨头倾向于维护系统而不是破坏,因其收益均建立在比特币系统之上,既得利益者断然不会搬石头砸自己脚。甚至很多巨头在达到一定算力占比后会主动控制算力增长,使得低于某阈值内。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

天然灵凡 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    33