作者:林冠宏 / 指尖下的幽灵

掘金:https://juejin.im/user/587f0dfe128fe100570ce2d8

博客:http://www.cnblogs.com/linguanh/

GitHub : https://github.com/af913337456/

腾讯云专栏: https://cloud.tencent.com/developer/user/1148436/activities


目录

  • 前序
  • PoS 共识算法
  • PoS 的特点
  • 编写 PoS 代码
    • 候选块数组
    • 块中的节点地址
    • 进行股权分配
    • 根据股权选出赢家
    • 结束

前序

这篇文章是上一篇的序章,上一篇的链接地址是:

https://juejin.im/post/5b78f6e46fb9a019e8227162,(一)区块链的共识算法:整体介绍 及 分叉 的通俗讲解

本篇文章将会着重介绍 PoS 共识算法和采用代码例子来实在地阐述它

关于什么是共识算法这个问题,请查看(一)区块链的共识算法:整体介绍 及 分叉 的通俗讲解,里面已经给出了答案。

PoS 共识算法

PoS 全称为 Proof of Stake 股权证明。字面意思就是,股份制。就是说,谁的股份越多,谁的话事权越大,这和我们生活中的股份制公司中的股东的意思的差不多的。

但是,在区块链的应用中,我们并不可能真实地分配给链中的节点股份,取而代之的是另外一些东西,这些东西充当股份,我们将这些东西分配给链中节点。下面将举一些例子来加以阐述这个概念。

例如 PoS虚拟货币的应用中,我们可以把持币量的多少,来看作拥有股权、股份的多少,现在 以太坊 ETH 中是拥有 PoS 共识机制的,所以在以太坊中,就是把各个以太坊节点 所拥有的 ETH 代币的数量来衡量,这个节点的股份有多少,它的话事权有多少。假设一个以太坊网络,共有3个节点,A 和 B 和 C,其中 A 节点拥有10000 个 ETH 代币,而 B 和 C 分别有 1000 和 2000 个,那么在这个以太坊网络中,A 的区块是最有可能被选中的,话事权是比较大的。

再例如,假设日后的某个非虚拟货币的区块链、公有链,一条实体业结合的链,例如 汽车链,我们就可以把每一位车主所拥有的车辆数目他的车价值多少钱来分配股份,例如规定一条公式:车数*车价值 = 股份的多少,在 PoS 中股份是一个概念,一个衡量话事权的概念。

PoS 的特点

上面的描述已经说明了 PoS 共识算法的概念。因为它是以拥有某样东西的数量衡量话事权的,这就意味着,只要我们的节点,拥有这类东西,例如 ETH 代币,哪怕拥有的只有 一个,都是有话事权的,即使很小,甚至都没机会露面,但它还是有机会。

PoS 中,块是已经铸造好的(这里没有“挖矿”的概念,所以我们不用这个词来证明股份),PoW 是有挖矿概念的。

这也就造成了它有下面的特点:

  • 优点:

    • 缩短了共识达成的时间,链中共识块的速度更快
    • 不再需要大量消耗能源挖矿
    • 作弊得不尝失,因为如果一名持有 51% 以上股权的人作弊,相当于他坑了自己,因为他是拥有股权最多的人,作弊导致的结果往往是拥有着越多的损失越多
  • 缺点:

    • 攻击成本低,只有节点有物品数量,例如代币数量,就能发起脏数据的区块攻击
    • 另外拥有代币数量大的节点获得记账权的概率会更大,会使得网络共识受少数富裕账户支配,从而失去公正性

编写 PoS 代码

为了能让更多人,以及非 go 开发者能看懂,下面将通过 伪代码 来实现,完整的 go 代码请留邮箱。

首先我们使用一个候选区块数组来保存,每一个 节点 广播过来的和自己当前节点生成的区块对象:


candidateBlocks [ ]Blocks 候选区块数组

每个区块结构体里面有一个变量 是用来记录生成这个区块的节点地址

type Block struct {
Timestamp string // 时间戳,代表该区块的生成时间
Hash string // 这个区块的 hash 值
PrevHash string // 这个区块的 上一个 区块的 hash 值
NodeAddress string // 生成这个区块的 节点地址
Data string // 区块携带的数据
}

然后有一个 子线程,专门负责遍历 候选区块数组,来根据区块里面的节点地址 获取 它的代币数量,然后分配股权


stakeRecord []string // 数组 for block ~ candidateBlocks {
coinNum = getCoinBalance(block.NodeAddress) // 获取代币数量
for i ~ coinNum { // 币有多少,就循环添加多少次
if stakeRecord.contains(block.NodeAddress) { // 是否以及包含了
break // 包含的就不再重复添加
}
stakeRecord = append(block.NodeAddress) // 添加
}
}

然后从 stakeRecord选出一个竞选胜利者。这个概率就和上面的 coinNum 有关,越大就越有机会。


index = randInt() // 得出一个整形随机数 winner = stakeRecord[index] // 取出胜利者节点的地址

最后,我们就能取出这个 winner 所生成的区块来进行公链的接入,然后广播出去


for block ~ candidateBlocks {
if block.NodeAddress == winner {
// 添加
}
} // 广播出去 ...

以上,就是一个很简单的, PoS 算法机制的代码实现,单纯地根据持币数量来做股权分配。而事实上,事情往往是比较复杂的,想想一下,如果我的股权的分配,不仅仅和代币的数量有关系呢,对吧,这样的话,就能衍生各种各样的想法变种方式

例如以太坊加入了币龄,在候选成功后,以太坊在这个步骤还会扣除币龄。种种的这些,都是可以变的,我们要理解 PoS 的精髓,才能在开发自己的公有链的时候,随心而行

