go語言區(qū)塊鏈實(shí)戰(zhàn)實(shí)現(xiàn)簡單的區(qū)塊與區(qū)塊鏈
區(qū)塊鏈實(shí)戰(zhàn)
字節(jié) | 字段 | 說明 |
---|---|---|
4 | 版本 | 區(qū)塊版本號,表示本區(qū)塊遵守的驗(yàn)證規(guī)則 |
32 | 父區(qū)塊頭哈希值 | 前一區(qū)塊的Merkle樹根的哈希值,同樣采取SHA256計(jì)算 |
32 | Merkle根 | 該區(qū)塊中交易的Merkle樹根的哈希值,同樣采用SHA256計(jì)算 |
4 | 時間戳 | 該區(qū)塊產(chǎn)生的近似時間,精確到秒的UNIX時間戳,必須嚴(yán)格大于前11各區(qū)塊的時間的中值,同時全節(jié)點(diǎn)也會拒接那些超過自己兩個小時的時間戳的區(qū)塊 |
4 | 難度目標(biāo) | 該區(qū)塊工作量證明算法的難度目標(biāo),已經(jīng)使用特定算法編碼 |
4 | Nonce | 未來找到滿足難度目標(biāo)所設(shè)定的隨機(jī)數(shù),為了解決32為隨機(jī)數(shù)在算力飛升的情況下不夠用的問題,規(guī)定時間戳和coinbase交易信息均改變,以此擴(kuò)展nonce的位數(shù) |
注意:區(qū)塊不存儲hash值,節(jié)點(diǎn)接受區(qū)塊后獨(dú)立計(jì)算并存儲在本地。
Version 1
區(qū)塊相關(guān):
1.定義一個區(qū)塊的結(jié)構(gòu)Block
a.區(qū)塊頭:6個字段
b.區(qū)塊體:字符串表示data
2.提供一個創(chuàng)建區(qū)塊的方法
NewBlock(參數(shù))
區(qū)塊鏈相關(guān)
定義一個區(qū)塊鏈結(jié)構(gòu)BlockChain
Block數(shù)組
提供一個創(chuàng)建BlockChain()的方法
NewBlockChain()
提供一個添加區(qū)塊的方法
AddBlock(參數(shù))
block.go文件
package main import ( "bytes" "crypto/sha256" "time" ) /* 1.定義一個區(qū)塊的結(jié)構(gòu)Block a.區(qū)塊頭:6個字段 b.區(qū)塊體:字符串表示data */ //區(qū)塊 type Block struct { Version int64 //版本 PerBlockHash []byte //前一個區(qū)塊的hash值 Hash []byte //當(dāng)前區(qū)塊的hash值,是為了簡化代碼 MerKelRoot []byte //梅克爾根 TimeStamp int64 //時間抽 Bits int64 //難度值 Nonce int64 //隨機(jī)值 //區(qū)塊體 Data []byte //交易信息 } /* 提供一個創(chuàng)建區(qū)塊的方法 NewBlock(參數(shù)) */ func NewBlock(data string ,prevBlockHash []byte) *Block { var block Block block = Block{ Version: 1, PerBlockHash: prevBlockHash, //Hash: []byte{}, //區(qū)塊不存儲hash值,節(jié)點(diǎn)接受區(qū)塊后獨(dú)立計(jì)算并存儲在本地。 MerKelRoot: []byte{}, TimeStamp: time.Now().Unix(), Bits: 1, Nonce: 1, Data: []byte(data), } block.SetHash() //填充Hash return &block } func (block *Block) SetHash() { // 源碼里面是要傳二維切片 func Join(s [][]byte, sep []byte) []byte tmp :=[][]byte{ IntToByte(block.Version), block.PerBlockHash, block.MerKelRoot, IntToByte(block.TimeStamp), IntToByte(block.Bits), IntToByte(block.Nonce), } data:=bytes.Join(tmp,[]byte{}) //之后再計(jì)算hash hash := sha256.Sum256(data) block.Hash = hash[:] //變切片 } //創(chuàng)始塊 func NewGensisBlock() *Block{ return NewBlock("Genesis Block!",[]byte{}) }
blockChain.go文件
package main /* 1. 定義一個區(qū)塊鏈結(jié)構(gòu)BlockChain Block數(shù)組 */ type BlockChain struct { blocks []*Block } /* 2. 提供一個創(chuàng)建BlockChain()的方法 NewBlockChain() */ func NewBlockChain() *BlockChain { block := NewGensisBlock() return &BlockChain{blocks:[]*Block{block}} //創(chuàng)建只有一個元素的區(qū)塊鏈,初始化 } /* 3. 提供一個添加區(qū)塊的方法 AddBlock(參數(shù)) */ func (bc *BlockChain)AddBlock(data string) { PerBlockHash := bc.blocks[len(bc.blocks)-1].Hash //這一個區(qū)塊的哈希是前一塊的哈希值 block := NewBlock(data,PerBlockHash) bc.blocks = append(bc.blocks,block) }
utils.go文件
package main import ( "bytes" "encoding/binary" "fmt" "os" ) func IntToByte(num int64) []byte { //func Write(w io.Writer, order ByteOrder, data interface{}) error { var buffer bytes.Buffer err := binary.Write(&buffer, binary.BigEndian, num) CheckErr("IntToByte",err) return buffer.Bytes() } func CheckErr(position string,err error) { if err != nil { fmt.Println("error ,pos:",position,err) os.Exit(1) } }
main.go文件
package main import "fmt" func main() { bc := NewBlockChain() bc.AddBlock("A send B 1BTC") bc.AddBlock("B send C 1BTC") for _,block := range bc.blocks { fmt.Printf("Version : %d\n",block.Version) fmt.Printf("PerBlockHash : %x\n",block.PerBlockHash) fmt.Printf("Hash : %x\n",block.Hash) fmt.Printf("MerKelRoot : %x\n",block.MerKelRoot) fmt.Printf("TimeStamp : %d\n",block.TimeStamp) fmt.Printf("Bits : %d\n",block.Bits) fmt.Printf("Nonce : %d\n",block.Nonce) fmt.Printf("Data : %s\n",block.Data) } }
執(zhí)行結(jié)果
以上就是go語言區(qū)塊鏈實(shí)戰(zhàn)實(shí)現(xiàn)簡單的區(qū)塊與區(qū)塊鏈的詳細(xì)內(nèi)容,更多關(guān)于go語言實(shí)現(xiàn)區(qū)塊與區(qū)塊鏈的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
提升編程技能:學(xué)習(xí)如何在Go語言中正確格式化時間
想知道如何在Go語言中輕松地格式化時間嗎?別再浪費(fèi)時間了!本文將帶你快速入門,讓你的代碼更加優(yōu)雅高效,快來學(xué)習(xí)吧!2024-01-01基于Golang實(shí)現(xiàn)Excel表格的導(dǎo)入導(dǎo)出功能
最近項(xiàng)目開發(fā)中有涉及到Excel的導(dǎo)入與導(dǎo)出功能,特別是導(dǎo)出表格時需要特定的格式,所以本文給大家介紹了基于Golang實(shí)現(xiàn)Excel表格的導(dǎo)入導(dǎo)出功能,文中通過代碼示例和圖文介紹的非常詳細(xì),需要的朋友可以參考下2023-12-12總結(jié)Go語言中defer的使用和注意要點(diǎn)
Go語言中的defer關(guān)鍵字實(shí)現(xiàn)比較特殊的功能,這篇文章給大家總結(jié)了關(guān)于Go語言中defer的使用和注意要點(diǎn),有需要的朋友們可以參考借鑒,下面來一起看看吧。2016-09-09go select編譯期的優(yōu)化處理邏輯使用場景分析
select 是 Go 中的一個控制結(jié)構(gòu),類似于用于通信的 switch 語句。每個 case 必須是一個通信操作,要么是發(fā)送要么是接收。接下來通過本文給大家介紹go select編譯期的優(yōu)化處理邏輯使用場景分析,感興趣的朋友一起看看吧2021-06-06