PoW机制中根据矿工的工作量来执行货币的分配和记账权的确定。算力竞争的胜者将获得相应区块记账权和比特币奖励。因此,矿机芯片的算力越高,挖矿的时间更长,就可以获得更多的数字货币。2 k2 O7 g# n! F, h
优点:
算法简单,容易实现;节点间无需交换额外的信息即可达成共识;破坏系统需要投入极大的成本。# N- b, h0 A' L& Z3 D1 O5 d# p3 C
缺点:. a. B ]# B3 _4 @( h* u
浪费能源;区块的确认时间难以缩短;新的区块链必须找到一种不同的散列算法,否则就会面临比特币的算力攻击;容易产生分叉,需要等待多个确认;永远没有最终性,需要检查点机制来弥补最终性。
目前基于PoW共识机制的数字货币有很多,比特币、莱特币、狗狗币、达士币、门罗币等初期的数字货币大多都是PoW共识机制。
其他的共识机制还有* |0 _, s4 `4 _ X1 R6 g% a& Y' 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共识机制# n) e' b4 f" {) U. Z: ?
4 l' W' `2 ?1 U2 v( k
这些共识机制,后面有时间会补充上的,今天主要介绍POW* N& D1 s6 B n: b5 b) T! R x9 ^
pow很简单,原理就是 利用计算力,在选择一个nonce的值结合区块的数据算出hash,使得hash的前面多少位都是0.3 h% y) {& p; A5 [. h1 ~5 l3 c
nonce是一个用来找到满足条件的hash值的数字,nonce值一直迭代,直到hash值有效为止。在我们案例中一个有效的hash值是最少有4个前导0。找到nonce值以满足合适条件的hash值的过程就叫做挖矿。; o# G, p% ^% ^5 i' I: G1 ^
下面给出代码:; w$ k6 `0 w4 k6 i
- golang版
- package mainimport ( "bytes"1 C4 D* E0 d% D' P
- "crypto/sha256"& F. ^; i3 m8 x: n
- "fmt"
- "math"
- "math/big")// 前导0,难度const targetBits = 8type ProofOfWork struct { x$ t, ^- X) a/ L* C; I: r1 I
- block *Block
- targetBit *big.Int
- }func NewProofOfWork(block *Block) *ProofOfWork { // 设置64位全10 f) e' B7 \/ e
- var IntTarget = big.NewInt(1) //00000000000000000000000000001. O4 _" c2 \1 B- q) m0 I, F4 A
- //100000000000000000000000000001 g; v7 B/ C B# n
- //00000000000100000000000000000
- //0000001
- // 右移 targetBits位1 R1 a) h* Z, g& `; O
- IntTarget.Lsh(IntTarget, uint(256 - targetBits)) return &ProofOfWork{block:block, targetBit:IntTarget}
- }func (pow *ProofOfWork)PrepareRawData(nonce int64)[]byte {' L) W0 s" ^9 m3 @! F( _4 l# w( ~
- block := pow.block
- tmp := [][]byte{/ s! I, ^* i# C9 j+ @+ g: I
- Int2Byte(block.Version),. i: H- m! `( Y4 [$ g [/ G
- block.PrevBlockHash,
- Int2Byte(block.TimeStamp),
- block.MerkeRoot,* h$ S( g! C$ A
- Int2Byte(nonce),4 M I; ~4 n( U$ t. s$ M- b
- Int2Byte(targetBits),) x& K9 d( U. T" p+ x& K
- block.Data}; I& y( m, j( [! Q1 g
- data := bytes.Join(tmp, []byte{}) return data
- }func (pow *ProofOfWork)Run() (int64, []byte) { var nonce int64 v, v+ n- D* X! _+ ]: i6 Z; ^
- 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"""' V9 c C5 ?' p6 P O1 L& k
- 工作量证明
- """class ProofofWork():+ ^0 H/ k- d: C; B$ w) ^
- """
- pow
- """' K' H( S, u. e7 W! I0 i( V1 P
- def __init__(self, block):6 \- i m7 M @2 }) b$ p0 d" _7 g: R
- self.block = block def mine(self):
- """
- 挖矿函数
- :return:
- """
- i = 0
- prefix = '0000'
- while True:0 u# }; x1 |/ ^" ?+ c& ~$ Q2 ~) Z" R
- nonce = str(i)
- message = hashlib.sha256(). _4 G2 E- C! E; J% t! z
- message.update(str(self.block.data).encode('utf-8'))5 O! a- Y0 z e' V( j
- message.update(nonce.encode("utf-8"))
- digest = message.hexdigest() if digest.startswith(prefix): return nonce, digest
- i += 1