(二)区块链的共识算法:PoS 及其 例子 代码 实现的更多相关文章

  1. 老K漫谈区块链的共识(3)——分布式系统和区块链共识

    1. 啥是分布式系统 当我们评价一个新的事物或者介绍一个新的技术的时候,我们不能架空历史和环境,新的事物不可能脱离历史和环境凭空诞生.任何新的事物和新的技术总是或多或少的,与旧的事件以及过去的技术有所 ...

  2. 老K漫谈区块链的共识(1)——免信任的共识机制

    老k,柏链道捷CTO.清华阿尔山区块链研究中心高级工程师,超过17年的系统软件开发经验,在操作系统.编译器.虚拟机和符号执行方面都有实战经验.主持开发多个开眼项目,目前主要从事区块链底层系统开发工作. ...

  3. [区块链] 加密算法——Hash算法(进阶)

    为了为保证存储于区块链中的信息的安全与完整,区块链中使用了包含密码哈希函数和椭圆曲线公钥密码技术在内的大量的现代密码学技术,同时,这些密码学技术也被用于设计基于工作量证明的共识算法并识别用户. 在前边 ...

  4. 共识算法 pos,Dpos

    在之前讲解了比特币中的共识算法pow(proot of work),我们先来简单的回顾一下. 新的交易将会广播给所有节点. 每个节点将都会讲新的交易收集到一个区块中. 每个节点都在为其区块收集困难的工 ...

  5. 区块链--Bitcoin共识机制

    目录 中心化和去中心化 比特币共识机制 拜占庭将军共识机制 比特币成功解决了拜占庭问题 中心化和去中心化 中心化模式: 优点:效率高 缺点:中间层次太多(组织层次连接) 去中心化模式: 缺点:效率低 ...

  6. 只用120行Java代码写一个自己的区块链-3挖矿算法

    在本系列前两篇文章中,我们向大家展示了如何通过精炼的Java代码实现一个简单的区块链.包括生成块,验证块数据,广播通信等等,这一篇让我们聚焦在如何实现 PoW算法. 大家都无不惊呼比特币.以太坊及其他 ...

  7. 区块链共识算法 PBFT(拜占庭容错)、PAXOS、RAFT简述

    共识算法 区块链中最重要的便是共识算法,比特币使用的是POS(Proof of Work,工作量证明),以太币使用的是POS(Proof of Stake,股权证明)使得算理便的不怎么重要了,而今PO ...

  8. Bystack的高TPS共识算法

    共识算法是分布式系统保证节点数据状态一致性的方法,在区块链的共识算法分POW(工作量证明)和POS(权益证明)两大类.第一类POW模式是在公链项目中运用的最广泛应用的共识算法,比特币长达10年的运行已 ...

  9. 分布式共识算法 (四) BTF算法(区块链使用)

    系列目录 分布式共识算法 (一) 背景 分布式共识算法 (二) Paxos算法 分布式共识算法 (三) Raft算法 分布式共识算法 (四) BTF算法 一.引子 前面介绍的算法,无论是 Paxos ...

随机推荐

  1. Django REST framework API开发

    RESTful设计方法 1. 域名 应该尽量将API部署在专用域名之下. https://api.example.com 如果确定API很简单,不会有进一步扩展,可以考虑放在主域名下. https:/ ...

  2. SDWebImage 加载一些大的图片的时候导致程序崩溃

    在  UIImage+MultiFormat这个类里面添加如下压缩方法, +(UIImage *)compressImageWith:(UIImage *)image { float imageWid ...

  3. 小甲鱼Python第十讲课后题---

    0. 下边的列表分片操作会打印什么内容? >>> list1 = [1, 3, 2, 9, 7, 8]>>> list1[2:5] [2,9,7] 1.请问 lis ...

  4. PLC300寻址指令

    1.寻址图解 2.直接寻址 直接寻址包括两大类,绝对地址寻址和符号地址寻址 绝对地址:由一个标识符和存储器位置组成. 例如:I 0.0 Q 1.7 PIW 256 PQW 512 MD 20 T 15 ...

  5. 提升SQLite数据插入效率低、速度慢的方法(转)

    前言 SQLite数据库由于其简单.灵活.轻量.开源,已经被越来越多的被应用到中小型应用中.甚至有人说,SQLite完全可以用来取代C语言中的文件读写操作.因此我最近编写有关遥感数据处理的程序的时候, ...

  6. Mysql查询特定值是哪些表哪些字段

    摘自网上 -- 查询整个数据库中某个特定值所在的表和字段的方法 # flush tables; -- 创建表来存储查询结果 drop table if exists tmp_table; CREATE ...

  7. shell编程学习笔记(十):Shell中的for循环

    shell编程中可以实现for循环遍历 先来写一个最简单的吧,循环输出从1到10,脚本内容为: #! /bin/sh for i in {1..10} do echo $i done 上面的代码从1到 ...

  8. iframe相关小结

    父页面调用子页面方法, 子页面加载父页面传送的数据记录了父子间的调用和数据加载. 以下是另一些关于iframe的小结: 1:document.getElementById("ii" ...

  9. VNC Viewer 设置屏幕分辨率

    1.第一种方法:使用geometry参数进行调整 vncserver -geometry 1280x1024即可,之后通过window下vnc连接后的ubuntu分辨率即为1280x1024了,注意这 ...

  10. OpenCV自带dnn的Example研究(3)— object_detection

    这个博客系列,简单来说,今天我们就是要研究 https://docs.opencv.org/master/examples.html下的 6个文件,看看在最新的OpenCV中,它们是如何发挥作用的. ...