PoW机制中根据矿工的工作量来执行货币的分配和记账权的确定。算力竞争的胜者将获得相应区块记账权和比特币奖励。因此,矿机芯片的算力越高,挖矿的时间更长,就可以获得更多的数字货币。
优点:) I. ~% i8 |& Y
算法简单,容易实现;节点间无需交换额外的信息即可达成共识;破坏系统需要投入极大的成本。" @$ G# P4 B2 F; n
缺点:
浪费能源;区块的确认时间难以缩短;新的区块链必须找到一种不同的散列算法,否则就会面临比特币的算力攻击;容易产生分叉,需要等待多个确认;永远没有最终性,需要检查点机制来弥补最终性。! Z& x+ y3 Y! e& M
目前基于PoW共识机制的数字货币有很多,比特币、莱特币、狗狗币、达士币、门罗币等初期的数字货币大多都是PoW共识机制。5 |' Z8 V# k6 } ~5 k7 ?" o6 E. d
其他的共识机制还有9 K7 O& C* r2 _4 ]8 E" s7 u6 u
PoS(Proof of Stake)DPOS(Delegated Proof-of-Stake)DAG(Directed acyclic graph)PBFT(Practical Byzantine Fault Tolerance)Pool验证池dBFT(delegated BFT)PoA(Proof-of-Authority)RPCA(Ripple Protocol consensus algorithm)Hcash——PoW+PoS共识机制
这些共识机制,后面有时间会补充上的,今天主要介绍POW" [( B k- B! V
pow很简单,原理就是 利用计算力,在选择一个nonce的值结合区块的数据算出hash,使得hash的前面多少位都是0.
nonce是一个用来找到满足条件的hash值的数字,nonce值一直迭代,直到hash值有效为止。在我们案例中一个有效的hash值是最少有4个前导0。找到nonce值以满足合适条件的hash值的过程就叫做挖矿。( `4 q8 W* ]! o# a# I9 t' E
下面给出代码:/ j9 Z7 p4 _0 L, ^* w
- golang版* t; V. w( ]5 `0 G* s
- package mainimport ( "bytes"
- "crypto/sha256"3 n1 C5 |8 N- D- C: s$ l7 J. Q; X
- "fmt"
- "math"
- "math/big")// 前导0,难度const targetBits = 8type ProofOfWork struct {0 S) p0 Y/ l: t
- block *Block
- targetBit *big.Int
- }func NewProofOfWork(block *Block) *ProofOfWork { // 设置64位全1
- var IntTarget = big.NewInt(1) //00000000000000000000000000001. @/ E0 {5 ~1 x
- //10000000000000000000000000000
- //000000000001000000000000000009 ~9 Q' b g+ i" j* B: P1 x) b
- //00000015 `3 c: T9 C" a
- // 右移 targetBits位
- IntTarget.Lsh(IntTarget, uint(256 - targetBits)) return &ProofOfWork{block:block, targetBit:IntTarget}. q5 n* l: x ^: H; j( M1 ^# K9 @
- }func (pow *ProofOfWork)PrepareRawData(nonce int64)[]byte {* A7 C) f7 f3 O0 V2 i8 O6 W* R
- block := pow.block
- tmp := [][]byte{/ m6 s% O+ s6 F, |! \3 ^
- Int2Byte(block.Version),9 x; ?! F. v; N+ P- d
- block.PrevBlockHash,
- Int2Byte(block.TimeStamp),
- block.MerkeRoot,9 ^- I% y& c, s. X \3 s# i
- Int2Byte(nonce),
- Int2Byte(targetBits),# ^$ Q- O S0 C( I& b7 o( G
- block.Data}
- data := bytes.Join(tmp, []byte{}) return data4 H- E) R) o7 A. t
- }func (pow *ProofOfWork)Run() (int64, []byte) { var nonce int64: u0 x. k& I2 k5 A$ d% _" ^
- var hash [32]byte( O& G, [& C& ?$ d. {4 ?) q
- var HashInt big.Int3 Q( v% S, m5 z8 |/ a/ _: e# u$ ^- |
- fmt.Printf("target hash:", pow.targetBit.Bytes()) for nonce
- python版
- function isValidHashDifficulty(hash, difficulty) { for (var i = 0, b = hash.length; i = difficulty;# s, a' m1 D$ t% L' v5 g
- }import hashlib"""$ P# {8 X" X9 ^3 N9 X
- 工作量证明
- """class ProofofWork():! a: G; O! Q- v8 B* Y$ T8 F
- """, p4 `6 A: p2 n6 g& F
- pow' |% @! h7 F: i7 N
- """
- def __init__(self, block):( w$ C, v$ H0 w! C; l
- self.block = block def mine(self):
- """) z# l' O* _! O* b X8 D1 }
- 挖矿函数
- :return:2 @ T9 i) p9 z3 ~5 \! k' k
- """' i# t/ W& h1 G$ P. @- x" B
- i = 0- z( ]3 ~$ |( t# e3 F: V
- prefix = '0000'
- while True:
- nonce = str(i)$ N# Q8 _5 g _1 i, L& Z& D4 X6 ~
- message = hashlib.sha256()5 W3 g7 w5 R) \ U) P
- message.update(str(self.block.data).encode('utf-8'))$ G8 L' e% P7 x" I! s O. F/ O
- message.update(nonce.encode("utf-8"))3 N5 e) q1 W% }5 z4 S4 Q
- digest = message.hexdigest() if digest.startswith(prefix): return nonce, digest* A6 \( i9 t8 s: B2 o2 T7 C
- i += 1