011 - 使用 go 实现 Delegated Proof of Stake 机制

DPoS的伪代码实现

for round i //分成很多个round,round无限持续
   dlist_i = get N delegates sort by votes //根据投票结果选出得票率最高的N个受托人
   dlist_i = shuffle(dlist_i) //随机改变顺序
   loop //round完了,退出循环
       slot = global_time_offset / block_interval
       pos = slot % N
       if dlist_i[pos] exists in this node //delegate在这个节点
           generateBlock(keypair of dlist_i[pos]) //产生block
       else
           skip

DPoS 使用 go 语言实现

package main

import (
    "log"
    "math/rand"
    "encoding/hex"
    "crypto/sha256"
    "time"
    "fmt"
)

//区块

type Block struct {
    Index     int
    Timestamp string
    BPM       int
    Hash      string
    PrevHash  string
    Delegate string
}

// 生成区块
func generateBlock(oldBlock Block, BPM int, address string) (Block, error) {

    var newBlock Block

    t := time.Now()

    newBlock.Index = oldBlock.Index + 1
    newBlock.Timestamp = t.String()
    newBlock.BPM = BPM
    newBlock.PrevHash = oldBlock.Hash
    newBlock.Hash = calculateBlockHash(newBlock)
    newBlock.Delegate = address

    return newBlock, nil
}

//区块链

var Blockchain []Block

// 受托人
var delegates = []string{"001","002","003","004","005"}

// 当前的 delegates 的索引
var indexDelegate int

// 生成Hash字符串
func calculateHash(s string) string {
    h := sha256.New()
    h.Write([]byte(s))
    hashed := h.Sum(nil)
    return hex.EncodeToString(hashed)
}

//生成区块的 Hash 值
func calculateBlockHash(block Block) string {
    record := string(block.Index) + block.Timestamp + string(block.BPM) + block.PrevHash
    return calculateHash(record)
}

func isBlockValid(newBlock, oldBlock Block) bool {
    if oldBlock.Index+1 != newBlock.Index {
        return false
    }

    if oldBlock.Hash != newBlock.PrevHash {
        return false
    }

    if calculateBlockHash(newBlock) != newBlock.Hash {
        return false
    }

    return true
}

// 更换受托人的排列顺序
func randDelegates(delegates []string) []string {

    var randList [] string 

    randList = delegates[1:]
    randList = append(randList,delegates[0])

    fmt.Printf("%v\n",randList)
    return randList
}

func main () {

    indexDelegate = 0

    // 创建初始区块
    t := time.Now()
    genesisBlock := Block{}
    genesisBlock = Block{0, t.String(), 0, calculateBlockHash(genesisBlock), "", ""}
    Blockchain = append(Blockchain, genesisBlock)

    indexDelegate++

    countDlegate := len(delegates)

    for indexDelegate < countDlegate {

        // 3秒生成区块
        time.Sleep(time.Second * 3)

        fmt.Println(indexDelegate)

        // 创建新的区块
        rand.Seed(int64(time.Now().Unix()))
        bpm := rand.Intn(100)
        oldLastIndex := Blockchain[len(Blockchain)-1]
        newBlock, err := generateBlock(oldLastIndex, bpm, delegates[indexDelegate])
        if err != nil {
            log.Println(err)
            continue
        }

        fmt.Printf("Blockchain....%v\n",newBlock)

        if isBlockValid(newBlock, oldLastIndex) {
            Blockchain = append(Blockchain,newBlock)
        }

        indexDelegate = (indexDelegate + 1)% countDlegate

        if indexDelegate == 0 {
            // 更换受托人的排列顺序
            delegates = randDelegates(delegates)
        }
    }
}

你可能感兴趣的:(011 - 使用 go 实现 Delegated Proof of Stake 机制)