45fan.com - 路饭网

搜索: 您的位置主页 > 网络频道 > 阅读资讯:区块链共识算法之DPOS(上)

区块链共识算法之DPOS(上)

2019-03-30 18:07:25 来源:www.45fan.com 【

简介

DPOS:Delegated Proof of Stake,委任权益证明。简而言之就是一群“有资格的群众”通过投票选举出少许“更有资格的大佬”来替群众“做事”。如果“更有资格的大佬”做的不好,一群“有资格的群众”通过投票也可以将这些大佬踢出“权力圈子”。一群“有资格的群众”怎么理解呢?就是你持有“某些东西”,通常又是“代币”。持有的越多,通常你的话语权就越大,也就意味着你的票“越牛批”

通常的实现一般分为2部分:

1、通过投票选举出少许“更有资格的大佬”

2、替群众“做事”

简单的代码模拟

下面用简单的代码来模拟上面所说的2部分, 代码实际比较简单,仅仅用来理解dpos的核心思想----选举+做事。另外代码是可以直接运行的,因为不熟悉go所以写的一般化。。。。

package main

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

const (
runForNodeNum  = 10
superNodeMaxNum = 3
)

//节点类型
type Node struct {
Name string //参选节点名称
Votes int  //获得的票数
}

type Block struct {
Index   int
Timestamp string
Prehash  string
Hash   string
Data   []byte
delegate *Node //哪个节点再出块
}

func GenerateGenesisBlock() *Block {
gene := Block{0, time.Now().String(), "0000000000000000000000000000000000000000000000000000000000000000", "", []byte("genesis block"), nil}
gene.Hash = hex.EncodeToString(blockHash(&gene))
return &gene
}

func blockHash(block *Block) []byte {
record := strconv.Itoa(block.Index) + block.Timestamp + block.Prehash + hex.EncodeToString(block.Data)
h := sha256.New()
h.Write([]byte(record))
hashed := h.Sum(nil)
return hashed
}

func (node *Node) GenerateNewBlock(lastBlock *Block, data []byte) *Block {
var newBlock = Block{lastBlock.Index + 1, time.Now().String(), lastBlock.Hash, "", data, nil}
newBlock.Hash = hex.EncodeToString(blockHash(&newBlock))
newBlock.delegate = node
fmt.Printf("%s(%d) produce ", node.Name, node.Votes)
fmt.Println(newBlock)
return &newBlock
}

var nodeArr = make([]Node, runForNodeNum)

func CreateNode() {
for i := 0; i < runForNodeNum; i++ {
name := fmt.Sprintf("runForNode%d", i+1)
nodeArr[i] = Node{name, 0}
}
}

func Vote(nodeChan chan<- []Node) {
for {
for i := 0; i < runForNodeNum; i++ {
rand.Seed(time.Now().UnixNano())
vote := rand.Intn(100) + 1
nodeArr[i].Votes = vote
time.Sleep(297005 * time.Nanosecond)
}
nodeChan <- nodeArr
}

}

func SortNodes(nodeArrAfterVote []Node) {
sort.Slice(nodeArrAfterVote, func(i int, j int) bool {
return nodeArrAfterVote[i].Votes > nodeArrAfterVote[j].Votes
})
}

func main() {

CreateNode()
nodeChan := make(chan []Node)
go Vote(nodeChan)

gene := GenerateGenesisBlock()
lastBlock := gene
nodeArrAfterVote := make([]Node, runForNodeNum)
for {
nodeArrAfterVoteTemp := <-nodeChan
//fmt.Println(nodeArrAfterVoteTemp)
copy(nodeArrAfterVote, nodeArrAfterVoteTemp)
SortNodes(nodeArrAfterVote)
fmt.Printf("\n")
fmt.Println(nodeArrAfterVote)
//fmt.Printf("%p\n", &nodeArrAfterVote[0]);
//fmt.Printf("%p\n", &nodeArr[0]);
//fmt.Printf("%p\n", &nodeArrAfterVoteTemp[0]);

for i := 0; i < superNodeMaxNum; i++ {
lastBlock = nodeArrAfterVote[i].GenerateNewBlock(lastBlock, []byte(fmt.Sprintf("new block id %d", lastBlock.Index)))
time.Sleep(1 * time.Second)
}
}
}

上面的代码简单的模拟了下 每轮出块完成后(3个节点轮流生产一个block/每轮),就去获取最新的投票结果(“有资格的群众”一直处于投票状态中,大佬也是要每轮竞选的,大佬压力也大啊),然后整个处于 出块->竞选->出块。。。。

最后

后面2节将详细分析著名公链EOS的源码-----dpos算法,一起探讨dpos算法不为人知的实现细节。

 
 

本文地址:http://www.45fan.com/a/question/100057.html
Tags: 算法 区块 DPOS
编辑:路饭网
关于我们 | 联系我们 | 友情链接 | 网站地图 | Sitemap | App | 返回顶部