兄弟连区块链教程分享区块链POW证明代码实现demo,2018年下半年,区块链行业正逐渐褪去发展之初的浮躁、回归理性,表面上看相关人才需求与身价似乎正在回落。但事实上,正是初期泡沫的渐退,让人们更多的关注点放在了区块链真正的技术之上。
这里强调一下区块链的协议分层
应用层
合约层
激励机制
共识层
网络层
数据层
上 一篇主要实现了区块链的 数据层,数据层主要使用的技术就是对数据的校验,求hash。
这里介绍工作量证明POW, POW是属于共识机制的内容。
PoW机制中根据矿工的工作量来执行货币的分配和记账权的确定。算力竞争的胜者将获得相应区块记账权和比特币奖励。因此,矿机芯片的算力越高,挖矿的时间更长,就可以获得更多的数字货币。
优点:
算法简单,容易实现;节点间无需交换额外的信息即可达成共识;破坏系统需要投入极大的成本。
缺点:
浪费能源;区块的确认时间难以缩短;新的区块链必须找到一种不同的散列算法,否则就会面临比特币的算力攻击;容易产生分叉,需要等待多个确认;永远没有最终性,需要检查点机制来弥补最终性。
目前基于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共识机制
这些共识机制,后面有时间会补充上的,今天主要介绍POW
pow很简单,原理就是 利用计算力,在选择一个nonce的值结合区块的数据算出hash,使得hash的前面多少位都是0.
nonce是一个用来找到满足条件的hash值的数字,nonce值一直迭代,直到hash值有效为止。在我们案例中一个有效的hash值是最少有4个前导0。找到nonce值以满足合适条件的hash值的过程就叫做挖矿。
下面给出代码:
golang版
- <p>package main</p><p>
- </p><p>import (</p><p> "bytes"</p><p> "crypto/sha256"</p><p> "fmt"</p><p> "math"</p><p> "math/big"</p><p>)</p><p>
- </p><p>// 前导0,难度</p><p>const targetBits = 8</p><p>
- </p><p>type ProofOfWork struct {</p><p> block *Block</p><p> targetBit *big.Int</p><p>
- </p><p>}</p><p>
- </p><p>func NewProofOfWork(block *Block) *ProofOfWork {</p><p> // 设置64位全1</p><p> var IntTarget = big.NewInt(1)</p><p> //00000000000000000000000000001</p><p> //10000000000000000000000000000</p><p> //00000000000100000000000000000</p><p> //0000001</p><p> // 右移 targetBits位</p><p> IntTarget.Lsh(IntTarget, uint(256 - targetBits))</p><p>
- </p><p> return &ProofOfWork{block:block, targetBit:IntTarget}</p><p>}</p><p>
- </p><p>func (pow *ProofOfWork)PrepareRawData(nonce int64)[]byte {</p><p>
- </p><p> block := pow.block</p><p> tmp := [][]byte{</p><p> Int2Byte(block.Version),</p><p> block.PrevBlockHash,</p><p> Int2Byte(block.TimeStamp),</p><p> block.MerkeRoot,</p><p> Int2Byte(nonce),</p><p> Int2Byte(targetBits),</p><p> block.Data}</p><p>
- </p><p> data := bytes.Join(tmp, []byte{})</p><p> return data</p><p>}</p><p>
- </p><p>func (pow *ProofOfWork)Run() (int64, []byte) {</p><p>
- </p><p> var nonce int64</p><p> var hash [32]byte</p><p> var HashInt big.Int</p><p> fmt.Printf("target hash:", pow.targetBit.Bytes())</p><p> for nonce < math.MaxInt64 {</p><p> data := pow.PrepareRawData(nonce)</p><p> hash = sha256.Sum256(data)</p><p>
- </p><p> HashInt.SetBytes(hash[:])</p><p> //fmt.Println(nonce)</p><p> // 这里用于 判断算出的hash值(int)只要比最大的IntTarget小就是正确的。</p><p> if HashInt.Cmp(pow.targetBit) == -1 {</p><p> fmt.Printf("Found Hash: %xn", hash)</p><p> break</p><p> } else {</p><p> nonce++</p><p> }</p><p>
- </p><p> }</p><p> return nonce, hash[:]</p><p>}</p><p>
- </p><p>// 对block的数据校验</p><p>func (pow *ProofOfWork)IsVaild() bool {</p><p> data := pow.PrepareRawData(pow.block.Nonce)</p><p> hash := sha256.Sum256(data)</p><p> var IntHash big.Int</p><p> IntHash.SetBytes(hash[:])</p><p> return IntHash.Cmp(pow.targetBit) == -1</p><p>
- </p><p>}</p>
复制代码
python版
- <p>function isValidHashDifficulty(hash, difficulty) {</p><p> for (var i = 0, b = hash.length; i < b; i ++) {</p><p> if (hash[i] !== '0') {</p><p> break;</p><p> }</p><p> }</p><p> return i >= difficulty;</p><p>}</p><p>
- </p><p>import hashlib</p><p>
- </p><p>"""</p><p>工作量证明</p><p>"""</p><p>
- </p><p>
- </p><p>class ProofofWork():</p><p> """</p><p> pow</p><p> """</p><p>
- </p><p> def __init__(self, block):</p><p> self.block = block</p><p>
- </p><p> def mine(self):</p><p> """</p><p> 挖矿函数</p><p> :return:</p><p> """</p><p> i = 0</p><p> prefix = '0000'</p><p>
- </p><p> while True:</p><p> nonce = str(i)</p><p> message = hashlib.sha256()</p><p> message.update(str(self.block.data).encode('utf-8'))</p><p> message.update(nonce.encode("utf-8"))</p><p> digest = message.hexdigest()</p><p> if digest.startswith(prefix):</p><p> return nonce, digest</p><p> i += 1</p>
复制代码 区块链行业高薪缺人,
时代的红利你要不要分一杯羹!
今晚19点30分,清华尹成团队带你10天夯实区块链开发基础,深入解读golang的基本数据类型与流程控制
听课地址:https://ke.qq.com/course/334561
|