Brotherly Block Chain Introduction Tutorial Sharing Block Chain POW Proof Code Implementation demo

Keywords: Go network Python

Here we emphasize the protocol hierarchy of block chains.
Application layer
Contract level
Incentive mechanism
Consensus level
Network layer
Data layer
In the last article, we mainly realized the data layer of block chain. The main technology used in the data layer is to check the data and find hash.
This paper introduces the workload to prove that POW belongs to the consensus mechanism.
In the PoW mechanism, the allocation of money and the determination of accounting rights are carried out according to the workload of miners. The winner of the arithmetic competition will receive the corresponding block bookkeeping rights and bitcoin awards. Therefore, the higher the power of miner chips, the longer the mining time, the more digital money can be obtained.
Advantage:
The algorithm is simple and easy to implement; there is no need to exchange additional information between nodes to reach a consensus; destroying the system requires a huge cost.
Disadvantages:
Energy is wasted; block confirmation time is difficult to shorten; new block chains must find a different hashing algorithm, otherwise they will face the computational attack of bitcoin; easy to produce bifurcation, need to wait for multiple confirmations; there will never be finality, need checkpoint mechanism to make up for finality.
At present, there are many digital currencies based on the PoW consensus mechanism. Most of the initial digital currencies such as Bitcoin, Wright coin, Dog coin, Das coin and Monroe coin are the PoW consensus mechanism.
Other consensus mechanisms include
PoS(Proof of Stake)
DPOS(Delegated Proof-of-Stake)
DAG(Directed acyclic graph)
PBFT(Practical Byzantine Fault Tolerance)
Pool verification pool
dBFT(delegated BFT)
PoA(Proof-of-Authority)
RPCA(Ripple Protocol consensus algorithm)
Hcash-PoW+PoS Consensus Mechanism
These consensus mechanisms, which will be supplemented later, will be introduced today.
pow is very simple, the principle is to use computational power, in the selection of a non CE value combined with block data to calculate hash, so that the number of bits in front of hash is 0.
Nonce is a number used to find a hash value that satisfies the condition. The nonce value is iterated until the hash value is valid. In our case, a valid hash value is at least four leading zeros. The process of finding a hash value that satisfies the appropriate conditions is called mining.
The following code is given:
golang version

package main

import (
    "bytes"
    "crypto/sha256"
    "fmt"
    "math"
    "math/big"
)

// Leader 0, difficulty
const targetBits  = 8

type ProofOfWork struct {
    block *Block
    targetBit *big.Int

}

func NewProofOfWork(block *Block) *ProofOfWork  {
    // Setting 64 bits all 1
    var IntTarget = big.NewInt(1)
    //00000000000000000000000000001
    //10000000000000000000000000000
    //00000000000100000000000000000
    //0000001
    // Move the targetBits bit to the right
    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)
        // The hash value (int) calculated here is correct as long as it is smaller than the largest IntTarget.
        if HashInt.Cmp(pow.targetBit) == -1 {
            fmt.Printf("Found Hash: %x\n", hash)
            break
        } else {
            nonce++
        }

    }
    return nonce, hash[:]
}

// Data Check for 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 version

function isValidHashDifficulty(hash, difficulty) {
  for (var i = 0, b = hash.length; i < b; i ++) {
      if (hash[i] !== '0') {
          break;
      }
  }
  return i >= difficulty;
}

import hashlib

"""
//proof of work
"""


class ProofofWork():
    """
    pow
    """

    def __init__(self, block):
        self.block = block

    def mine(self):
        """
        //Mining function
        :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

Posted by elementaluk on Fri, 01 Feb 2019 08:36:16 -0800