PoW机制中根据矿工的工作量来执行货币的分配和记账权的确定。算力竞争的胜者将获得相应区块记账权和比特币奖励。因此,矿机芯片的算力越高,挖矿的时间更长,就可以获得更多的数字货币。
优点:" d! v. Q. q0 F2 d& l
算法简单,容易实现;节点间无需交换额外的信息即可达成共识;破坏系统需要投入极大的成本。. q. E5 U% m9 o9 `( F6 D
缺点:, [& j- v0 `: l$ f# `
浪费能源;区块的确认时间难以缩短;新的区块链必须找到一种不同的散列算法,否则就会面临比特币的算力攻击;容易产生分叉,需要等待多个确认;永远没有最终性,需要检查点机制来弥补最终性。
目前基于PoW共识机制的数字货币有很多,比特币、莱特币、狗狗币、达士币、门罗币等初期的数字货币大多都是PoW共识机制。
其他的共识机制还有
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共识机制
这些共识机制,后面有时间会补充上的,今天主要介绍POW1 u; N: D" j0 j* e4 r9 I
pow很简单,原理就是 利用计算力,在选择一个nonce的值结合区块的数据算出hash,使得hash的前面多少位都是0.4 P. I) j$ M5 q$ _
nonce是一个用来找到满足条件的hash值的数字,nonce值一直迭代,直到hash值有效为止。在我们案例中一个有效的hash值是最少有4个前导0。找到nonce值以满足合适条件的hash值的过程就叫做挖矿。# M! \+ B5 Y& }/ Y
下面给出代码:2 Y# Z4 P0 }: s3 J
- golang版7 [$ D5 V& g+ U
- package mainimport ( "bytes"- Y* p1 z7 U' v: d/ |
- "crypto/sha256"% E- n8 H' }& `
- "fmt"$ \8 a' J* e* [* @& l- j, Y9 C
- "math"7 c/ N' k1 K L* m4 K
- "math/big")// 前导0,难度const targetBits = 8type ProofOfWork struct {
- block *Block
- targetBit *big.Int0 n% g) b4 _! C2 I$ p
- }func NewProofOfWork(block *Block) *ProofOfWork { // 设置64位全1& Z. ~' u" c5 T0 x G t
- var IntTarget = big.NewInt(1) //00000000000000000000000000001
- //10000000000000000000000000000
- //00000000000100000000000000000$ F1 ~; e% g7 p+ j
- //0000001
- // 右移 targetBits位/ T+ r! C5 l! R5 p5 u' ]- q
- IntTarget.Lsh(IntTarget, uint(256 - targetBits)) return &ProofOfWork{block:block, targetBit:IntTarget}, @+ `7 }( w3 W( N" P6 y' c: x
- }func (pow *ProofOfWork)PrepareRawData(nonce int64)[]byte {* ^& t' W* x) N6 S: i
- block := pow.block
- tmp := [][]byte{4 U& F2 J( |( J, |+ {& Z
- Int2Byte(block.Version)," Z1 J8 H. h2 F( Z0 o" d5 [
- block.PrevBlockHash,
- Int2Byte(block.TimeStamp),4 z# L4 Z- a( q/ w% L- T# n
- block.MerkeRoot,
- Int2Byte(nonce),! {% N+ |# j+ C5 Q2 X
- Int2Byte(targetBits),. t& ^* Z* `: }+ m
- block.Data}
- data := bytes.Join(tmp, []byte{}) return data
- }func (pow *ProofOfWork)Run() (int64, []byte) { var nonce int642 v5 X# Z7 y, i9 y/ g; J* G8 H
- var hash [32]byte
- var HashInt big.Int
- fmt.Printf("target hash:", pow.targetBit.Bytes()) for nonce
- python版
- function isValidHashDifficulty(hash, difficulty) { for (var i = 0, b = hash.length; i = difficulty;
- }import hashlib"""
- 工作量证明
- """class ProofofWork():( ?: [! a! ]% ~
- """
- pow6 c- }( V0 N( k
- """
- def __init__(self, block):
- self.block = block def mine(self):- Q# N9 {: b( ^/ _
- """& C) I# O3 z4 M" s# A: G9 L
- 挖矿函数; c9 Q9 A; n! c8 L+ ~- F" x# [
- :return:5 N2 R/ \% \. y3 G# ^/ l+ J
- """8 {+ B2 Q7 C6 D
- i = 0
- prefix = '0000'9 r$ z3 S p6 ^3 {
- while True:- q- n; x2 a' x( \$ V9 W+ @
- nonce = str(i)- K$ E9 i) C6 d$ x, W6 x% Z. |# |# q
- message = hashlib.sha256()
- message.update(str(self.block.data).encode('utf-8')) \+ I. R& h# ]6 C- i7 k$ K
- message.update(nonce.encode("utf-8"))& G% M% u# q& D* p' O7 V
- digest = message.hexdigest() if digest.startswith(prefix): return nonce, digest) S6 d+ N, K' c3 g7 \% Q
- i += 1