区块链共识算法——(二)PoS共识(Proof of Stake)

背景

2011 年 7 月, 一 位 名 为 Quantum Mechanic 的 数 字 货 币 爱 好 者 在 比 特 币 论 坛 首次提出了权益证明 PoS 共识算法. 随后, Sunny King 在 2012 年 8 月发布的点点币 (Peercoin, PPC) 中首次实现. PoS 由 系统中具有最高权益而非最高算力的节点获得记账 权, 其中权益体现为节点对特定数量货币的所有权, 称为币龄或币天数 (Coin days)

PoS是考虑到PoW的最大缺陷:浪费资源而提出的,简单来说就是谁的权益大,谁说了算

原理

PoS共识机制(Proof of Stake 权益证明)通过权益记账的方式,解决效率低下、资源浪费、节点一致性等问题。

各个节点需要满足一定的条件(如抵押一定的代币)才能成为验证节点(权益提高),系统通过算法在其中选择一部分作为出块节点(矿工),每隔一段时间重新选择,算法会保证完全随机,不可被操控。只有出块节点才能进行数据处理,争夺记账权。

权益主要由权益因子决定,可以是持币数量,也可以是币龄及两者的结合。

优势与缺陷

区块链共识算法——(二)PoS共识(Proof of Stake)_第1张图片
PoW vs PoS

以太坊在之后很有可能会改用PoS进行共识,其更加符合以太坊高效率的特点。

代码实现

from hashlib import sha256
import time
import random


class block:
    def __init__(self, index, data, timestamp, prehash=""):
        self.index = index
        self.data = data
        self.timestamp = timestamp
        self.prehash = prehash
        self.hash = self.caculateHash()

    def caculateHash(self):
        result = str(self.index) + str(self.data) + str(self.timestamp) + str(self.prehash)
        return sha256(result.encode("utf-8")).hexdigest()

    def __str__(self):
        return str(self.__dict__)


class blockchain:
    def __init__(self):
        self.chain = [self.createGenesisBlock()]

    def createGenesisBlock(self):
        return block(0, "创世块数据在此!!!!", time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))

    def getLastBlock(self):
        return self.chain[len(self.chain) - 1]

    # 上链
    def addBlock(self, newBlock):
        newBlock.prehash = self.getLastBlock().hash
        self.chain.append(newBlock)

    def __str__(self):
        return str(self.__dict__)


# 节点类,
# tokens:持币量  days:持币时间  address:节点地址
class Node:
    def __init__(self, tokens=0, days=0, address=""):
        self.tokens = tokens
        self.days = days
        self.address = address

    def __str__(self):
        return str(self.__dict__)


# PoS挖矿策略,返回挖矿节点的位置
def PoSMiner(nodes, cnt):
    rd = random.randint(1, cnt)  # 通过随机数选择,持币越多占额越多
    print("随机数:" + str(rd))
    index = 0
    for i in range(0, 5):
        index += nodes[i].tokens
        if (index >= rd):
            print("挖矿节点为:")
            print(nodes[i])
            nodes[i].tokens += 1 # 模拟奖励
            break


def main():
    myBlockchain = blockchain()

    print("初始区块链:")
    print(myBlockchain.getLastBlock())

    # 构造5个节点,每个节点持币量和地址不同
    node1 = Node(1, 1, "0x0001")
    node2 = Node(2, 1, "0x0002")
    node3 = Node(3, 1, "0x0003")
    node4 = Node(4, 1, "0x0004")
    node5 = Node(5, 1, "0x0005")
    nodes = [node1, node2, node3, node4, node5]

    print("\n5个节点基本信息:\n")
    for i in range(0, 5):
        print(nodes[i])

    # 模拟3次上链
    for round in range(2, 5):
        cnt = 0  # 总币量
        for i in range(0, 5):
            cnt += nodes[i].tokens
        print("\n当前总币量:" + str(cnt))

        PoSMiner(nodes, cnt)
        myBlockchain.addBlock(block(myBlockchain.getLastBlock().index + 1, "第" + str(round) + "个区块的数据在此!!",
                                    time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))

    print("\n5个节点基本信息:\n")
    for i in range(0, 5):
        print(nodes[i])

    print("\n打印区块链上各区块:")
    for aBlock in myBlockchain.chain:
        print(aBlock)

main()

实现结果

区块链共识算法——(二)PoS共识(Proof of Stake)_第2张图片
结果1

区块链共识算法——(二)PoS共识(Proof of Stake)_第3张图片
结果2

参考文献:
《区块链共识算法的发展现状与展望》——自动化学报

你可能感兴趣的:(区块链共识算法——(二)PoS共识(Proof of Stake))