内容简介:Delegated Proof of Stake,委任权益证明。中文名叫做股份授权证明机制(又称受托人机制),它的原理是让每一个持有比特股的人进行投票,由此产生101位代表 , 我们可以将其理解为101个超级节点或者矿池,而这101个超级节点彼此的权利是完全相等的。从某种角度来看,DPOS有点像是议会制度或人民代表大会制度。如果代表不能履行他们的职责(当轮到他们时,没能生成区块),他们会被除名,网络会选出新的超级节点来取代他们。DPOS的出现最主要还是因为矿机的产生,大量的算力在不了解也不关心比特币的人身
DPOS介绍
概念
Delegated Proof of Stake,委任权益证明。
中文名叫做股份授权证明机制(又称受托人机制),它的原理是让每一个持有比特股的人进行投票,由此产生101位代表 , 我们可以将其理解为101个超级节点或者矿池,而这101个超级节点彼此的权利是完全相等的。从某种角度来看,DPOS有点像是议会制度或人民代表大会制度。如果代表不能履行他们的职责(当轮到他们时,没能生成区块),他们会被除名,网络会选出新的超级节点来取代他们。DPOS的出现最主要还是因为矿机的产生,大量的算力在不了解也不关心比特币的人身上,类似演唱会的黄牛,大量囤票而丝毫不关心演唱会的内容。
比特股引入了见证人这个概念,见证人可以生成区块,每一个持有比特股的人都可以投票选举见证人。得到总同意票数中的前N个(N通常定义为101)候选者可以当选为见证人,当选见证人的个数(N)需满足:至少一半的参与投票者相信N已经充分地去中心化。
见证人的候选名单每个维护周期(1天)更新一次。见证人然后随机排列,每个见证人按序有2秒的权限时间生成区块,若见证人在给定的时间片不能生成区块,区块生成权限交给下一个时间片对应的见证人。DPoS的这种设计使得区块的生成更为快速,也更加节能。
DPoS充分利用了持股人的投票,以公平民主的方式达成共识,他们投票选出的N个见证人,可以视为N个矿池,而这N个矿池彼此的权利是完全相等的。持股人可以随时通过投票更换这些见证人(矿池),只要他们提供的算力不稳定,计算机宕机,或者试图利用手中的权力作恶。
应用
- 比特股 Bitshares(提出这个概念)
- EOS
共识算法我DPoS + BFT
- Asch
共识算法为DPoS + PBFT, 有101个受托人, 目前正在开放竞选
go实现DPOS
package main import ( "time" "encoding/hex" "math/rand" "log" "sort" "crypto/sha256" ) //定义区块结构体 type Block struct { Index int Timestamp string BPM int Hash string PrevHash string Delegate string } // 创建区块函数 func generateBlock(oldBlock Block, _BMP int, address string) (Block, error) { var newBlock Block t := time.Now() newBlock.Index = oldBlock.Index + 1 newBlock.Timestamp = t.String() newBlock.BPM = _BMP newBlock.PrevHash = oldBlock.Hash newBlock.Hash = createBlockHash(newBlock) newBlock.Delegate = address return newBlock, nil } //生成区块hash func createBlockHash(block Block) string { record := string(block.Index) + block.Timestamp + string(block.BPM) + block.PrevHash sha3 := sha256.New() sha3.Write([] byte(record)) hash := sha3.Sum(nil) return hex.EncodeToString(hash) } // 简单的检验区块函数 func isBlockValid(newBlock, oldBlock Block) bool{ if oldBlock.Index + 1 != newBlock.Index { return false } if newBlock.PrevHash != oldBlock.Hash { return false } return true } // 区块集合 var blockChain []Block // dpos里的超级节点结构体(受托人) type Trustee struct { name string votes int } type trusteeList [] Trustee // 下面的三个函数是为了 排序 使用,大家可以查下 go 的排序还是很强大的 func (_trusteeList trusteeList) Len() int { return len(_trusteeList) } func (_trusteeList trusteeList) Swap(i, j int){ _trusteeList[i], _trusteeList[j] = _trusteeList[j], _trusteeList[i] } func (_trusteeList trusteeList) Less(i, j int) bool { return _trusteeList[j].votes < _trusteeList[i].votes } // 选举获得投票数最高的前5节点作为超级节点,并打乱其顺序 func selectTrustee() ([]Trustee){ _trusteeList := [] Trustee { {"node1", rand.Intn(100)}, {"node2", rand.Intn(100)}, {"node3", rand.Intn(100)}, {"node4", rand.Intn(100)}, {"node5", rand.Intn(100)}, {"node6", rand.Intn(100)}, {"node7", rand.Intn(100)}, {"node8", rand.Intn(100)}, {"node9", rand.Intn(100)}, {"node10", rand.Intn(100)}, {"node11", rand.Intn(100)}, {"node12", rand.Intn(100)}, } sort.Sort(trusteeList(_trusteeList)) result := _trusteeList[:5] _trusteeList = result[1:] _trusteeList = append(_trusteeList, result[0]) log.Println("当前超级节点列表是", _trusteeList) return _trusteeList } func main() { t := time.Now() // init gensis block(创建创世块,真正的可不是这么简单的,这里只做流程实现) genesisBlock := Block{0, t.String(), 0, createBlockHash(Block{}), "", ""} blockChain = append(blockChain, genesisBlock) // 这里只是完成了一次dpos的写区块操作,eos真正的是每个节点实现6个区块,并且所有超级节点(21个)轮完,之后再做选举 var trustee Trustee for _, trustee = range selectTrustee() { _BPM := rand.Intn(100) blockHeight := len(blockChain) oldBlock := blockChain[blockHeight - 1] newBlock, err := generateBlock(oldBlock, _BPM, trustee.name) if err != nil { log.Println(err) continue } if isBlockValid(newBlock, oldBlock) { blockChain = append(blockChain, newBlock) log.Println("当前操作区块的节点是: ", trustee.name) log.Println("当前区块数量是: ", len(blockChain) - 1) log.Println("当前区块信息: ", blockChain[len(blockChain) - 1]) } } }
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
HTML 压缩/解压工具
在线压缩/解压 HTML 代码
随机密码生成器
多种字符组合密码