DPoS——股份授权证明 go简单实现

⚫ 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)))
	}
}
  1. DpoS优点
  1. 能耗低
  2. 更加去中心化
  3. 更快的确认速度
  4. EOS用DpoS
  5. PBFT(超级账本)
  1. DpoS缺点
  1. 投票的积极性不高
  2. 社区选举有可能存在网络安全问题

猜你喜欢

转载自blog.csdn.net/s15738841819/article/details/84284830