久久精品精选,精品九九视频,www久久只有这里有精品,亚洲熟女乱色综合一区
    分享

    區塊鏈實戰(二)PoW工作量證明的實現

     小生凡一 2021-11-30

    Version 2

    1. 定義一個工作量證明的結構ProofOfWork

      block

    ? 目標值

    1. 提供一個創造PoW的方法

      NewProofOfWork(參數)

    2. 提供一個計算哈希值的方法

      Run()

    3. 提供一個校驗函數

      IsValid()

    結構目錄
    在這里插入圖片描述

    block.go

    package main
    
    import (
       "time"
    )
    
    /*
    1.定義一個區塊的結構Block
    a.區塊頭:6個字段
    b.區塊體:字符串表示data
    */
    //區塊
    type Block struct {
       Version int64   //版本
       PerBlockHash []byte //前一個區塊的hash值
       Hash []byte //當前區塊的hash值,是為了簡化代碼
       MerKelRoot []byte  //梅克爾根
       TimeStamp int64  //時間抽
       Bits int64  //難度值
       Nonce int64 //隨機值
    
    //區塊體
       Data []byte  //交易信息
    }
    
    /*
    提供一個創建區塊的方法
    NewBlock(參數)
    */
    func NewBlock(data string ,prevBlockHash []byte) *Block {
       var block Block
       block = Block{
          Version:      2,
          PerBlockHash: prevBlockHash,
          //Hash:         []byte{},      //區塊不存儲hash值,節點接受區塊后獨立計算并存儲在本地。
          MerKelRoot:   []byte{},
          TimeStamp:    time.Now().Unix(),
          Bits:         targetBits,
          Nonce:        0,
          Data:         []byte(data),
       }
       // block.SetHash()  //填充Hash
       PoW:= NewProofOfWork(&block)
       nonce , hash :=PoW.Run()
       block.Nonce=nonce
       block.Hash=hash
       return &block
    }
    
    /*
    func (block *Block) SetHash() {
       // 源碼里面是要傳二維切片 func Join(s [][]byte, sep []byte) []byte
       tmp :=[][]byte{
          IntToByte(block.Version),
          block.PerBlockHash,
          block.MerKelRoot,
          IntToByte(block.TimeStamp),
          IntToByte(block.Bits),
          IntToByte(block.Nonce),
       }
       data:=bytes.Join(tmp,[]byte{})    //之后再計算hash
       hash := sha256.Sum256(data)
       block.Hash = hash[:]  //變切片
    }
    */
    
    
    //創始塊
    func NewGensisBlock() *Block{
       return NewBlock("Genesis Block!",[]byte{})
    }
    

    blockChain.go

    package main
    
    
    /*
    1. 定義一個區塊鏈結構BlockChain
       Block數組
    */
    type BlockChain struct {
       blocks []*Block
    }
    
    /*
    2. 提供一個創建BlockChain()的方法
       NewBlockChain()
    */
    func NewBlockChain() *BlockChain {
       block := NewGensisBlock()
       return &BlockChain{blocks:[]*Block{block}}  //創建只有一個元素的區塊鏈,初始化
    }
    /*
    3. 提供一個添加區塊的方法
       AddBlock(參數)
    */
    
    func (bc *BlockChain)AddBlock(data string)  {
       PerBlockHash := bc.blocks[len(bc.blocks)-1].Hash  //這一個區塊的哈希是前一塊的哈希值
       block := NewBlock(data,PerBlockHash)
       bc.blocks = append(bc.blocks,block)
    }
    

    proofOfWork.go

    package main
    
    import (
       "bytes"
       "crypto/sha256"
       "fmt"
       "math"
       "math/big"
    )
    
    /*
    1. 定義一個工作量證明的結構ProofOfWork
    block
    目標值
    */
    type ProofOfWork struct {
       block *Block
       target *big.Int   //目標值
    }
    /*
    2. 提供一個創造PoW的方法
    NewProofOfWork(參數)
    */
    const targetBits = 24 
    
    func NewProofOfWork(block *Block) *ProofOfWork {  //工作量證明
       target := big.NewInt(1)  //000....001
       target.Lsh(target,uint(256-targetBits))  //將1向左移動 //ox00000010000000..00
       pow:=ProofOfWork{
          block:  block,
          target: target,
       }
       return &pow
    }
    
    func (pow *ProofOfWork) PrepareData(nonce int64) []byte {
       // 源碼里面是要傳二維切片 func Join(s [][]byte, sep []byte) []byte
       block := pow.block
       tmp :=[][]byte{
          IntToByte(block.Version),
          block.PerBlockHash,
          block.MerKelRoot,
          IntToByte(block.TimeStamp),
          IntToByte(block.Bits),
          IntToByte(block.Nonce),
       }
       data:=bytes.Join(tmp,[]byte{})    //之后再計算hash
       return data
    }
    
    /*
    2. 提供一個計算哈希值的方法
    Run()
    */
    
    func (pow *ProofOfWork)Run() (int64,[]byte) {
        /*偽代碼
       for nonce  {
          hash := sha256(block_data+nonce)
          if (hash) < pow.target{
             flag=1
          }else{
             flag=0
          }
       }
            return nonce,hash[:]
       */
       //1.憑借數據
       //2.哈希值轉成big.Int類型
       var hash [32]byte
       var nonce int64 = 0
       var hashInt big.Int
       fmt.Println("開始挖礦了!")
       fmt.Printf("難度 target hash : %x\n" ,pow.target.Bytes())
       for nonce < math.MaxInt64  {
          data:=pow.PrepareData(nonce)
          hash = sha256.Sum256(data)
          // Cmp compares x and y and returns:
          //
          //   -1 if x <  y
          //    0 if x == y
          //   +1 if x >  y
          //
          hashInt.SetBytes(hash[:])
          if hashInt.Cmp(pow.target) == -1 {
             fmt.Printf("Found ,nonce :%d ,hash :%x \n",nonce,hash)
          }else {
             //fmt.Printf("Not Found ,current nonce :%d ,hash :%x \n",nonce,hash)
             nonce++
          }
       }
       return nonce,hash[:]
    }
    /*
    3. 提供一個校驗函數
    IsValid()
    */
    
    func (pow *ProofOfWork)IsValid() bool{
       var hashInt big.Int
       data := pow.PrepareData(pow.block.Nonce)
       hash:=sha256.Sum256(data)
       hashInt.SetBytes(hash[:])
       return hashInt.Cmp(pow.target) == -1  //如果是-1就是找到了就是
    
    }
    

    utils.go

    package main
    
    import (
       "bytes"
       "encoding/binary"
       "fmt"
       "os"
    )
    
    func IntToByte(num int64) []byte {
       //func Write(w io.Writer, order ByteOrder, data interface{}) error {
       var buffer bytes.Buffer
       err := binary.Write(&buffer, binary.BigEndian, num)
       CheckErr("IntToByte",err)
       return buffer.Bytes()
    }
    
    func CheckErr(position string,err error) {
       if err != nil {
          fmt.Println("error ,pos:",position,err)
          os.Exit(1)
       }
    }
    

    main.go

    package main
    
    import "fmt"
    
    func main() {
       bc := NewBlockChain()
       bc.AddBlock("A send B 1BTC")
       bc.AddBlock("B send C 1BTC")
       for _,block := range bc.blocks {
          fmt.Printf("Version : %d\n",block.Version)
          fmt.Printf("PerBlockHash : %x\n",block.PerBlockHash)
          fmt.Printf("Hash : %x\n",block.Hash)
          fmt.Printf("MerKelRoot : %x\n",block.MerKelRoot)
          fmt.Printf("TimeStamp : %d\n",block.TimeStamp)
          fmt.Printf("Bits : %d\n",block.Bits)
          fmt.Printf("Nonce : %d\n",block.Nonce)
          fmt.Printf("Data : %s\n",block.Data)
          fmt.Printf("IsVaild : %v\n",NewProofOfWork(block).IsValid())
       }
    }
    

    結果

    在這里插入圖片描述

    結構

    在這里插入圖片描述

      轉藏 分享 獻花(0

      0條評論

      發表

      請遵守用戶 評論公約

      類似文章 更多

      主站蜘蛛池模板: 日本一区不卡高清更新二区 | 亚洲国产在一区二区三区| XXXXXHD亚洲日本HD| 国产美熟女乱又伦AV果冻传媒 | 亚洲AV无码专区亚洲AV桃| JAPANESE国产在线观看播放| 亚洲AV伊人久久综合密臀性色| 在线中文字幕国产精品| 久久天堂综合亚洲伊人HD妓女| 久久久久久亚洲精品| 国产尤物精品自在拍视频首页| 国产女人高潮视频在线观看| 亚洲一区二区精品另类| 欧美日韩一区二区综合| 肥臀浪妇太爽了快点再快点| 日产精品一卡2卡三卡四乱码| 久久精品无码免费不卡| 亚洲欧美日韩成人综合一区| 少妇肉麻粗话对白视频| 美乳丰满人妻无码视频| 天天做天天爱天天综合网2021 | 中文字幕乱码一区二区免费| 亚洲自偷自拍另类小说| 亚洲春色在线视频| 50岁熟妇的呻吟声对白| 无套后入极品美女少妇| 一个人免费视频观看在线WWW| 草裙社区精品视频播放| 成人H视频在线观看| 夜鲁夜鲁很鲁在线视频 视频| 在线 | 18精品免费1区2| 亚洲伊人久久综合影院| 国产好大好硬好爽免费不卡| 久久天天躁夜夜躁狠狠| 中文成人无码精品久久久| 成人做受120秒试看试看视频| 国产AV无码专区亚洲AV毛片搜| 精品一区二区成人精品| 中文字幕在线精品人妻| WWW夜插内射视频网站| 人妻综合专区第一页|