golang實現簡單區塊鏈demo

原理就不介紹了,具體可以去看我的另一篇 ofollow,noindex">通過一個App Demo的演示深入理解區塊鏈執行原理 程式碼只是最簡單的,只是簡單的實現了對一個區塊的定義以及區塊之間的聯絡。在這裡p2p,激勵,共識都沒有。
區塊鏈重要的 資料層、網路層、共識層、激勵層
下面的程式碼只是展示了資料層上面的東西,後續會把剩餘的補充上,好好學習,天天向上。加油。

package main import ( "bytes" "crypto/sha256" "encoding/binary" "fmt" "os" "time" ) // 實現int轉換成byte陣列 func Int2Byte(num int64) []byte { var buffer bytes.Buffer err := binary.Write(&buffer, binary.BigEndian, num) CheckErr(err) return buffer.Bytes() } func CheckErr(err error) { if err != nil { fmt.Println("err:", err) os.Exit(1) } } //區塊的結構 type Block struct { Versionint64 PrevBlockHash []byte Hash[]byte TimeStampint64 TargetBitsint64 Nonceint64 MerkeRoot[]byte Data[]byte } func NewBlock(data string, prevBlockHash []byte) *Block { block := &Block{ Version:1, PrevBlockHash: prevBlockHash, TimeStamp:time.Now().Unix(), TargetBits:10, Nonce:5, MerkeRoot:[]byte{}, Data:[]byte(data)} block.SetHash() return block } // int -> byte func (block *Block) SetHash() { tmp := [][]byte{ //實現將int轉成byte陣列的函式 Int2Byte(block.Version), block.PrevBlockHash, Int2Byte(block.TimeStamp), block.MerkeRoot, Int2Byte(block.Nonce), block.Data} //將區塊個欄位連線成一個切片,使用[]byte{}進行連線 data := bytes.Join(tmp, []byte{}) //算出hash的值 hash := sha256.Sum256(data) block.Hash = hash[:] } func NewGenesisBlock() *Block { return NewBlock("Genesis Block!", []byte{}) } type BlockChian struct { //使用切片儲存區塊,用於模擬區塊鏈 blocks []*Block } func NewBlockChain() *BlockChian { //建立一個區塊鏈 return &BlockChian{[]*Block{NewGenesisBlock()}} } func (bc *BlockChian) AddBlock(data string) { // 防止區塊越界 if len(bc.blocks) <= 0 { os.Exit(1) } lastBlock := bc.blocks[len(bc.blocks)-1] block := NewBlock(data, lastBlock.Hash) bc.blocks = append(bc.blocks, block) } func main() { // 例項化一個區塊鏈 bc := NewBlockChain() //新增block bc.AddBlock("測試第一個BTC") bc.AddBlock("測試第二個EOS") //打印出資訊 for i, block := range bc.blocks { fmt.Println("=========block num:", i) fmt.Println("data", string(block.Data)) fmt.Println("Version:", block.Version) fmt.Printf("Hash:%x\n", block.Hash) fmt.Printf("TimeStamp:%d\n", block.TimeStamp) fmt.Printf("MerkeRoot:%x\n", block.MerkeRoot) fmt.Printf("None:%d\n", block.Nonce) } }
