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