PoW机制中根据矿工的工作量来执行货币的分配和记账权的确定。算力竞争的胜者将获得相应区块记账权和比特币奖励。因此,矿机芯片的算力越高,挖矿的时间更长,就可以获得更多的数字货币。
优点:
算法简单,容易实现;节点间无需交换额外的信息即可达成共识;破坏系统需要投入极大的成本。7 O( u0 |7 ]0 T' V0 q
缺点:/ [6 p: \( Y# H- y" M, I6 s* @
浪费能源;区块的确认时间难以缩短;新的区块链必须找到一种不同的散列算法,否则就会面临比特币的算力攻击;容易产生分叉,需要等待多个确认;永远没有最终性,需要检查点机制来弥补最终性。
目前基于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共识机制- S% y+ @# E) C, l7 t5 {* {& L
这些共识机制,后面有时间会补充上的,今天主要介绍POW! ?" Y. @$ G3 U4 ^9 Y
pow很简单,原理就是 利用计算力,在选择一个nonce的值结合区块的数据算出hash,使得hash的前面多少位都是0.$ ~8 b+ B6 ]; Z/ O* E+ K. v
nonce是一个用来找到满足条件的hash值的数字,nonce值一直迭代,直到hash值有效为止。在我们案例中一个有效的hash值是最少有4个前导0。找到nonce值以满足合适条件的hash值的过程就叫做挖矿。6 F" a) H' o) r5 U/ h
下面给出代码:
- golang版+ e: K, w1 v+ X: E; \8 |
- package mainimport ( "bytes"
- "crypto/sha256"; e9 s6 X) W0 j. T. q. U1 A
- "fmt"( k* x/ g9 o0 E! B5 g" W" y
- "math", F* p1 K+ p5 u. y! V+ M
- "math/big")// 前导0,难度const targetBits = 8type ProofOfWork struct {- i7 G& } B- D4 p8 M% K+ E
- block *Block
- targetBit *big.Int
- }func NewProofOfWork(block *Block) *ProofOfWork { // 设置64位全1' s( e5 A' o `+ l3 G
- var IntTarget = big.NewInt(1) //00000000000000000000000000001
- //10000000000000000000000000000
- //00000000000100000000000000000
- //0000001
- // 右移 targetBits位
- IntTarget.Lsh(IntTarget, uint(256 - targetBits)) return &ProofOfWork{block:block, targetBit:IntTarget}
- }func (pow *ProofOfWork)PrepareRawData(nonce int64)[]byte {
- block := pow.block; v- C7 s4 P1 |
- tmp := [][]byte{
- Int2Byte(block.Version),; r0 b! W) q' a' I
- block.PrevBlockHash,
- Int2Byte(block.TimeStamp),
- block.MerkeRoot,4 n' g4 v& Q3 m% U3 f6 w
- Int2Byte(nonce),- V* B5 W; n2 L! L
- Int2Byte(targetBits),; y% P g) K* X1 j5 t% @0 K
- block.Data}
- data := bytes.Join(tmp, []byte{}) return data
- }func (pow *ProofOfWork)Run() (int64, []byte) { var nonce int64
- var hash [32]byte
- var HashInt big.Int
- fmt.Printf("target hash:", pow.targetBit.Bytes()) for nonce $ k# V& [4 C+ n _" x: t# r4 W, P
- python版
- function isValidHashDifficulty(hash, difficulty) { for (var i = 0, b = hash.length; i = difficulty;" V' _& P4 N8 I5 q) }# d
- }import hashlib"""
- 工作量证明9 k% E: K6 a' ?+ t
- """class ProofofWork():! A8 K! s. @9 P6 z
- """
- pow1 d0 P" R7 N% Y; _
- """8 F# z3 O( r% h) k+ j
- def __init__(self, block):
- self.block = block def mine(self):6 _! F) V q8 r8 `: I1 V6 [7 S
- """: E7 a* M/ B2 W$ } T" S( d
- 挖矿函数: z3 t0 {2 a$ r3 o$ f& G8 }: ]
- :return:" D: z ~& V E0 o$ s
- """
- i = 09 t- X4 _& c5 e. p \# J( R' N& n/ h
- prefix = '0000'
- while True:+ B* q. {, \# s2 j* D3 `
- nonce = str(i)
- message = hashlib.sha256()
- 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
- i += 1