go語言區(qū)塊鏈實戰(zhàn)實現(xiàn)簡單的區(qū)塊與區(qū)塊鏈
區(qū)塊鏈實戰(zhàn)
| 字節(jié) | 字段 | 說明 |
|---|---|---|
| 4 | 版本 | 區(qū)塊版本號,表示本區(qū)塊遵守的驗證規(guī)則 |
| 32 | 父區(qū)塊頭哈希值 | 前一區(qū)塊的Merkle樹根的哈希值,同樣采取SHA256計算 |
| 32 | Merkle根 | 該區(qū)塊中交易的Merkle樹根的哈希值,同樣采用SHA256計算 |
| 4 | 時間戳 | 該區(qū)塊產(chǎn)生的近似時間,精確到秒的UNIX時間戳,必須嚴格大于前11各區(qū)塊的時間的中值,同時全節(jié)點也會拒接那些超過自己兩個小時的時間戳的區(qū)塊 |
| 4 | 難度目標 | 該區(qū)塊工作量證明算法的難度目標,已經(jīng)使用特定算法編碼 |
| 4 | Nonce | 未來找到滿足難度目標所設定的隨機數(shù),為了解決32為隨機數(shù)在算力飛升的情況下不夠用的問題,規(guī)定時間戳和coinbase交易信息均改變,以此擴展nonce的位數(shù) |
注意:區(qū)塊不存儲hash值,節(jié)點接受區(qū)塊后獨立計算并存儲在本地。
Version 1
區(qū)塊相關:
1.定義一個區(qū)塊的結構Block
a.區(qū)塊頭:6個字段
b.區(qū)塊體:字符串表示data
2.提供一個創(chuàng)建區(qū)塊的方法
NewBlock(參數(shù))
區(qū)塊鏈相關
定義一個區(qū)塊鏈結構BlockChain
Block數(shù)組
提供一個創(chuàng)建BlockChain()的方法
NewBlockChain()
提供一個添加區(qū)塊的方法
AddBlock(參數(shù))
block.go文件
package main
import (
"bytes"
"crypto/sha256"
"time"
)
/*
1.定義一個區(qū)塊的結構Block
a.區(qū)塊頭:6個字段
b.區(qū)塊體:字符串表示data
*/
//區(qū)塊
type Block struct {
Version int64 //版本
PerBlockHash []byte //前一個區(qū)塊的hash值
Hash []byte //當前區(qū)塊的hash值,是為了簡化代碼
MerKelRoot []byte //梅克爾根
TimeStamp int64 //時間抽
Bits int64 //難度值
Nonce int64 //隨機值
//區(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é)點接受區(qū)塊后獨立計算并存儲在本地。
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{}) //之后再計算hash
hash := sha256.Sum256(data)
block.Hash = hash[:] //變切片
}
//創(chuàng)始塊
func NewGensisBlock() *Block{
return NewBlock("Genesis Block!",[]byte{})
}
blockChain.go文件
package main
/*
1. 定義一個區(qū)塊鏈結構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í)行結果

以上就是go語言區(qū)塊鏈實戰(zhàn)實現(xiàn)簡單的區(qū)塊與區(qū)塊鏈的詳細內容,更多關于go語言實現(xiàn)區(qū)塊與區(qū)塊鏈的資料請關注腳本之家其它相關文章!
相關文章
基于Golang實現(xiàn)Excel表格的導入導出功能
最近項目開發(fā)中有涉及到Excel的導入與導出功能,特別是導出表格時需要特定的格式,所以本文給大家介紹了基于Golang實現(xiàn)Excel表格的導入導出功能,文中通過代碼示例和圖文介紹的非常詳細,需要的朋友可以參考下2023-12-12
go select編譯期的優(yōu)化處理邏輯使用場景分析
select 是 Go 中的一個控制結構,類似于用于通信的 switch 語句。每個 case 必須是一個通信操作,要么是發(fā)送要么是接收。接下來通過本文給大家介紹go select編譯期的優(yōu)化處理邏輯使用場景分析,感興趣的朋友一起看看吧2021-06-06

