预定公链开发视频课

黎跃春区块链博客


黎跃春,江湖人称春哥,孔壹学院、 链乎创始人,区块链职业教育布道师,通信和信息技术培养工程区块链高级授课专家。


链乎问答社区
链乎公众号

011 - 使用 go 实现 Delegated Proof of Stake 机制

作者:黎跃春

博客:http://liyuechun.org

官网:http://kongyixueyuan.com

DPoS的伪代码实现

for round i //分成很多个round,round无限持续
   dlist_i = get N delegates sort by votes //根据投票结果选出得票率最高的N个受托人
   dlist_i = shuffle(dlist_i) //随机改变顺序
   loop //round完了,退出循环
       slot = global_time_offset / block_interval
       pos = slot % N
       if dlist_i[pos] exists in this node //delegate在这个节点
           generateBlock(keypair of dlist_i[pos]) //产生block
       else
           skip

DPoS 使用 go 语言实现

package main

import (
	"log"
	"math/rand"
	"encoding/hex"
	"crypto/sha256"
	"time"
	"fmt"
)

//区块

type Block struct {
	Index     int
	Timestamp string
	BPM       int
	Hash      string
	PrevHash  string
	Delegate string
}

// 生成区块
func generateBlock(oldBlock Block, BPM int, address string) (Block, error) {

	var newBlock Block

	t := time.Now()

	newBlock.Index = oldBlock.Index + 1
	newBlock.Timestamp = t.String()
	newBlock.BPM = BPM
	newBlock.PrevHash = oldBlock.Hash
	newBlock.Hash = calculateBlockHash(newBlock)
	newBlock.Delegate = address

	return newBlock, nil
}

//区块链

var Blockchain []Block

// 受托人
var delegates = []string{"001","002","003","004","005"}

// 当前的 delegates 的索引
var indexDelegate int

// 生成Hash字符串
func calculateHash(s string) string {
	h := sha256.New()
	h.Write([]byte(s))
	hashed := h.Sum(nil)
	return hex.EncodeToString(hashed)
}

//生成区块的 Hash 值
func calculateBlockHash(block Block) string {
	record := string(block.Index) + block.Timestamp + string(block.BPM) + block.PrevHash
	return calculateHash(record)
}

func isBlockValid(newBlock, oldBlock Block) bool {
	if oldBlock.Index+1 != newBlock.Index {
		return false
	}

	if oldBlock.Hash != newBlock.PrevHash {
		return false
	}

	if calculateBlockHash(newBlock) != newBlock.Hash {
		return false
	}

	return true
}

// 更换受托人的排列顺序
func randDelegates(delegates []string) []string {

	var randList [] string 
	
	randList = delegates[1:]
	randList = append(randList,delegates[0])

	fmt.Printf("%v\n",randList)
	return randList
}

func main () {

	indexDelegate = 0

	// 创建初始区块
	t := time.Now()
	genesisBlock := Block{}
	genesisBlock = Block{0, t.String(), 0, calculateBlockHash(genesisBlock), "", ""}
	Blockchain = append(Blockchain, genesisBlock)

	indexDelegate++

	countDlegate := len(delegates)

	for indexDelegate < countDlegate {
		
		// 3秒生成区块
		time.Sleep(time.Second * 3)

		fmt.Println(indexDelegate)

		// 创建新的区块
		rand.Seed(int64(time.Now().Unix()))
		bpm := rand.Intn(100)
		oldLastIndex := Blockchain[len(Blockchain)-1]
		newBlock, err := generateBlock(oldLastIndex, bpm, delegates[indexDelegate])
		if err != nil {
			log.Println(err)
			continue
		}

		fmt.Printf("Blockchain....%v\n",newBlock)

		if isBlockValid(newBlock, oldLastIndex) {
			Blockchain = append(Blockchain,newBlock)
		}

		indexDelegate = (indexDelegate + 1)% countDlegate

		if indexDelegate == 0 {
			// 更换受托人的排列顺序
			delegates = randDelegates(delegates)
		}
	}
}

版权声明:博客中的文章版权归博主所有,未经授权,禁止转载,转载请注明出处,合作请联系:liyc1215(微信)

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