区块链POW证明代码实现demo

论坛 期权论坛 区块链     
若与   2018-11-20 23:26   4792   0
            

这里强调一下区块链的协议分层
  • 应用层
  • 合约层
  • 激励机制
  • 共识层
  • 网络层
  • 数据层
上 一篇主要实现了区块链的 数据层,数据层主要使用的技术就是对数据的校验,求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.
  1. nonce
复制代码
是一个用来找到满足条件的
  1. hash
复制代码
值的数字,
  1. nonce
复制代码
值一直迭代,直到
  1. hash
复制代码
值有效为止。在我们案例中一个有效的hash值是最少有
  1. 4
复制代码
个前导
  1. 0
复制代码
。找到
  1. nonce
复制代码
值以满足合适条件的
  1. hash
复制代码
值的过程就叫做挖矿。
下面给出代码:
golang版
  1. package mainimport (    "bytes"    "crypto/sha256"    "fmt"    "math"    "math/big")// 前导0,难度const targetBits  = 8type ProofOfWork struct {    block *Block    targetBit *big.Int}func NewProofOfWork(block *Block) *ProofOfWork  {    // 设置64位全1    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    tmp := [][]byte{        Int2Byte(block.Version),        block.PrevBlockHash,        Int2Byte(block.TimeStamp),        block.MerkeRoot,        Int2Byte(nonce),        Int2Byte(targetBits),        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 < math.MaxInt64 {        data := pow.PrepareRawData(nonce)        hash = sha256.Sum256(data)        HashInt.SetBytes(hash[:])        //fmt.Println(nonce)        // 这里用于 判断算出的hash值(int)只要比最大的IntTarget小就是正确的。        if HashInt.Cmp(pow.targetBit) == -1 {            fmt.Printf("Found Hash: %x\n", hash)            break        } else {            nonce++        }    }    return nonce, hash[:]}// 对block的数据校验func (pow *ProofOfWork)IsVaild() bool {    data := pow.PrepareRawData(pow.block.Nonce)    hash := sha256.Sum256(data)    var IntHash big.Int    IntHash.SetBytes(hash[:])    return IntHash.Cmp(pow.targetBit) == -1}
复制代码
python版
  1. function isValidHashDifficulty(hash, difficulty) {  for (var i = 0, b = hash.length; i < b; i ++) {      if (hash[i] !== '0') {          break;      }  }  return i >= difficulty;}import hashlib"""工作量证明"""class ProofofWork():    """    pow    """    def __init__(self, block):        self.block = block    def mine(self):        """        挖矿函数        :return:        """        i = 0        prefix = '0000'        while True:            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
复制代码
         
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:229
帖子:5
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP