PoW机制中根据矿工的工作量来执行货币的分配和记账权的确定。算力竞争的胜者将获得相应区块记账权和比特币奖励。因此,矿机芯片的算力越高,挖矿的时间更长,就可以获得更多的数字货币。
优点:9 j$ U0 E$ R# z
算法简单,容易实现;节点间无需交换额外的信息即可达成共识;破坏系统需要投入极大的成本。, f" n2 U+ w3 U+ R. j. [! D% u' Z
缺点:. T* c! q) a3 e
浪费能源;区块的确认时间难以缩短;新的区块链必须找到一种不同的散列算法,否则就会面临比特币的算力攻击;容易产生分叉,需要等待多个确认;永远没有最终性,需要检查点机制来弥补最终性。2 w$ ~3 B% A- X0 W$ `' [$ g! }
目前基于PoW共识机制的数字货币有很多,比特币、莱特币、狗狗币、达士币、门罗币等初期的数字货币大多都是PoW共识机制。
其他的共识机制还有# d# n2 Z8 n- }9 e; N; h
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共识机制' F! G5 {3 M! U$ N2 ]5 h: O$ h
# g: w8 M" n4 S& t4 I5 L' p
这些共识机制,后面有时间会补充上的,今天主要介绍POW& c8 W& b6 w# U) i0 }
pow很简单,原理就是 利用计算力,在选择一个nonce的值结合区块的数据算出hash,使得hash的前面多少位都是0.
nonce是一个用来找到满足条件的hash值的数字,nonce值一直迭代,直到hash值有效为止。在我们案例中一个有效的hash值是最少有4个前导0。找到nonce值以满足合适条件的hash值的过程就叫做挖矿。0 Q1 S) O7 P* D
下面给出代码:
- golang版
- package mainimport ( "bytes"7 { x* T9 S/ Q+ m3 F/ j% Q' c5 Z
- "crypto/sha256"
- "fmt"; Y& m; Q; K! x4 |7 t
- "math"
- "math/big")// 前导0,难度const targetBits = 8type ProofOfWork struct {
- block *Block8 x8 @6 r( P3 e2 s
- targetBit *big.Int; a% G C& n4 y" c2 C/ z
- }func NewProofOfWork(block *Block) *ProofOfWork { // 设置64位全1, C7 ^3 \5 j$ {: A5 ?+ ^7 ]! k
- var IntTarget = big.NewInt(1) //00000000000000000000000000001
- //10000000000000000000000000000
- //00000000000100000000000000000
- //0000001
- // 右移 targetBits位" I" ?! K \7 s
- IntTarget.Lsh(IntTarget, uint(256 - targetBits)) return &ProofOfWork{block:block, targetBit:IntTarget}
- }func (pow *ProofOfWork)PrepareRawData(nonce int64)[]byte {
- block := pow.block. c7 B" h6 C% y8 R
- tmp := [][]byte{
- Int2Byte(block.Version),
- block.PrevBlockHash,
- Int2Byte(block.TimeStamp),2 @9 ]. ]; i5 I7 H
- block.MerkeRoot,
- Int2Byte(nonce),+ V2 D" i8 J* ^2 ], C6 O
- Int2Byte(targetBits),
- block.Data}
- data := bytes.Join(tmp, []byte{}) return data
- }func (pow *ProofOfWork)Run() (int64, []byte) { var nonce int64
- var hash [32]byte, {+ x1 { S0 y
- var HashInt big.Int
- fmt.Printf("target hash:", pow.targetBit.Bytes()) for nonce ! T4 v8 |" ~% C! Z! X
- python版
- function isValidHashDifficulty(hash, difficulty) { for (var i = 0, b = hash.length; i = difficulty;
- }import hashlib"""
- 工作量证明 Y- _) V. K$ U, O; L6 M2 i
- """class ProofofWork():
- """
- pow
- """
- def __init__(self, block):8 Z8 B2 q/ F# X6 W1 h
- self.block = block def mine(self):6 ^ C9 z& m i1 F9 j) [2 j2 a- T
- """
- 挖矿函数+ }; Y% x* J! b1 \- g% T' j3 K
- :return:
- """+ K) h' y( e9 ~% B0 b! M
- i = 0
- prefix = '0000'
- while True:# X4 C& t$ g& W, e" o
- nonce = str(i)
- message = hashlib.sha256() B% r% I2 y# Y
- message.update(str(self.block.data).encode('utf-8'))
- message.update(nonce.encode("utf-8"))
- digest = message.hexdigest() if digest.startswith(prefix): return nonce, digest( |0 @/ ~: L& e* T7 w" f' J# ^
- i += 1