algorithm 4th

用Go语言构建自己的区块链

2019-01-06  本文已影响0人  百炼

date[2019-01-06]

注意:
当main包里面有多个go文件时,使用go build *.go运行,当然最好的办法是main包里面就保留一个go文件。

用Go语言构建自己的区块链

package blockchain_core

import (
    "crypto/sha256"
    "encoding/hex"
    "time"
)

type Block struct {
    Index         int64  //区块编号
    Timestamp     int64  //区块时间
    PrevBlockHash string //上一个区块的哈希值
    Hash          string //当前区块的哈希值
    Data          string //区块数据
}

func calculateHash(b Block) string {
    blockData := string(b.Index) + string(b.Timestamp) + b.PrevBlockHash + b.Data
    hashInBytes := sha256.Sum256([]byte(blockData))
    return hex.EncodeToString(hashInBytes[:])
}

func GenerateNewBlock(preBlock Block, data string) Block {
    newBlock := Block{}
    newBlock.Index = preBlock.Index + 1
    newBlock.PrevBlockHash = preBlock.Hash
    newBlock.Timestamp = time.Now().Unix()
    newBlock.Data = data
    newBlock.Hash = calculateHash(newBlock)
    return newBlock
}

func GenerateGenesisBlock() Block {
    preBlock := Block{}
    preBlock.Index = -1
    preBlock.Hash = ""
    return GenerateNewBlock(preBlock, "Genesis Block")
}
package blockchain_core

import (
    "fmt"
    "log"
)

type Blockchain struct {
    Blocks []*Block
}

func (bc *Blockchain) Print() {
    for _, block := range bc.Blocks {
        fmt.Printf("Index:%d\n", block.Index)
        fmt.Printf("Prev.Hash:%s\n", block.PrevBlockHash)
        fmt.Printf("Curr.Hash:%s\n", block.Hash)
        fmt.Printf("Data: %s\n", block.Data)
        fmt.Printf("Data: %d\n\n", block.Timestamp)
    }
}
func NewBlockchain() *Blockchain {
    genesisBlock := GenerateGenesisBlock()
    blockchain := Blockchain{}
    blockchain.AppendBlock(&genesisBlock)
    return &blockchain
}
func (bc *Blockchain) SendData(data string) {
    preBlock := bc.Blocks[len(bc.Blocks)-1]
    newBlock := GenerateNewBlock(*preBlock, data)
    bc.AppendBlock(&newBlock)
}
func (bc *Blockchain) AppendBlock(newBlock *Block) {
    if len(bc.Blocks) == 0 {
        bc.Blocks = append(bc.Blocks, newBlock)
        return
    }
    if isValid(*newBlock, *bc.Blocks[len(bc.Blocks)-1]) {
        bc.Blocks = append(bc.Blocks, newBlock)
    } else {
        log.Fatal("invalid block")
    }
}

func isValid(newBlock, oldBlock Block) bool {
    if newBlock.Index-1 != oldBlock.Index {
        return false
    }
    if newBlock.PrevBlockHash != oldBlock.Hash {
        return false
    }

    if calculateHash(newBlock) != newBlock.Hash {
        return false
    }
    return true
}
package main

import "blockchain.core"

func main() {
    bc := blockchain_core.NewBlockchain()
    bc.SendData("Send 1 BTC to Jacky")
    bc.SendData("Send 1 EOS to Jack")
    bc.Print()
}
上一篇 下一篇

猜你喜欢

热点阅读