美文网首页大数据区块链研习社区块链大学
区块链开发:共识机制PoS #C07

区块链开发:共识机制PoS #C07

作者: 纳兰少 | 来源:发表于2019-03-18 09:06 被阅读0次

原理介绍

前面提到,PoW最大的缺点之一就是电力消耗严重,所以点点币的创始人Sunny King最早提出了PoS共识来解决这一问题。PoS 全称是 Proof of Stake,也即权益证明。

PoS去掉了穷举nonce的过程,继而采用更快速的算法

hash (hash (PrevBlock), CurBlock, t) ≤ target * CoinAge
  • PrevBlock表示前一个区块
  • CurBlock为当前区块
  • t为当前区块的时间戳
  • target为目标值
  • CoinAge为当前区块的币龄

不等式左边唯一的变量就是时间戳t,也就是这里不再是通过nonce来尝试哈希值,而是通过时间戳。网络中对时间戳的尝试是有限制的,通常为1小时,如果一个节点在7200次尝试中都没有找到合适的t,那么就放弃。

不等式右边的target是每隔一段时间随系统变化的,称为难度(或者难度系数),而CoinAge表示当前区块的币龄。 那么什么是币龄呢?

币龄其实就是币数乘以天数,也就是Coin × Age,Age表示矿工拥有的币在自己账户中锁定的天数。一旦发生转账,即使是转向自己的账户,Age都会被清零,币龄会相应的减少。

共识机制的一个作用就是筛选出记账人,PoW机制通过算力来获得记账权,而PoS则将其转换为财产证明。每个节点的币龄是不同的,币龄越大,找到合适t的概率也越大,获得记账的概率也越大,所以PoS被称为权益证明,类似于公司里的股权制度,大股东拥有更高的说话权。

代码实现

基本结构

相比于比特币采用PoW机制,以太坊采用了PoS机制,但是以太坊的PoS机制称为Casper,目前还没有完全公布出来,所以这里就根据上文的理解实现一个简单版的PoS。

class Pos {
    constructor(blockchain) {
        this.difficulty_ = 4294967295;// ~uint64(0) >> 32
        this.time_stamp_ = (new Date()).getTime();
        this.state_ = "Idle";
        this.block_chain_ = blockchain;
    }
}

Pos中的difficulty_为初始目标难度,会随着区块的增长不断地调整,下文会详细描述。time_stamp_则是当前时间戳,据上文所述,PoS共识算法中,时间戳是唯一的变量。

权益证明

事实上,PoS的发展经历了多个阶段,第一个阶段是以点点币为代表的PoS 1.0版本,在这个版本中使用的是币龄;为了进一步巩固PoS的安全,2014年rat4(Pavel Vasin)提出了PoS 2.0,并发布了黑币。PoS 2.0相比PoS 1.0的一个重要改进就是采用币数来代替币龄,这里为了简化,实现中采用币数而非币龄。

    prepared() {
        return this.state_ == "Idle";
    }
    make_consensus(block_data) {
        this.state_ = "Busy";
        this.calc_difficulty(block_data);

        let self = this;
        setImmediate(function make_proof(block) {
            let time_period = self.time_stamp_ - block_data.get_timestamp();
            if (time_period > 3600 * 1000) {
                self.state_ = "Idle";
                block.emit('consensus failed');
                return;
            }

            let amount = self.block_chain_.get_amount();
            block.set_consensus_data({
                "difficulty": self.difficulty_,
                "timestamp": self.time_stamp_,
                "amount": amount
            });

            var hash = block.calc_block_hash();
            if (parseInt(hash, 16) < self.difficulty_ * amount) {
                self.state_ = "Idle";
                block.emit('consensus completed');
            } else {
                setTimeout(make_proof, 1000, block);
            }
        }, block_data);
    }

难度调整

难度系数的调整这里采用点点币的调整策略,两个区块生成时间间隔目标设定为10分钟,以一周为度量时间,理应产生1008个区块。如果前两个区块的时间间隔大于10分钟,则当前目标值增大,区块生成难度减小;反之当前目标值减小,难度增大。

当前区块目标值 = 前一个区块目标值 x (1007x10x60 + 2x前两个区块时间间隔) / (1009x10x60)
    calc_difficulty(block) {
        let prev = this.block_chain_.get_last_block();
        if (!prev)
            return this.difficulty_;
        let prev_prev = this.block_chain_.get_hash(prev.hash);
        if (!prev_prev)
            return prev.difficulty;

        let TargetSpacing = 10 * 60;
        let TargetTimespan = 7 * 24 * 60 * 60;
        let Interval = TargetTimespan / TargetSpacing;
        let ActualSpacing = prev.timestamp - prev_prev.timestamp;
        this.difficulty_ = prev.difficulty * ((Interval - 1) * TargetSpacing + 2 * ActualSpacing) / ((TargetSpacing + 1) * TargetSpacing);
    }

优缺点

