【go共识算法】-DPOS

jincheng828 · · 1983 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

DPOS介绍

概念

Delegated Proof of Stake,委任权益证明。
中文名叫做股份授权证明机制(又称受托人机制),它的原理是让每一个持有比特股的人进行投票,由此产生101位代表 , 我们可以将其理解为101个超级节点或者矿池,而这101个超级节点彼此的权利是完全相等的。从某种角度来看,DPOS有点像是议会制度或人民代表大会制度。如果代表不能履行他们的职责(当轮到他们时,没能生成区块),他们会被除名,网络会选出新的超级节点来取代他们。DPOS的出现最主要还是因为矿机的产生,大量的算力在不了解也不关心比特币的人身上,类似演唱会的黄牛,大量囤票而丝毫不关心演唱会的内容。

比特股引入了见证人这个概念,见证人可以生成区块,每一个持有比特股的人都可以投票选举见证人。得到总同意票数中的前N个(N通常定义为101)候选者可以当选为见证人,当选见证人的个数(N)需满足:至少一半的参与投票者相信N已经充分地去中心化。

见证人的候选名单每个维护周期(1天)更新一次。见证人然后随机排列,每个见证人按序有2秒的权限时间生成区块,若见证人在给定的时间片不能生成区块,区块生成权限交给下一个时间片对应的见证人。DPoS的这种设计使得区块的生成更为快速,也更加节能。

DPoS充分利用了持股人的投票,以公平民主的方式达成共识,他们投票选出的N个见证人,可以视为N个矿池,而这N个矿池彼此的权利是完全相等的。持股人可以随时通过投票更换这些见证人(矿池),只要他们提供的算力不稳定,计算机宕机,或者试图利用手中的权力作恶。

应用

  • 比特股 Bitshares(提出这个概念)
  • EOS

共识算法我DPoS + BFT

  • Asch

共识算法为DPoS + PBFT, 有101个受托人, 目前正在开放竞选

go实现DPOS

package main

import (
    "time"
    "encoding/hex"
    "math/rand"
    "log"
    "sort"
    "crypto/sha256"
)
//定义区块结构体
type Block struct {
    Index int
    Timestamp string
    BPM int
    Hash string
    PrevHash string
    Delegate string
}
// 创建区块函数
func generateBlock(oldBlock Block, _BMP int, address string) (Block, error) {
    var newBlock Block
    t := time.Now()

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

    return newBlock, nil
}
//生成区块hash
func createBlockHash(block Block) string {
    record := string(block.Index) + block.Timestamp + string(block.BPM) + block.PrevHash
    sha3 := sha256.New()
    sha3.Write([] byte(record))
    hash := sha3.Sum(nil)
    return hex.EncodeToString(hash)
}
// 简单的检验区块函数
func isBlockValid(newBlock, oldBlock Block) bool{
    if oldBlock.Index + 1 != newBlock.Index {
        return false
    }

    if newBlock.PrevHash != oldBlock.Hash {
        return false
    }
    return true
}
// 区块集合
var blockChain []Block

// dpos里的超级节点结构体(受托人)
type Trustee struct {
    name string
    votes int
}

type trusteeList [] Trustee
// 下面的三个函数是为了排序使用,大家可以查下go的排序还是很强大的
func (_trusteeList trusteeList) Len() int {
    return len(_trusteeList)
}
func (_trusteeList trusteeList) Swap(i, j int){
    _trusteeList[i], _trusteeList[j] = _trusteeList[j], _trusteeList[i]
}
func (_trusteeList trusteeList) Less(i, j int) bool {
    return _trusteeList[j].votes < _trusteeList[i].votes
}

// 选举获得投票数最高的前5节点作为超级节点,并打乱其顺序
func selectTrustee() ([]Trustee){
    _trusteeList := [] Trustee {
        {"node1", rand.Intn(100)},
        {"node2", rand.Intn(100)},
        {"node3", rand.Intn(100)},
        {"node4", rand.Intn(100)},
        {"node5", rand.Intn(100)},
        {"node6", rand.Intn(100)},
        {"node7", rand.Intn(100)},
        {"node8", rand.Intn(100)},
        {"node9", rand.Intn(100)},
        {"node10", rand.Intn(100)},
        {"node11", rand.Intn(100)},
        {"node12", rand.Intn(100)},
    }
    sort.Sort(trusteeList(_trusteeList))
    result := _trusteeList[:5]
    _trusteeList = result[1:]
    _trusteeList = append(_trusteeList, result[0])
    log.Println("当前超级节点列表是", _trusteeList)
    return _trusteeList
}

func main() {
    t := time.Now()

    // init gensis block(创建创世块,真正的可不是这么简单的,这里只做流程实现)
    genesisBlock := Block{0, t.String(), 0, createBlockHash(Block{}), "", ""}
    blockChain = append(blockChain, genesisBlock) // 这里只是完成了一次dpos的写区块操作,eos真正的是每个节点实现6个区块,并且所有超级节点(21个)轮完,之后再做选举
    var trustee Trustee
    for _, trustee = range selectTrustee() {
        _BPM := rand.Intn(100)
        blockHeight := len(blockChain)
        oldBlock := blockChain[blockHeight - 1]
        newBlock, err := generateBlock(oldBlock, _BPM, trustee.name)
        if err != nil {
            log.Println(err)
            continue
        }

        if isBlockValid(newBlock, oldBlock) {
            blockChain = append(blockChain, newBlock)
            log.Println("当前操作区块的节点是: ", trustee.name)
            log.Println("当前区块数量是: ", len(blockChain) - 1)
            log.Println("当前区块信息: ", blockChain[len(blockChain) - 1])

        }

    }
}

有疑问加站长微信联系(非本文作者)

本文来自:Segmentfault

感谢作者:jincheng828

查看原文:【go共识算法】-DPOS

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1983 次点击  ∙  1 赞  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传