查看: 110|回复: 0

[Java语言] 兄弟连区块链教程分享区块链POW证明代码实现demo

发表于 2018-10-17 16:36:52
  兄弟连区块链教程分享区块链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版
  1. <p>package main</p><p>
  2. </p><p>import (</p><p>    "bytes"</p><p>    "crypto/sha256"</p><p>    "fmt"</p><p>    "math"</p><p>    "math/big"</p><p>)</p><p>
  3. </p><p>// 前导0,难度</p><p>const targetBits  = 8</p><p>
  4. </p><p>type ProofOfWork struct {</p><p>    block *Block</p><p>    targetBit *big.Int</p><p>
  5. </p><p>}</p><p>
  6. </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>
  7. </p><p>    return &ProofOfWork{block:block, targetBit:IntTarget}</p><p>}</p><p>
  8. </p><p>func (pow *ProofOfWork)PrepareRawData(nonce int64)[]byte  {</p><p>
  9. </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>
  10. </p><p>    data := bytes.Join(tmp, []byte{})</p><p>    return data</p><p>}</p><p>
  11. </p><p>func (pow *ProofOfWork)Run() (int64, []byte) {</p><p>
  12. </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>
  13. </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: %x\n", hash)</p><p>            break</p><p>        } else {</p><p>            nonce++</p><p>        }</p><p>
  14. </p><p>    }</p><p>    return nonce, hash[:]</p><p>}</p><p>
  15. </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>
  16. </p><p>}</p>
复制代码

python版
  1. <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>
  2. </p><p>import hashlib</p><p>
  3. </p><p>"""</p><p>工作量证明</p><p>"""</p><p>
  4. </p><p>
  5. </p><p>class ProofofWork():</p><p>    """</p><p>    pow</p><p>    """</p><p>
  6. </p><p>    def __init__(self, block):</p><p>        self.block = block</p><p>
  7. </p><p>    def mine(self):</p><p>        """</p><p>        挖矿函数</p><p>        :return:</p><p>        """</p><p>        i = 0</p><p>        prefix = '0000'</p><p>
  8. </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



回复

使用道具 举报