2000行程式碼用go語言實現的比特幣基本的相關模型功能
阿新 • • 發佈:2018-12-20
|版權宣告:本文為博主原創文章,未經博主允許不得轉載。部落格地址:https://blog.csdn.net/sgsgy5
前言:閒暇時期,參考了一些資料,用go簡單的實現了比特幣中的一些相關功能,實現完全大概2000行程式碼左右,現在剛利用閒暇時間寫了一點小功能,大概500多行程式碼左右,只實現了基本的區塊連結,儲存是選擇了github上面的一個開源庫,bolt輕量級資料庫,還有很多需要迭代完善,這個月內打算完善好,可供參考
- 區塊的結構,和區塊鏈的結構定義,一些相關功能沒有加入,後期會加入,比如交易,UTXO等
- pow工作量證明,現在不夠完善,後期會完善
- 錢包結點的相關功能,後期會完善
- 加密的相關功能,後期會完善
type Block struct { //區塊的一個結構 Version uint64 //版本號 PrevBlockHash []byte //前區塊雜湊值 MerkelRoot []byte //這是一個雜湊值,後面完善 TimeStamp uint64 //時間戳,從1970.1.1到現在的秒數 Difficulty uint64 //通過這個數字,算出一個雜湊值:0x00010000000xxx,暫時寫死難度,程式碼裡面大概5個前導0以上本地普通電腦就跑不動了 Nonce uint64 // 這是我們要找的隨機數,挖礦就找證書 Hash []byte //當前區塊雜湊值, 正常的區塊不存在,我們為了方便放進來 Data []byte //資料本身,區塊體,先用字串表示,v4版本的時候會引用真正的交易結構 }
//定義一個區塊鏈結構,使用bolt資料庫進行儲存
type BlockChain struct { //儲存在資料庫中,會生成一個檔案
//資料庫的控制代碼
Db *bolt.DB
//最後一個區塊的雜湊值
lastHash []byte //在記憶體中的臨時值,只儲存最後一個區塊雜湊
}
const difficulty = 16 //難度值寫死暫時,後期完善 //1. 定義工作量證明, block, 難度值 type ProofOfWork struct { //資料來源 block Block //難度值 target *big.Int //一個能夠處理大數的內建的型別,有比較方法 }
上面是一些基本的結構, 這裡比較主要的就是工作量證明函式 我們來看一下實現方式
func (pow *ProofOfWork) Run() ([]byte, uint64) {
//1. 拿到區塊資料
//block := pow.block
//區塊的雜湊值
var currentHash [32]byte
//挖礦的隨機值
var nonce uint64
for {
info := pow.prepareData(nonce)
//2. 對資料做雜湊運算
currentHash = sha256.Sum256(info)
//3. 比較
//引用big.int,將獲取的[]byte型別的雜湊值轉成big.int
var currentHashInt big.Int
currentHashInt.SetBytes(currentHash[:])
// -1 if x < y
// 0 if x == y
// +1 if x > y
//
//func (x *Int) Cmp(y *Int) (r int) {
if currentHashInt.Cmp(pow.target) == -1 {
//a. 比目標小,成功,返回雜湊和nonce
break
} else {
//b. 比目標大,繼續nonce++
nonce++
}
}
return currentHash[:], nonce
}
這裡的雜湊運算就是,加上隨機數來運算雜湊,一直找找到一個隨機數使得雜湊符合難度值 比目標雜湊是00001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,那麼就需要找比這個雜湊小的雜湊,就是前面一定要有5個0的雜湊才符合要求,這樣打包區塊才是有效的,
我們這裡就簡單實現了,後期迭代會加入UTXO,交易機制,還有錢包結點相關功能,歡迎提意見,