目錄:
創(chuàng)新互聯(lián)服務(wù)項(xiàng)目包括??稻W(wǎng)站建設(shè)、保康網(wǎng)站制作、保康網(wǎng)頁制作以及保康網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,??稻W(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到??凳》莸牟糠殖鞘校磥硐嘈艜?huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!
一.初始化區(qū)塊鏈
1.代碼結(jié)構(gòu)
2. 定義區(qū)塊結(jié)構(gòu)與方法
3. 定義區(qū)塊鏈結(jié)構(gòu)與方法
4. 幫助庫代碼
5. 測(cè)試生成區(qū)塊與初始化區(qū)塊鏈
6. 測(cè)試代碼
二. POW挖礦實(shí)現(xiàn)
1.代碼結(jié)構(gòu)
2. 定義pow算法實(shí)現(xiàn)
3. 修改區(qū)塊的生成方式(從自定義到挖礦)
4. 測(cè)試代碼,測(cè)試挖礦
5.驗(yàn)證區(qū)塊有效性
一.初始化區(qū)塊鏈
1. 代碼結(jié)構(gòu)
Block.go :定義區(qū)塊結(jié)構(gòu)與方法
BlockChain.go :定義區(qū)塊鏈結(jié)構(gòu)與方法
help.go :將常用代碼塊進(jìn)行封裝,形成幫助庫
main.go:測(cè)試代碼
2.定義區(qū)塊結(jié)構(gòu)與方法
package BLC import ( "time" "strconv" "bytes" "crypto/sha256" ) //定義區(qū)塊 type Block struct { //1.區(qū)塊高度,也就是區(qū)塊的編號(hào),第幾個(gè)區(qū)塊 Height int64 //2.上一個(gè)區(qū)塊的Hash值 PreBlockHash []byte //3.交易數(shù)據(jù)(最終都屬于transaction 事務(wù)) Data []byte //4.創(chuàng)建時(shí)間的時(shí)間戳 TimeStamp int64 //5.當(dāng)前區(qū)塊的Hash值 Hash []byte //6.Nonce 隨機(jī)數(shù),用于驗(yàn)證工作量證明 Nonce int64 } //定義區(qū)塊生成Hash的方法 func (block *Block) SetHash() { //1.將Height 轉(zhuǎn)換為字節(jié)數(shù)組 []byte heightBytes := IntToHex(block.Height) //2.將TimeStamp 轉(zhuǎn)換為字節(jié)數(shù)組 []byte //2.1 將Int64的TimeStamp 轉(zhuǎn)換成二進(jìn)制 timeString := strconv.FormatInt(block.TimeStamp, 2) //2.2 將二進(jìn)制字符串轉(zhuǎn)成字節(jié)數(shù)組 timeBytes := []byte(timeString) //3.拼接所有屬性,形成一個(gè)二維的byte數(shù)組 blockBytes := bytes.Join([][]byte{heightBytes, block.PreBlockHash, block.Data, timeBytes, block.Hash}, []byte{}) //4.生成Hash hash := sha256.Sum256(blockBytes) block.Hash = hash[:] } //1. 創(chuàng)建新的區(qū)塊 func NewBlock(data string, height int64, PreBlockHash []byte) *Block { //創(chuàng)建區(qū)塊 block := &Block{ height, PreBlockHash, []byte(data), time.Now().Unix(), nil, 0, } //設(shè)置Hash block.SetHash() return block } //2.生成創(chuàng)世區(qū)塊 func CreateGenesisBlock(data string) *Block { return NewBlock(data, 1, []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}) }
3.定義區(qū)塊鏈與方法
package BLC type BlockChain struct { Blocks []*Block //存儲(chǔ)有序的區(qū)塊 } func (blc *BlockChain)AddBlockChain(data string,height int64,preHash []byte){ //創(chuàng)建新區(qū)塊 newBlock := NewBlock(data,height,preHash) //往鏈中添加區(qū)塊 blc.Blocks=append(blc.Blocks,newBlock) } //1.創(chuàng)建帶有創(chuàng)世區(qū)塊的區(qū)塊鏈 func CreateBlockChainWithGenesisBlock() *BlockChain { //創(chuàng)建創(chuàng)世區(qū)塊 genesisBlock := CreateGenesisBlock("Genesis Data..") //返回區(qū)塊鏈對(duì)象 return &BlockChain{[]*Block{genesisBlock}} }
4.幫助代碼庫
package BLC import ( "bytes" "encoding/binary" "log" ) //將int64轉(zhuǎn)換為字節(jié)數(shù)組 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() }
5.測(cè)試代碼
package main import ( "publicChain/BLC" "fmt" ) func main() { //創(chuàng)建創(chuàng)世區(qū)塊 blockChain := BLC.CreateBlockChainWithGenesisBlock() //創(chuàng)建新的區(qū)塊 blockChain.AddBlockChain("Send $100 to Bruce", blockChain.Blocks[len(blockChain.Blocks)-1].Height+1, blockChain.Blocks[len(blockChain.Blocks)-1].Hash) blockChain.AddBlockChain("Send $200 to Apple", blockChain.Blocks[len(blockChain.Blocks)-1].Height+1, blockChain.Blocks[len(blockChain.Blocks)-1].Hash) blockChain.AddBlockChain("Send $300 to Alice", blockChain.Blocks[len(blockChain.Blocks)-1].Height+1, blockChain.Blocks[len(blockChain.Blocks)-1].Hash) blockChain.AddBlockChain("Send $400 to Bob", blockChain.Blocks[len(blockChain.Blocks)-1].Height+1, blockChain.Blocks[len(blockChain.Blocks)-1].Hash) fmt.Printf("創(chuàng)建的區(qū)塊鏈為:\t%v\n", blockChain) fmt.Printf("區(qū)塊鏈存儲(chǔ)的區(qū)塊為:\t%v\n", blockChain.Blocks) fmt.Printf("第二個(gè)區(qū)塊的數(shù)據(jù)信息(交易信息)為:\t%v\n", string(blockChain.Blocks[1].Data)) }
結(jié)果顯示
二. POW挖礦實(shí)現(xiàn)
1.代碼結(jié)構(gòu)
多出的ProofOfWork.go用于實(shí)現(xiàn)挖礦
2. 定義pow算法實(shí)現(xiàn)
ProofOfWork.go
package BLC import ( "math/big" "bytes" "crypto/sha256" "fmt" "time" ) type ProofOfWork struct { Block *Block //當(dāng)前要驗(yàn)證的區(qū)塊 target *big.Int //大數(shù)存儲(chǔ),區(qū)塊難度 } //數(shù)據(jù)拼接,返回字節(jié)數(shù)組 func (pow *ProofOfWork) prePareData(nonce int) []byte { data := bytes.Join( [][]byte{ pow.Block.PreBlockHash, pow.Block.Data, IntToHex(pow.Block.TimeStamp), IntToHex(int64(targetBit)), IntToHex(int64(nonce)), IntToHex(int64(pow.Block.Height)), }, []byte{}, ) return data } //256位Hash里面至少要有16個(gè)零0000 0000 0000 0000 const targetBit = 16 func (proofOfWork *ProofOfWork) Run(num int64) ([]byte, int64) { //3.判斷Hash的有效性,如果滿足條件循環(huán)體 nonce := 0 var hashInt big.Int //存儲(chǔ)新生成的hash值 var hash [32]byte for { //1. 將Block的屬性拼接成字節(jié)數(shù)組 databytes := proofOfWork.prePareData(nonce) //2.生成Hash hash = sha256.Sum256(databytes) fmt.Printf("挖礦中..%x\n", hash) //3. 將hash存儲(chǔ)至hashInt hashInt.SetBytes(hash[:]) //4.判斷hashInt是否小于Block里面的target // Cmp compares x and y and returns: // // -1 if x < y // 0 if x == y // +1 if x > y //需要hashInt(y)小于設(shè)置的target(x) if proofOfWork.target.Cmp(&hashInt) == 1 { //fmt.Println("挖礦成功", hashInt) fmt.Printf("第%d個(gè)區(qū)塊,挖礦成功:%x\n",num,hash) fmt.Println(time.Now()) time.Sleep(time.Second * 2) break } nonce ++ } return hash[:], int64(nonce) } //創(chuàng)建新的工作量證明對(duì)象 func NewProofOfWork(block *Block) *ProofOfWork { /*1.創(chuàng)建初始值為1的target 0000 0001 8 - 2 */ target := big.NewInt(1) //2.左移256-targetBit target = target.Lsh(target, 256-targetBit) return &ProofOfWork{block, target} }
3. 修改區(qū)塊的生成方式(從自定義到挖礦)
Block.go
package BLC import ( "time" ) //定義區(qū)塊 type Block struct { //1.區(qū)塊高度,也就是區(qū)塊的編號(hào),第幾個(gè)區(qū)塊 Height int64 //2.上一個(gè)區(qū)塊的Hash值 PreBlockHash []byte //3.交易數(shù)據(jù)(最終都屬于transaction 事務(wù)) Data []byte //4.創(chuàng)建時(shí)間的時(shí)間戳 TimeStamp int64 //5.當(dāng)前區(qū)塊的Hash值 Hash []byte //6.Nonce 隨機(jī)數(shù),用于驗(yàn)證工作量證明 Nonce int64 } //1. 創(chuàng)建新的區(qū)塊 func NewBlock(data string, height int64, PreBlockHash []byte) *Block { //創(chuàng)建區(qū)塊 block := &Block{ height, PreBlockHash, []byte(data), time.Now().Unix(), nil, 0, } //調(diào)用工作量證明的方法,并且返回有效的Hash和Nonce值 //創(chuàng)建pow對(duì)象 pow := NewProofOfWork(block) //挖礦驗(yàn)證 hash, nonce := pow.Run(height) block.Hash = hash[:] block.Nonce = nonce return block } //2.生成創(chuàng)世區(qū)塊 func CreateGenesisBlock(data string) *Block { return NewBlock(data, 1, []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}) }
4. 測(cè)試代碼,測(cè)試挖礦
main.go
package main import ( "publicChain/part2-工作量證明/BLC" "fmt" ) func main() { fmt.Println("開始挖礦") //創(chuàng)建創(chuàng)世區(qū)塊 blockChain := BLC.CreateBlockChainWithGenesisBlock() //創(chuàng)建新的區(qū)塊 blockChain.AddBlockChain("Send $100 to Bruce", blockChain.Blocks[len(blockChain.Blocks)-1].Height+1, blockChain.Blocks[len(blockChain.Blocks)-1].Hash) blockChain.AddBlockChain("Send $200 to Apple", blockChain.Blocks[len(blockChain.Blocks)-1].Height+1, blockChain.Blocks[len(blockChain.Blocks)-1].Hash) blockChain.AddBlockChain("Send $300 to Alice", blockChain.Blocks[len(blockChain.Blocks)-1].Height+1, blockChain.Blocks[len(blockChain.Blocks)-1].Hash) blockChain.AddBlockChain("Send $400 to Bob", blockChain.Blocks[len(blockChain.Blocks)-1].Height+1, blockChain.Blocks[len(blockChain.Blocks)-1].Hash) fmt.Printf("創(chuàng)建的區(qū)塊鏈為:\t%v\n", blockChain) fmt.Printf("區(qū)塊鏈存儲(chǔ)的區(qū)塊為:\t%v\n", blockChain.Blocks) fmt.Printf("第二個(gè)區(qū)塊的數(shù)據(jù)信息(交易信息)為:\t%v\n", string(blockChain.Blocks[1].Data)) fmt.Printf("第二個(gè)區(qū)塊的隨機(jī)數(shù)為:\t%v\n", blockChain.Blocks[1].Nonce) }
測(cè)試結(jié)果
共計(jì)對(duì)五個(gè)區(qū)塊進(jìn)行挖礦,結(jié)果如上
5.驗(yàn)證區(qū)塊有效性
ProofOfWork.go
//判斷挖礦得到的區(qū)塊是否有效 func (proofOfWork *ProofOfWork) IsValid() bool { //1.proofOfWork.Block.Hash //2.proofOfWork.Target var hashInt big.Int hashInt.SetBytes(proofOfWork.Block.Hash) if proofOfWork.target.Cmp(&hashInt) == 1 { return true } return false }
測(cè)試代碼:
main.go
//通過POW挖出新的區(qū)塊block block := BLC.NewBlock("Send $500 to Tom", blockChain.Blocks[len(blockChain.Blocks)-1].Height+1, blockChain.Blocks[len(blockChain.Blocks)-1].Hash) //手動(dòng)將該區(qū)塊添加至區(qū)塊鏈中 blockChain.Blocks = append(blockChain.Blocks, block) //創(chuàng)建一個(gè)工作量證明對(duì)象 proofOfWork := BLC.NewProofOfWork(block) //判斷該區(qū)塊是否合法有效 fmt.Println(proofOfWork.IsValid())
測(cè)試結(jié)果:
第六個(gè)區(qū)塊是我們新創(chuàng)建的區(qū)塊,返回值為true,驗(yàn)證有效
參考資料:
區(qū)塊鏈共識(shí)算法-POW: https://www.jianshu.com/p/b23cbafbbad2
當(dāng)前標(biāo)題:區(qū)塊鏈初始化與實(shí)現(xiàn)POW工作量證明
URL鏈接:http://aaarwkj.com/article34/gojgpe.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供標(biāo)簽優(yōu)化、微信公眾號(hào)、網(wǎng)站收錄、移動(dòng)網(wǎng)站建設(shè)、App開發(fā)、商城網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)