DPoS算法


前言


提示:以下是本篇文章正文内容,下面案例可供参考

一、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)))
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_44763160/article/details/120273090
今日推荐