區塊鏈工作量證明
阿新 • • 發佈:2019-01-02
-
簡單實現
proofOfWork.go
package main import ( "math/big" "bytes" "math" "crypto/sha256" "fmt" ) type ProofOfWork struct { block *Block //目標值 target *big.Int } const targetBits = 24 func NewProofOfWork(block *Block) *ProofOfWork{ //000000000000000....01 target := big.NewInt(1) //0x000000100000000000 16進位制 target.Lsh(target,256-targetBits) pow := ProofOfWork{block,target} return &pow } //拼裝資料 func (pow *ProofOfWork)PrepareData(nonce int64) []byte{ block := pow.block tmp := [][]byte{ IntToByte(block.Version), block.PrevBlockHash, block.MerKelRoot, IntToByte(block.TimeStamp), IntToByte(targetBits), IntToByte(nonce), block.Data} data := bytes.Join(tmp,[]byte{}) return data } func (pow *ProofOfWork)Run()(int64,[]byte){ //1. 拼裝資料 //2. 雜湊值轉成big.Int型別 /* for nonce{ hash := sha256(block資料 + nonce) if 轉換(hash) < pow.target { 找到了 }else{ nonce++ } } return nonce, hash[:] */ var nonce int64 = 0 var hash [32]byte var hashInt big.Int fmt.Println("Begin Mining...") fmt.Printf("target hash: %x\n",pow.target.Bytes()) for nonce < math.MaxInt64{ data := pow.PrepareData(nonce) hash = sha256.Sum256(data) hashInt.SetBytes(hash[:]) if hashInt.Cmp(pow.target) == -1 { fmt.Printf("found hash : %x, nonce : %d\n", hash, nonce) break }else { nonce++ } } return nonce,hash[:] } func (pow *ProofOfWork)IsVaild()bool{ var hashInt big.Int data := pow.PrepareData(pow.block.Nonce) hash := sha256.Sum256(data) hashInt.SetBytes(hash[:]) return hashInt.Cmp(pow.target) == -1 }
block.go
package main import ( "time" ) type Block struct { Version int64 PrevBlockHash []byte Hash []byte MerKelRoot []byte TimeStamp int64 Bits int64 Nonce int64 Data []byte } func NewBlock(data string,prevBlockHash []byte) *Block{ var block Block block = Block { Version:1, PrevBlockHash:prevBlockHash, MerKelRoot: []byte{}, TimeStamp:time.Now().Unix(), Bits:targetBits, Nonce:0, Data:[]byte(data)} //block.SetHash() pow :=NewProofOfWork(&block) nonce,hash := pow.Run() block.Nonce = nonce block.Hash = hash return &block } func NewGenesisBlock() *Block{ return NewBlock("Genesis Block",[]byte{}) }
-
總結(思維導圖)