文章目录
前言
提示:以下是本篇文章正文内容,下面案例可供参考
一、DPoS——股份授权证明
DPoS 基本原理
⚫ PoS 机制的加密货币,每个节点都可以操作区块,并按照个人的持股比例获得“利
息”
⚫ DPoS 是由被社区选举的可信帐户(受托人,得票数排行前 101 位)来创建区块,
为了成为正式受托人,用户要去社区拉票,获得足够多用户的信任,用户根据自己
持有的加密货币数量占总量的百分比来投票
⚫ DPoS 机制类似于股份制公司,普通股民进不了董事会,要投票选举代表(受托人)
代他们做决策
⚫ 这 101 个受托人可以理解为 101 个矿池,而这 101 个矿池彼此的权利是完全相等的
⚫ 那些握着加密货币的用户可以随时通过投票更换这些代表(矿池),只要他们提供
的算力不稳定,计算机宕机、或者试图利用手中的权力作恶,他们将会立刻被愤怒
的选民门踢出整个系统,而后备代表可以随时顶上去
二、go语言简单实现
package main
import (
"time"
"strconv"
"encoding/hex"
"crypto/sha256"
"fmt"
"math/rand"
)
//实现投票的功能
//定义全节点
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)))
}
}