type Block struct {
Number int
BPM int
Hash string
PrevHash string
Validator string
Timestamp time.Time
}
其中BPM
用于之后的共识。
var Blockchain []Block
func GenerateBlock(prevBlock Block, BPM int, address string) Block {
return newBlock
}
func (b *Block) CalculateBlockHash() string {
record := string(b.Number) + b.Timestamp.String() + string(b.BPM) + b.PrevHash
return calculateHash(record)
}
在这里使用的是sha256
的Hash
计算方法。
func IsBlockValid(newBlock, prevBlock Block) bool {
if prevBlock.Number+1 != newBlock.Number {
return false
}
if prevBlock.Hash != newBlock.PrevHash {
return false
}
if newBlock.CalculateBlockHash() != newBlock.Hash {
return false
}
return true
}
genesisBlock = Block{0, 0, "", "", "", t}
Blockchain = append(Blockchain, genesisBlock)
执行PoS
需要获取每个节点的Balance
和BPM
信息:
// 获取 Balance 信息
for scanBalance.Scan() {
balance, err := strconv.Atoi(scanBalance.Text())
validators[address] = balance
}
// 获取 BPM 信息
for {
bpm, err := strconv.Atoi(scanBPM.Text())
newBlock := GenerateBlock(prevLastIndex, bpm, address)
if IsBlockValid(newBlock, prevLastIndex) {
candidateBlocks = append(candidateBlocks, newBlock) // 将新生成的区块放入到候选区块中
}
}
将每个用户的Stake
作为权重,并从中随机选择获胜者:
k, ok := setValidators[block.Validator]
if ok {
for i := 0; i < k; i++ {
lotteryPool = append(lotteryPool, block.Validator)
}
}
}
s := rand.NewSource(time.Now().Unix())
r := rand.New(s)
lotteryMiner := lotteryPool[r.Intn(len(lotteryPool))]