PoW机制中根据矿工的工作量来执行货币的分配和记账权的确定。算力竞争的胜者将获得相应区块记账权和比特币奖励。因此,矿机芯片的算力越高,挖矿的时间更长,就可以获得更多的数字货币。2 t7 ]2 d7 z4 E7 i
优点:
算法简单,容易实现;节点间无需交换额外的信息即可达成共识;破坏系统需要投入极大的成本。% c0 P P! [1 M3 x+ u G
缺点:; t' D6 W8 U; ]& b
浪费能源;区块的确认时间难以缩短;新的区块链必须找到一种不同的散列算法,否则就会面临比特币的算力攻击;容易产生分叉,需要等待多个确认;永远没有最终性,需要检查点机制来弥补最终性。3 Q7 y1 |* t" E' k9 ?
目前基于PoW共识机制的数字货币有很多,比特币、莱特币、狗狗币、达士币、门罗币等初期的数字货币大多都是PoW共识机制。( X. `1 H+ Z b# }4 _) f
其他的共识机制还有
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共识机制* U, J2 `8 c1 j: N+ S z/ z
这些共识机制,后面有时间会补充上的,今天主要介绍POW2 x2 C& a& c# h- P& o- V
pow很简单,原理就是 利用计算力,在选择一个nonce的值结合区块的数据算出hash,使得hash的前面多少位都是0. F, O! [7 e0 S# Z, \7 M
nonce是一个用来找到满足条件的hash值的数字,nonce值一直迭代,直到hash值有效为止。在我们案例中一个有效的hash值是最少有4个前导0。找到nonce值以满足合适条件的hash值的过程就叫做挖矿。$ e: O4 Z) I" @) S+ ]! g+ s. O
下面给出代码:1 a# `# T" ^, X
- golang版
- package mainimport ( "bytes"
- "crypto/sha256"( ?' |5 M1 }- k
- "fmt"
- "math"2 I# @8 h) `& z5 j6 n
- "math/big")// 前导0,难度const targetBits = 8type ProofOfWork struct {
- block *Block
- targetBit *big.Int
- }func NewProofOfWork(block *Block) *ProofOfWork { // 设置64位全13 ~; p" _7 {3 x0 w/ {( o" ~ |( b
- var IntTarget = big.NewInt(1) //00000000000000000000000000001
- //10000000000000000000000000000
- //00000000000100000000000000000. k- o) l, ~6 G% b6 L
- //00000015 q: B. f9 N* J# h3 w7 w, y. I# `' z
- // 右移 targetBits位# G& h" ^' R( ~/ u3 K: b
- IntTarget.Lsh(IntTarget, uint(256 - targetBits)) return &ProofOfWork{block:block, targetBit:IntTarget}0 p# Y6 A6 c! C# w- `- e
- }func (pow *ProofOfWork)PrepareRawData(nonce int64)[]byte {4 E$ d3 f9 E* N; l
- block := pow.block0 I" e6 a [9 j( ?" T$ F% h+ A- b
- tmp := [][]byte{
- Int2Byte(block.Version),
- block.PrevBlockHash,
- Int2Byte(block.TimeStamp),
- block.MerkeRoot,
- Int2Byte(nonce),# J# z) _& J6 ?' Q6 H
- Int2Byte(targetBits),0 W5 t( f& `$ b2 v
- block.Data}# o. y+ B& S y6 d
- data := bytes.Join(tmp, []byte{}) return data: C, U) h8 R1 x& Y- Y
- }func (pow *ProofOfWork)Run() (int64, []byte) { var nonce int641 a3 {: `, d! v$ e3 G% b: M8 u
- var hash [32]byte1 L0 w8 d7 K4 {5 y# [; U* C8 {5 u
- var HashInt big.Int7 z+ R+ G9 S+ I& L
- fmt.Printf("target hash:", pow.targetBit.Bytes()) for nonce 2 \" s- J6 p4 \' F) m
- python版
- function isValidHashDifficulty(hash, difficulty) { for (var i = 0, b = hash.length; i = difficulty;
- }import hashlib"""$ o9 X9 r" _" K/ T$ ], ~
- 工作量证明& r7 {6 m8 D9 X- @2 j/ v+ R7 |
- """class ProofofWork():
- """
- pow# k1 _6 o5 v9 ~: l% i r
- """, f9 F2 V1 k5 H/ j2 X: V8 z
- def __init__(self, block):$ B% v7 @( T4 R2 m R5 c7 _
- self.block = block def mine(self):
- """% M! \2 S' g% v/ Q3 O' J
- 挖矿函数
- :return:
- """
- i = 0+ ^- ^+ q# \/ x, h) T( e9 C& u s( O
- prefix = '0000') ~2 ^' P6 i9 S
- while True:0 v! G" p0 u7 w# ` J/ X
- nonce = str(i). L( z) G, i& k0 G* p$ g
- message = hashlib.sha256()& d1 t- Y' L& D# T
- message.update(str(self.block.data).encode('utf-8'))3 Z: H0 \7 S9 g1 y- v, S
- message.update(nonce.encode("utf-8")); J: o, H4 E; i5 u& \# x6 v
- digest = message.hexdigest() if digest.startswith(prefix): return nonce, digest
- i += 1