PoS机制相对于PoW机制的优点这里已经归纳的很清楚了。

  • 无需消耗大量电力以确保区块链(例如,估计比特币和以太网每天都会燃烧超过100万美元的电力和硬件成本作为其共识机制的一部分)。
  • 由于缺乏高电力消耗,因此不需要发布尽可能多的新硬币以激励参与者继续参与网络。理论上甚至可能会出现负净发行,其中一部分交易费用被“烧毁”,因此供应随着时间的推移而下降。
  • PoS有助于实现更多采用博弈论机制设计的技术,从而更好地抑制中心化卡特尔式机构的形成,如果这种机构确实形成了的话,也能够阻止它们危害网络(如工作量证明中的自私挖矿)。
  • 降低中心化风险,因此规模经济不会造成太大问题。你不会因为负担得起更好的大批量矿机而获得与投入资金不成比例的收益,在PoS中,1000万美元投资带给你的收益就是100万美元投资的整整十倍。
  • 能够使用经济处罚来使各种形式的51%攻击比PoW中付出的代价更加昂贵 - 用Vlad Zamfir的话来说,“如果你参与了51%的攻击,那就好像你的ASIC农场被烧毁了”。

PoS虽然有诸多PoW没有的优势,但是也有诸多PoW所没有的缺点。比较典型的有冷启动问题、币龄加和攻击、贿赂攻击、女巫攻击、长程攻击以及无成本利益问题。

冷启动问题(Initial Distribution Problem)

当基于PoS机制的系统启动时,只有创世区块上有币,如何让币分散到网络上去就是个问题,所以早期系统都是先采用PoW挖矿,然后再转为PoS挖矿。但随着 ERC20 类型的标准合约代币的出现,这个问题被解决了,不再需要第一阶段改成 PoW,也可以将代币分散出去。

此外,在PoS机制中,持币量会对挖矿难度产生影响,所以矿工更加倾向于囤币而非让代币流通。对于这个问题,瑞迪币引入了币龄按时间衰减的算法,构造了权益速度证明,鼓励用户流动代币,而不是囤积代币。

币龄加和攻击(Coin Age Accumulation Attack)

PoS中币龄与时间挂钩,这样攻击者就可以先囤积一些币,依靠时间来积累股权,然后一次性发动攻击。这个问题的解决办法就是引入一个时间因子上限来控制,比如点点币中就是90天。

贿赂攻击(Bribe Attack)

坏节点可以通过拉选票的方式来让自己成为记账人,从而从而左右区块链的升级与发展过程。这一点在DPoS机制中较为明显,一般通过仲裁机制来解决,但是更重要的是建立良好的社区。

女巫攻击(Sybil Attack)

区块链的一大特性就是匿名性,私钥和真实身份无法建立连接,这样攻击者就可以伪装成多个身份来攻击系统。例如破坏系统的数据冗余机制、或者在联盟链中伪装成多个节点投票等。

通常的解决办法是:

  1. 引入PoW机制,利用PoW来证明你是一个真的节点。
  2. 采用相应的身份认证机制,这一点在联盟链中比较重要。

长程攻击(Long-Range Attack)

由于PoS取消了电力消耗,所以挖矿成本与挖矿时间都大幅度下降,这样坏节点的作恶成本也大大降低,甚至可能篡改账本。但这与PoW中的51%攻击还不一样,这里称之为长程攻击,其过程为如果一些攻击者获得了一些账户的私钥,而这些私钥在历史上某个时刻控制了超过51%的股权,那就可以从该时刻开始进行51%攻击,制造分叉链。而且PoS没有PoW的能源消耗来控制成本与时间,攻击者可以在短时间内让分叉链赶上原来的主链。

如果PoS公链的创始人或者早期投资人将自己的代币转移出售后,再将账户卖给攻击者,那么攻击者就有可能从创世区块开始攻击,制造一条完全不同的分叉链。

许多方法被提出用于应对长程攻击,比如:密钥演化算法迭代更新密钥、在同步时限制最大能接受的分叉节点数量、或者主观依赖受信节点等。但是这些方法也有争议,尤其是当长程攻击配合女巫攻击时,其有效性更是有待商榷。

无成本利益问题(Nothing at Stake)

无成本利益问题其实可以看作是长程攻击的“扩展”版本,长程攻击中,直接攻击者只有一个,而无成本利益问题中却有很多潜在的攻击者。

在PoS中,矿工分叉并不需要什么算力成本,那么每个矿工在产生孤块的时候就可以继续往下挖,分叉链和主链同时挖,反正没什么成本。不管持币多少都可以这样挖,并把分叉链广播出去,而其他矿工收到后,也可能会继续挖下去,说不定什么时候这条链就值钱了。这样子即使没有攻击者,系统会逐渐趋于混乱,而非稳定。

在PoW中,需要将算力分散,这样会得不偿失。

而在Casper协议中,矿工需通过抵押保证金的方法对共识结果进行下注,这就迫使矿工去采取正确的行为。

相关文章

网友评论

    本文标题:区块链开发:共识机制PoS #C07

    本文链接:https://www.haomeiwen.com/subject/vikhmqtx.html