1. 程式人生 > 程式設計 >使用go實現簡易比特幣區塊鏈公鏈功能

使用go實現簡易比特幣區塊鏈公鏈功能

使用go語言實現具備以下功能的簡易區塊鏈

  • 區塊與區塊鏈
  • 共識機制
  • 資料庫
  • Cli命令列操作
  • 交易管理
  • 密碼學
  • 數字簽名
  • 交易快取池
  • P2P網路管理

由於平時還要進行論文工作,專案不定時更新

2021.1.1實現了區塊結構、區塊鏈結構、工作量證明pow,剩下部分陸續更新

1.實現區塊結構

package BLC

import (
	"bytes"
	"crypto/sha256"
	"time"
)

//實現一個最基本的區塊結構
type Block struct {
	TimeStamp int64 //時間戳,區塊產生的時間
	Heigth int64//區塊高度(索引、號碼)代表當前區塊的高度
	PreBlockHash []byte//前一個區塊(父區塊)的雜湊
	Hash []byte//當前區塊的雜湊
	Data []byte//交易資料
}
//建立一個新的區塊
func NewBlock(height int64,preBlockHash []byte,Data []byte) *Block {
	var block Block
	block=Block{Heigth: height,PreBlockHash: preBlockHash,Data: Data,TimeStamp: time.Now().Unix()}
	block.SetHash()
	return &block
}
//計算區塊雜湊
func (b *Block)SetHash() { 
	//int64轉換成位元組陣列
	//高度轉換
	heightBytes:=IntToHex(b.Heigth)
	//時間轉換
	timeStampBytes:=IntToHex(b.TimeStamp)
//拼接所有屬性進行hash
	blockBytes:=bytes.Join([][]byte{heightBytes,timeStampBytes,b.PreBlockHash,b.Data},[]byte{})
	hash:=sha256.Sum256(blockBytes)
	b.Hash=hash[:]
}

2.實現區塊鏈結構

package BLC

type BlockChain struct {
	Blocks []*Block //儲存有序的區塊
}
//初始化區塊鏈
func CreateBlockChainWithGenesisBlock() *BlockChain {
	//新增創世區塊
	genesisBlock:=CreateGenesisBlock("the init of blockchain")

	return &BlockChain{[]*Block{genesisBlock}}
}
//新增新的區塊到區塊鏈中
func (bc *BlockChain)AddBlock(height int64,data []byte,prevBlockHash []byte){
	newBlock := NewBlock(height,prevBlockHash,data)
	bc.Blocks=append(bc.Blocks,newBlock)
}

3.實現工作量證明

package BLC

import (
	"bytes"
	"crypto/sha256"
	"fmt"
	"math/big"
)

//目標難度值,生成的hash前 targetBit 位為0才滿足條件
const targetBit =16
//工作量證明
type ProofOfWork struct {
	Block *Block //對指定的區塊進行驗證
	target *big.Int //大資料儲存
}
//建立新的pow物件
func NewProofOfWork(block *Block) *ProofOfWork {
	target:=big.NewInt(1)
	target=target.Lsh(target,256-targetBit)
	return &ProofOfWork{block,target}
}
//開始工作量證明
func (proofOfWork *ProofOfWork)Run() ([]byte,int64) {
	//資料拼接
	var nonce=0 //碰撞次數
	var hash [32]byte //生成的hash
	var hashInt big.Int //儲存轉換後的hash
	for {
		dataBytes:=proofOfWork.prepareData(nonce)
		hash=sha256.Sum256(dataBytes)
		hashInt.SetBytes(hash[:])
		fmt.Printf("hash:\r%x",hash)
		//難度比較
		if proofOfWork.target.Cmp(&hashInt)==1{
			break
		}
		nonce++
	}
	fmt.Printf("碰撞次數:%d\n",nonce)
	return hash[:],int64(nonce)
}
//準備資料,將區塊屬性拼接起來,返回位元組陣列
func (pow *ProofOfWork)prepareData(nonce int) []byte {
	data:=bytes.Join([][]byte{
		pow.Block.PreBlockHash,pow.Block.Data,IntToHex(pow.Block.TimeStamp),IntToHex(pow.Block.Heigth),IntToHex(int64(nonce)),IntToHex(targetBit),},[]byte{})
	return data
}

4.當前執行結果

在這裡插入圖片描述

到此這篇關於使用go實現簡易比特幣區塊鏈公鏈功能的文章就介紹到這了,更多相關go實現比特幣區塊鏈公鏈內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!