源碼地址:https://github.com/corgi-kx/blockchain_consensus_algorithm/tree/master/dpos
股份授權(quán)證明機(jī)制是POS的一個(gè)變種,簡(jiǎn)單來(lái)說(shuō)就是你手里有選票(幣就相當(dāng)于選票)浦马。這時(shí)一些正在競(jìng)選超級(jí)節(jié)點(diǎn)的大節(jié)點(diǎn)們說(shuō)把票都投給我把朴上,等我當(dāng)選了超級(jí)節(jié)點(diǎn)茎匠,我吃肉你喝湯,豈不美哉?然后你就信了,把票投給了競(jìng)選節(jié)點(diǎn),這些節(jié)點(diǎn)競(jìng)選成功成為超級(jí)節(jié)點(diǎn)后會(huì)輪循的獲得出塊權(quán)愧捕。曠工費(fèi)、通脹放出的代幣也就都到了他們手里了碟摆。比較中心化的一種共識(shí)機(jī)制晃财,但是TPS很高。
區(qū)塊結(jié)構(gòu):
type block struct {
//上一個(gè)塊的hash
prehash string
//本塊hash
hash string
//時(shí)間戳
timestamp string
//區(qū)塊內(nèi)容
data string
//區(qū)塊高度
height int
//挖出本塊的節(jié)點(diǎn)地址
address string
}
//用于存儲(chǔ)區(qū)塊鏈
var blockchain []block
//普通節(jié)點(diǎn)
type node struct{
//代幣數(shù)量
votes int
//節(jié)點(diǎn)地址
address string
}
//競(jìng)選節(jié)點(diǎn)
type superNode struct {
node
}
//投票節(jié)點(diǎn)池
var voteNodesPool []node
//競(jìng)選節(jié)點(diǎn)池
var starNodesPool []superNode
//存放可以挖礦的超級(jí)節(jié)點(diǎn)池
var superStarNodesPool []superNode
初始化:
生成投票節(jié)點(diǎn)池并隨機(jī)賦予代幣數(shù)量典蜕,同時(shí)為競(jìng)選節(jié)點(diǎn)池生成競(jìng)選節(jié)點(diǎn)
//初始化
func init() {
//初始化投票節(jié)點(diǎn)
for i:=0;i<=voteNodeNum;i++ {
rInt,err:=rand.Int(rand.Reader,big.NewInt(10000))
if err != nil {
log.Panic(err)
}
voteNodesPool = append(voteNodesPool,node{int(rInt.Int64()),"投票節(jié)點(diǎn)"+strconv.Itoa(i)})
}
//初始化超級(jí)節(jié)點(diǎn)
for i:=0;i<=superNodeNum;i++ {
starNodesPool = append(starNodesPool,superNode{node{0,"超級(jí)節(jié)點(diǎn)"+strconv.Itoa(i)}})
}
}
模擬普通節(jié)點(diǎn)投票(隨機(jī)的對(duì)競(jìng)選節(jié)點(diǎn)投票)
//投票
func voting() {
for _, v := range voteNodesPool {
rInt, err := rand.Int(rand.Reader, big.NewInt(superNodeNum+1))
if err != nil {
log.Panic(err)
}
starNodesPool[int(rInt.Int64())].votes += v.votes
}
}
對(duì)競(jìng)選節(jié)點(diǎn)根據(jù)得票數(shù)排序断盛,前幾名成為超級(jí)節(jié)點(diǎn)
//對(duì)挖礦節(jié)點(diǎn)進(jìn)行排序
func sortMineNodes() {
sort.Slice(starNodesPool, func(i, j int) bool {
return starNodesPool[i].votes > starNodesPool[j].votes
})
superStarNodesPool = starNodesPool[:mineSuperNodeNum]
}
主函數(shù)
func main() {
fmt.Println("初始化", voteNodeNum, "個(gè)投票節(jié)點(diǎn)...")
fmt.Println(voteNodesPool)
fmt.Println("當(dāng)前存在的", superNodeNum, "個(gè)競(jìng)選節(jié)點(diǎn)")
fmt.Println(starNodesPool)
fmt.Println("投票節(jié)點(diǎn)們開(kāi)始進(jìn)行投票...")
voting()
fmt.Println("結(jié)束投票,查看競(jìng)選節(jié)點(diǎn)們獲得票數(shù)...")
fmt.Println(starNodesPool)
fmt.Println("對(duì)競(jìng)選節(jié)點(diǎn)按獲得票數(shù)排序愉舔,前", mineSuperNodeNum, "名钢猛,當(dāng)選超級(jí)節(jié)點(diǎn)")
sortMineNodes()
fmt.Println(superStarNodesPool)
fmt.Println("開(kāi)始挖礦...")
genesisBlock := block{"0000000000000000000000000000000000000000000000000000000000000000", "", time.Now().Format("2006-01-02 15:04:05"), "我是創(chuàng)世區(qū)塊", 1, "000000000"}
genesisBlock.getHash()
blockchain = append(blockchain, genesisBlock)
fmt.Println(blockchain[0])
i, j := 0, 0
for {
time.Sleep(time.Second)
newBlock := generateNewBlock(blockchain[i], "我是區(qū)塊內(nèi)容", superStarNodesPool[j].address)
blockchain = append(blockchain, newBlock)
fmt.Println(blockchain[i+1])
i++
j++
j = j % len(superStarNodesPool)
}
}
運(yùn)行結(jié)果: