什么是作業量證明
Proof Of Work,簡稱POW,即對作業量的證明,
為什么要做作業量證明
**挖礦(計算or作業)**的結果會作為資料加入區塊鏈成為一個區塊,完成這個**作業**的人也會獲得獎勵(即挖礦獲得位元幣),
所以**挖礦**的程序是一種多勞多得的按勞分配模式,算力高,花費的時間多,獲得的數字貨幣也就越多,
所以必須要證明礦工們為了得到答案確實進行了**計算**,
怎么樣做作業量證明
哈希演算法
SHA256:一種將任意長度的訊息壓縮到某一固定長度的訊息摘要的函式
為什么選擇哈希演算法
①哈希演算法不是加密演算法,也就是沒有密碼,根據一個哈希值看不出或者說得不到原始資料,非常安全,
②一個唯一的原始資料,只能有唯一一個哈希,而且在已知原始資料和演算法的前提下,可以較快計算出一個哈希值,
作業量證明代碼
①pay attention to “//新加”
需要注意的是“ { ”不能單獨放在一行,但是為了清晰,下面的代碼都手動做了處理!
需要注意的是“ { ”不能單獨放在一行,但是為了清晰,下面的代碼都手動做了處理!
需要注意的是“ { ”不能單獨放在一行,但是為了清晰,下面的代碼都手動做了處理!
②main.go檔案
package main
import (
"../core"
"fmt"
"strconv"
)
func main()
{
bc :=core.NewBlockchain()
bc.AddBlock("Send 1 BTC to Ivan")
bc.AddBlock("Send 2 createblockchain -address hanshuhuan more BTC to Ivan")
for _,block :=range bc.Blocks
{
fmt.Printf( "Prev. hash: %x\n",block.PrevBlockHash)
fmt.Printf( "Data: %s\n",block.Data)
fmt.Printf( "Hash: %x\n",block.Hash)
//新加:證明某個block的作業量
pow :=core.NewProofOfWork(block)
//新加:校驗演算法
fmt.Printf("PoW:%s\n",strconv.FormatBool(pow.Validate()))
fmt.Println()
}
}
③block.go檔案
package core
import (
"bytes"
"crypto/sha256"
"encoding/gob"
"log"
"time"
)
type Block struct
{
Timestamp int64
Transactions []*Transaction
PrevBlockHash []byte
Hash []byte
//新加
Nonce int
}
func NewBlock(transactions []*Transaction, prevBlockHash []byte) *Block
{
block := &Block
{
Timestamp: time.Now().Unix(),
Transactions: transactions,
PrevBlockHash: prevBlockHash,
Hash: []byte{},
//新加
Nonce: 0
}
//新加:創建一個作業量證明
pow := NewProofOfWork(block)
//進行作業量證明
nonce, hash := pow.Run()
block.Hash = hash[:]
//新加
block.Nonce = nonce
return block
}
func (b *Block) SetHash()
{
timestamp :=[]byte(strconv.FormatInt(b.Timestamp,10))
headers :=bytes.Join([][]byte{b.PrevBlockHash,b.Data,timestamp},[]byte{})
hash :=sha256.Sum256(headers)
b.Hash=hash[:]
}
func NewGenesisBlock() *Block
{
return NewBlock( "Genesis Block",[]byte{})
}
④proofofwork.go檔案
package core;l
import (
"bytes"
"crypto/sha256"
"fmt"
"math"
"math/big"
)
var
(
maxNonce=math.MaxInt64
)
//決定了挖礦的難度
const targetBits = 20
//ProofOfWork represents a proof-of-work對這個區塊計算要滿足目標
type ProofOfWork struct
{
block *Block
target *big.Int
}
//NewProofOfWork builds and returns a ProofOfWork
func NewProofOfWork(b *Block) *ProofOfWork
{
//首先確定一個固定的整數1
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),
IntToHex(int64(targetBits)),
//前面四項都是不可變的
IntToHex(int64(nonce)),
},
[]byte{},
)
return data
}
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 (pow *ProofOfWork) Run()(int,[]byte)
{
var hashInt big.Int
var hash [32]byte
nonce :=0
//開始計算
fmt.Printf("Mining the blockcontaining \"%s\"\n",pow.block.Data)
//一個一個對比
for nonce < maxNonce
{
//由四項不可變資料+一個可變數字nonce組成
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\n")
return nonce,hash[:]
}
// Validate 校驗演算法
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
}
⑤blockchain.go檔案
沒有改動
⑥util.go檔案
package core
import
(
"bytes"
"encoding/binary"
"log"
)
// IntToHex Convert an int64 to a byte array
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()
}
運行結果展示

運行結果解釋
從main檔案開始,創建了一個區塊鏈,回傳了一個創世紀塊,然后又新加了兩個區塊(這三個區塊都經歷了newblock()這個方法,所以都會進行作業量證明),然后遍歷這個區塊鏈(陣列),輸出每一個區塊的“前一個哈希值、本身的資料、后一個區塊的哈希值”,然后去證明每個區塊的作業量(詳情請見注釋),并輸出最后證明的結果,
總結
通過一個“看似沒有用的演算法”,得到一個“看似沒有用,但是又很麻煩的數”,因為這個計算的程序非常耗費時間(其實費電),所以這個作業量就有了價值,
首先得到這個結果的人把答案發布到網上,其他人都可以去證明(校驗演算法),都承認這個結果正確之后,那個首先拿到答案的人就有了位元幣,
隨著時間的推移,位元幣全網算力不斷增加,演算法運行需要消耗的CPU越來越多,導致設備所需算力提高,位元幣挖礦變得越發困難,所以位元幣越來越難拿到,但是它本身數量有限,所以位元幣越來越值錢,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/313175.html
標籤:區塊鏈
下一篇:區塊鏈技術——框架&基本原型
