golang-Blockchain Learning 02 Proof of workload

Source: Internet
Author: User

Objective

On the basis of the previous "golang-Blockchain learning 01", we have increased our blockchain workload proof.

Knowledge points

1, Blockchain proofofwork (proof of workload) concept, because everyone wants to generate blocks to get rewards, for the sake of fairness, we stipulate that to successfully generate a block must complete the task of the specified difficulty. That is, whoever completes the task with the specified difficulty will successfully generate a chunk. First set aside an egg, combined with an example of the workload proof will be summarized at the end of the text.

Golang to achieve a simple workload proof

1, define a workload difficulty. For example, the hash value of the required chunk must be 0 in front of the five bits. That is, hash similar: 00000xxxxxxxxxxx style.
2, add a nonce variable in the block structure, by constantly modifying the value of the nonce, constantly calculate the entire area of the hash value, until the above requirements can be met.
3. code example
Create a Proofofwork.go file. Define a structure for proof of work

type ProofOfWork struct {    block  *Block    // 即将生成的区块对象    target *big.Int    //生成区块的难度}

Create an instantiated proof of work structure.

const targetBits = 20func NewProofOfWork(b *Block) *ProofOfWork {    target := big.NewInt(1)    //难度:target=10的18次方(即要求计算出的hash值小于这个target)    target.Lsh(target, uint(256-targetBits))    pow := &ProofOfWork{b, target}    return pow}

Algorithm for calculating hash value

func (pow *ProofOfWork) Run() (int, []byte) {    var hashInt big.Int    var hash [32]byte    nonce := 0// 从0自增    fmt.Printf("Mining the block containing \"%s\"\n", pow.block.Data)    // 循环从nonce=0一直计算到nonce=2的64次方的值,知道算出符合要求的hash值    for nonce < maxNonce {      // 准备计算hash的数据        data := pow.prepareData(nonce)        hash = sha256.Sum256(data)// 计算hash        fmt.Printf("\r%x", hash)        hashInt.SetBytes(hash[:])        // 难度证明        if hashInt.Cmp(pow.target) == -1 {            break// 符合        } else {            nonce++// 不符合继续计算        }    }    fmt.Printf("\n\n")    return nonce, hash[:]}

Preparing data

func (pow *ProofOfWork) prepareData(nonce int) []byte {    data := bytes.Join([][]byte{        pow.block.PrevBlockHash,        pow.block.Data,        IntToHex(pow.block.TimeStamp),        IntToHex(int64(targetBits)),        IntToHex(int64(nonce)),    }, []byte{})    return data}

Attachment

Formula on the code. List of all code files.
/lession02/src/coin/main.go

package mainimport (    "fmt"    "core"    "strconv")func main() {fmt.Printf("%d\n",uint(256-20))    bc := core.NewBlockChain()    bc.AddBlock("send 1 btc to Ivan")    bc.AddBlock("send 2 btc to Ivan")    for _, block := range bc.Blocks {        fmt.Printf("PrevBlockHash:%x\n", block.PrevBlockHash)        fmt.Printf("Data:%s\n", block.Data)        fmt.Printf("Hash:%x\n", block.Hash)        fmt.Printf("TimeStamp:%d\n", block.TimeStamp)        fmt.Printf("Nonce:%d\n", block.Nonce)        pow := core.NewProofOfWork(block)        fmt.Printf("Pow is %s\n", strconv.FormatBool(pow.Validate()))        println()    }}

/lession02/src/core/block.go

package coreimport (    "time"    "strconv"    "bytes"    "crypto/sha256")type Block struct {    TimeStamp     int64    Data          []byte    PrevBlockHash []byte    Hash          []byte    Nonce         int}func NewBlock(data string, prevBlockHash []byte) *Block {    block := &Block{time.Now().Unix(), []byte(data), prevBlockHash, []byte{}, 0}    pow := NewProofOfWork(block)    block.Nonce, block.Hash = pow.Run()    return block}func (b *Block) SetHash() {    strTimeStamp := []byte(strconv.FormatInt(b.TimeStamp, 10))    headers := bytes.Join([][]byte{b.PrevBlockHash, b.Data, strTimeStamp}, []byte{})    hash := sha256.Sum256(headers)    b.Hash = hash[:]}func NewGenesisBlock() *Block {    return NewBlock("Genesis Block", []byte{})}

/lession02/src/core/blockchain.go

package coretype BlockChain struct {    Blocks []*Block}func (bc *BlockChain) AddBlock(data string) {    preBlock := bc.Blocks[len(bc.Blocks)-1]    newBlock := NewBlock(data, preBlock.Hash)    bc.Blocks = append(bc.Blocks, newBlock)}func NewBlockChain() *BlockChain {    return &BlockChain{[]*Block{NewGenesisBlock()}}}

/lession02/src/core/proofofwork.go

Package Coreimport ("math" "Math/big" "FMT" "crypto/sha256" "bytes") var (maxnonce = math). MaxInt64) Const Targetbits = 20type proofofwork struct {block *block target *big. Int}func Newproofofwork (b *block) *proofofwork {target: = big. Newint (1) target. Lsh (target, UINT (256-targetbits)) Pow: = &proofofwork{b, Target} return Pow}func (Pow *proofofwork) preparedata ( nonce int) []byte {data: = bytes. Join ([][]byte{Pow.block.PrevBlockHash, Pow.block.Data, Inttohex (pow.block.TimeStamp), Inttohe X (Int64 (targetbits)), Inttohex (Int64 (Nonce)),}, []byte{}) return Data}func (Pow *proofofwork) Run () (int, [] byte) {var hashint big. Int var hash [32]byte nonce: = 0 fmt. Printf ("Mining The block containing \"%s\ "\ n", Pow.block.Data) for nonce < maxnonce {Data: = Pow.preparedata (nonce) hash = sha256. Sum256 (data) fmt. Printf ("\r%x", hash) hashint.setbytes (hash[:]) if haSHINT.CMP (pow.target) = =-1 {break} else {nonce++}} fmt. Printf ("\ n") return nonce, Hash[:]}func (Pow *proofofwork) Validate () bool {var hashint big. Int Data: = Pow.preparedata (pow.block.Nonce) Hash: = sha256. Sum256 (data) hashint.setbytes (hash[:]) IsValid: = hashint.cmp (pow.target) = =-1 return isValid}

/lession02/src/core/utils.go

package coreimport (    "bytes"    "encoding/binary"    "log"    "crypto/sha256")func IntToHex(num int64) []byte {    buff := new(bytes.Buffer)    err := binary.Write(buff, binary.BigEndian, num)    if err != nil {        log.Panic(err)    }    return buff.Bytes()}func DataToHash(data []byte) []byte {    hash := sha256.Sum256(data)    return hash[:]}
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.