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