PoW机制中根据矿工的工作量来执行货币的分配和记账权的确定。算力竞争的胜者将获得相应区块记账权和比特币奖励。因此,矿机芯片的算力越高,挖矿的时间更长,就可以获得更多的数字货币。
优点:! S) n3 f4 B8 n5 n' }
算法简单,容易实现;节点间无需交换额外的信息即可达成共识;破坏系统需要投入极大的成本。
缺点:
浪费能源;区块的确认时间难以缩短;新的区块链必须找到一种不同的散列算法,否则就会面临比特币的算力攻击;容易产生分叉,需要等待多个确认;永远没有最终性,需要检查点机制来弥补最终性。
目前基于PoW共识机制的数字货币有很多,比特币、莱特币、狗狗币、达士币、门罗币等初期的数字货币大多都是PoW共识机制。% j; X- b3 y* W4 \: J: v& o
其他的共识机制还有2 s' X* ?' e: ~; G, F$ ]+ 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共识机制
这些共识机制,后面有时间会补充上的,今天主要介绍POW
pow很简单,原理就是 利用计算力,在选择一个nonce的值结合区块的数据算出hash,使得hash的前面多少位都是0.8 z* A0 Q& b* R( G1 J0 W
nonce是一个用来找到满足条件的hash值的数字,nonce值一直迭代,直到hash值有效为止。在我们案例中一个有效的hash值是最少有4个前导0。找到nonce值以满足合适条件的hash值的过程就叫做挖矿。
下面给出代码:
- golang版1 \9 l5 G3 g/ N3 F; D
- package mainimport ( "bytes". H8 g, f6 b1 t5 b
- "crypto/sha256"& u) @! T1 I+ T
- "fmt": A* c6 H) Y! G! L3 E' p4 E( u3 A
- "math"
- "math/big")// 前导0,难度const targetBits = 8type ProofOfWork struct {. d Z* ^& V- ]! P$ i
- block *Block
- targetBit *big.Int
- }func NewProofOfWork(block *Block) *ProofOfWork { // 设置64位全1
- var IntTarget = big.NewInt(1) //000000000000000000000000000012 x. q1 t/ o2 s9 n9 d7 z# x
- //10000000000000000000000000000
- //00000000000100000000000000000
- //0000001
- // 右移 targetBits位
- IntTarget.Lsh(IntTarget, uint(256 - targetBits)) return &ProofOfWork{block:block, targetBit:IntTarget}4 K: Y% i7 q6 T
- }func (pow *ProofOfWork)PrepareRawData(nonce int64)[]byte {8 U# _& ]4 M# L% X S! y
- block := pow.block8 H& G9 e' x; U, d0 T, u1 u
- tmp := [][]byte{
- Int2Byte(block.Version),0 L8 \/ @! |* Y" @5 W& k
- block.PrevBlockHash,
- Int2Byte(block.TimeStamp),
- block.MerkeRoot,
- Int2Byte(nonce),
- Int2Byte(targetBits),
- block.Data}
- data := bytes.Join(tmp, []byte{}) return data* v7 E" d6 S3 m* x9 e
- }func (pow *ProofOfWork)Run() (int64, []byte) { var nonce int64" h9 ]9 p3 c, G- j# W F3 R$ |
- 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;: ?4 j% h2 |7 n: g
- }import hashlib"""
- 工作量证明3 t8 D( N2 s7 A- ]2 K. O
- """class ProofofWork():% f5 \# S- u2 S6 N. s
- """
- pow
- """
- def __init__(self, block):
- self.block = block def mine(self):8 S2 i6 }0 T: T' |/ o
- """: Y( n" O8 R n5 Y, ]9 B1 i
- 挖矿函数2 o8 s3 ^( S8 z
- :return:, G) t, f: L, h9 o! `# l6 l2 {
- """
- i = 0
- prefix = '0000'2 `/ O2 E. N# a6 U
- while True:
- nonce = str(i)2 L9 V6 s) U( j C8 x
- message = hashlib.sha256()
- message.update(str(self.block.data).encode('utf-8'))
- message.update(nonce.encode("utf-8"))! q8 e/ K" g: q! ~, n, @
- digest = message.hexdigest() if digest.startswith(prefix): return nonce, digest
- i += 1