区块链中的共识算法
在比特币公链架构解析中,就曾提到过为了实现去中介化的设计,比特币设计了一套共识协议,并通过此协议来保证系统的稳定性和防攻击性。 并且我们知道,截止目前使用最广泛,也是最被大家接受的共识算法,是我们先前介绍过的POW(proof of work)工作量证明算法。目前市值排名前二的比特币和以太坊也是采用的此算法。
虽然POW共识算法取得了巨大的成功,但对它的质疑也从来未曾停止过。 其中最主要的一个原因就是电力消耗。据不完全统计,基于POW的挖矿机制所消耗的电量是非常巨大的,甚至比绝大多数国家耗电量还要多。这对我们的资源造成了极大的浪费,此外随着比特大陆等公司的强势崛起,造成了算力的高度集中。
基于以上种种原因,更多的共识算法被提出来 POS、DPOS、BPFT等等。 今天我们就来认识POS(proof of stake)算法。
Proof of stake,译为权益证明。你可以已经猜到了,权益证明简单理解就是拥有更多token的人,有更大的概率获得记账权利,然后获得奖励。 这个概率具体有多大呢? 下面我们在代码实现中会展示,分析也放在后面。 当然,POS是会比POW更好吗? 会更去中心化吗? 现在看来未必,所以我们这里也不去对比谁优谁劣。 我们站在中立的角度,单纯的来讨论讨论POS这种算法。
代码实战
生成一个Block
既然要实现POS算法,那么就难免要生成一条链,链又是由一个个Block生成的,所以下面我们首先来看看如何生成Block,当然在前面的内容里面,关于如何生成Block,以及交易、UTXO等等都已经介绍过了。由于今天我们的核心是实现POS,所以关于Block的生成,我们就用最简单的实现方式,好让大家把目光聚焦在核心的内容上面。
我们用三个方法来实现生成一个合法的区块
- calculate_hash 计算区块的hash值
- is_block_valid 校验区块是否合法
- generate_block 生成一个区块
from hashlib import sha256
from datetime import datetime
def generate_block(oldblock, bpm, address):
"""
:param oldblock:
:param bpm:
:param address:
:return:
"""
newblock = {
"Index": oldblock["Index"] + 1,
"BPM": bpm,
"Timestamp": str(datetime.now()),
"PrevHash": oldblock["Hash"],
"Validator": address
}
newblock["Hash"] = calculate_hash(newblock)
return newblock
def calculate_hash(block):
record = "".join([
str(block["Index"]),
str(block["BPM"]),
block["Timestamp"],
block["PrevHash"]
])
return sha256(record.encode()).hexdigest()
def is_block_valid(newblock, oldblock):
"""
:param newblock:
:param oldblock:
:return:
"""
if oldblock["Index"] + 1 != newblock["Index"]:
return False
if oldblock["Hash"] != newblock["PrevHash"]:
return False
if calculate_hash(newblock) != newblock["Hash"]:
return False
return True
这里为了更灵活,我们没有用类的实现方式,直接采用函数来实现了Block生成,相信很容易看懂。