使用 go 实现 Delegated Proof of Stake 机制
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 (
"time"
"crypto/sha256"
"encoding/hex"
"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 main() {
lenc:=len(delegates)
var firstBlock Block
firstBlock.Hash = ""
firstBlock.PrevHash=""
firstBlock.Index=1
var i = 0
for {
time.Sleep(time.Second)
var newblock,_ = generateBlock(firstBlock,1,delegates[i])
fmt.Println(newblock,delegates[i])
i++
i= i%lenc
}
}
// 创建初始区块
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)
}
}
}
“`