⚫ DPoS 即 Delegated Proof of Stake 译为股份授权证明
⚫ 最早于 2013 年由 Bitshares 提出,目的为解决 PoW 和 PoS 机制的不足
⚫DPoS 机制的加密货币,每个节点都可以操作区块,并按照个人的持股比例获得“利 息”
⚫DPoS 是由被社区选举的可信帐户(受托人,得票数排行前 101 位)来创建区块, 为了成为正式受托人,用户要去社区拉票,获得足够多用户的信任,用户根据自己 持有的加密货币数量占总量的百分比来投票
⚫DPoS 机制类似于股份制公司,普通股民进不了董事会,要投票选举代表(受托人) 代他们做决策
⚫这 101 个受托人可以理解为 101 个矿池,而这 101 个矿池彼此的权利是完全相等的
⚫那些握着加密货币的用户可以随时通过投票更换这些代表(矿池),只要他们提供 的算力不稳定,计算机宕机、或者试图利用手中的权力作恶,他们将会立刻被愤怒 的选民门踢出整个系统,而后备代表可以随时顶上去
//实现投票的功能
//定义全节点
type Node struct {
//节点名称
Name string
//被选举的票数
Votes int
}
//区块
type Block struct {
Index int
Timestamp string
Prehash string
Hash string
Data []byte
//代理人
delegate *Node
}
func firstBlock() Block {
gene := Block{0, time.Now().String(),
"", "", []byte("first block"), nil}
gene.Hash = string(blockHash(gene))
return gene
}
//计算哈希
func blockHash(block Block) []byte {
hash := strconv.Itoa(block.Index) + block.Timestamp +
block.Prehash + hex.EncodeToString(block.Data)
h := sha256.New()
h.Write([]byte(hash))
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
return newBlock
}
//创建10个节点
var NodeAddr = make([]Node, 10)
//创建节点
func CreateNode() {
for i := 0; i < 10; i++ {
name := fmt.Sprintf("节点 %d 票数", i)
//初始化时票数为0
NodeAddr[i] = Node{name, 0}
}
}
//简单模拟投票
func Vote() {
for i := 0; i < 10; i++ {
rand.Seed(time.Now().UnixNano())
time.Sleep(100000)
vote := rand.Intn(10000)
//为10个节点投票
//每个节点的票数,就是随机出来的值,0~9999
NodeAddr[i].Votes = vote
fmt.Printf("节点 [%d] 票数 [%d]\n", i, vote)
}
}
//一共10个节点,选出票数最多的前三名
func SortNodes() []Node {
//10个节点
n := NodeAddr
//外层遍历节点个数
for i := 0; i < len(n); i++ {
for j := 0; j < len(n)-1; j++ {
//按票数排序
if n[j].Votes < n[j+1].Votes {
n[j], n[j+1] = n[j+1], n[j]
}
}
}
//返回三个票数多的节点
return n[:3]
}
func main() {
//初始化10个全节点
CreateNode()
fmt.Printf("创建的节点列表: \n")
fmt.Println(NodeAddr)
fmt.Print("节点票数: \n")
//投票
Vote()
//选出前三名
nodes := SortNodes()
fmt.Print("获胜者: \n")
fmt.Println(nodes)
//创世区块
first := firstBlock()
lastBlock := first
fmt.Print("开始生成区块: \n")
for i := 0; i < len(nodes); i++ {
fmt.Printf("[%s %d] 生成新的区块\n", nodes[i].Name, nodes[i].Votes)
lastBlock = nodes[i].GenerateNewBlock(lastBlock, []byte(fmt.Sprintf("new Block %d", i)))
}
}
- DpoS优点
- 能耗低
- 更加去中心化
- 更快的确认速度
- EOS用DpoS
- PBFT(超级账本)
- DpoS缺点
- 投票的积极性不高
- 社区选举有可能存在网络安全问题