波卡运行原理系列(六)GRANDPA共识简述

定义

GRANDPA = GHOST-based Recursive Ancestor Deriving Prefix Agreement

确定性 = 敲定 = 不可逆:不会出现“冲突”的情况

活性:有效交易最终必定会上链

冲突 = 分叉:非预期的分叉会导致双重支付等各种问题,是不安全的

GRANDPA要解决的问题

保证区块链的确定性。
波卡将GRANDPA与BABE分成两个模块,BABE提供活性和概率的确定性,GRANDPA提供确定性。
GRANDPA共识与BABE或者比特币的POW不同,BABE和比特币的POW是概率确定性,而GRANDPA共识要做到100%不可逆。
之所以需要做到不可逆,因为波卡的跨链特性,需要保证跨链的交易一旦执行,绝不可能在原链上被撤销。

要解决这个问题还需要分别解决下面三个问题:

问题1

不要全部节点确认才成为不可逆的问题

因为我们没办法保证所有节点都会对某个块进行确认,毕竟网络波动的原因会一直存在,否则会极大影响效率。因此我们提出了各种BFT算法,在部分节点确认的情况下,保证网络的安全性。

这里会用到 BFT 2 次 ⅔ 共识,之所有需要2次是因为:

如上图,如果只有 1 次 ⅔ 节点确认,会有 2 个块高度为 101 的区块成为了不可逆,造成“冲突”

不会立马成为 commit, 会先成为 pre-commit, 然后 pre-commit 经过 2/3 共识后才会成为commit,就根本没有任何情况能让 2 个 N 同时成为 commit

问题2

敲定过程中的大量网络传输的消耗问题

因为需要 2 次 ⅔ 共识广播,所以 GRANDPA 的复杂度是 O(n²),随着节点数量的增加,效率也会大幅下降,比如EOS虽然只有21个出块节点,但它敲定的时间大概需要3分钟左右,而波卡的目标是全网1000个节点。

因此 GRANDPA 不是对每个pre-commit块进行逐个投票,而是将过程分为预投票和预执行,对当前最高块进行投票,通过拆解区块结构,可以一次确认若干个块,极大提高敲定效率。

如下图,每个节点选出自己认为最高块,从而确定本轮新敲定的块。

问题3

出现意外或者恶意节点的问题

问题1和2中都只考虑理想的诚实节点的情况,但实际运行时可能会出现其他情况导致“冲突”,比如下图

当网络情况不好,导致两边的蓝色诚实节点无法同步,他们各自提交自己收到的区块,而当中的恶意节点对两边的提交都进行签名(双签),从而导致网络“冲突”

除此之外,大量节点离线也导致问题。

针对这类问题,GRANDPA具有一项称为“安全责任”的功能,即通过扣除节点抵押并将其从节点集中剔除,使验证者对违反安全性的行为负责。

如果你想要重写一个之前的区块,除了需要能够控制超过 ⅓ 的节点外,你还需要承受这 ⅓ 节点的抵押被系统扣除的成本。

GRANDPA 的缺点

GRANDPA最大的缺点是敲定时间的不确定性,Edgeware上线初期就出现过几个小时无法敲定区块的现象。
不过任何设计都有代价,只能说这是 GRANDPA 追求节点数量(去中心化),必须付出的代价。

参考文献

Polkadot Consensus Part 2: GRANDPA

Polkadot 共识第 2 部分 : GRANDPA

GRANDPA Block Finality in Polkadot: An Introduction

Polkadot的区块最终确定性祖父协议GRANDPA:简介

DPOS 3.0 + BFT 为什么需要 2 次 2/3 共识

Substrate 应用链开发教程03 – 如何使用 Substrate 开发 AppChain

本教程内容: 从零开始,15分钟搭建一条基于substrate的存证应用链

Screen Shot 2020-06-01 at 12.07.50

腾讯
https://v.qq.com/x/page/h0975d22ota.html

B站
https://www.bilibili.com/video/BV1F5411W7jL/

YouTube
https://youtu.be/IV_MUYlfLVM

PPT
https://github.com/ericfish/Substrate-Dev-Book/blob/master/ppt/Sub-Video-03.pdf

代码:
https://github.com/ericfish/Substrate-Dev-Book

推荐开发测试钱包 MathWallet 浏览器插件:
http://mathwallet.org

波卡运行原理系列(五)波卡和以太坊的不同之处

波卡什么时候上线?

这个可能是这段时间收到用户提问次数最多的问题。

回答这个问题前,需要先对“上线”有个明确的定义。
如果我们把“上线”定义为 DOT 通证可以转账,那么目前波卡还未上线。

但是波卡的上线其实早就启动了,而且它重新定义了“上线”的过程,这个过程也深刻的反映出波卡网络“渐进安全”的思想。
启动过程开始于2019/8/23,Kusama网络通过POA共识启动,逐步通过链上治理开放抵押、POS、转账等功能,整个过程为期2个月。
不同于测试网,Kusama的定义是实验网,它的链上数据会长期存在,因为波卡跨链的特性,这些数据将来可以“跨”到波卡主网。于是新的项目,就可以先在Kusama上线,如果将来做大了,可以通过跨链轻松的迁移到波卡主网,获得更高的安全性;如果没做大,那么在Kusama上也可以在获得当前规模下足够安全性的同时,享有更低的使用成本。
因其存在长期价值,Kusama的市值目前已经上涨了近7倍。

总结,波卡主网会重走一遍Kusama的启动过程,而经过了Kusama的市场验证,波卡主网正式开启转账时会更加稳定和安全。CC1就是波卡主网的第一个候选版本。

有那么多链需要跨吗?

目前看资产和共识的确基本都在两大公链BTC和ETH上。
那么其它链存在的意义是什么?当然是尝试去解决两大公链目前的问题。
那么为什么两大公链不去解决自己的这些问题呢?在解决,但由于历史包袱,解决得比较慢。

但这里我们从应用开发者的视角去看这个问题。
应用开发者需要什么样的区块链?
1 根据当前的项目规模,获得安全、性能、成本与当前规模相匹配的区块链环境
2 可以逐步升级的区块链环境
3 可以获得网络效应的区块链环境
而这些正是波卡网络会提供的,至于如何提供,本文后面几个问题中会逐步展开聊。

总结,跨链的意义不只是把BTC或ETH上的资产跨过来,而是基于跨链构造对开发者更灵活的区块链环境。

怎么解决 TPS 和 GAS Fee 的问题?

解决 TPS 和 GAS Fee 的问题并不难,EOS 的 TPS 就高得多,难点在于满足安全性要求的前提下,解决 TPS 和 GAS Fee 的问题。

这里就要聊下 Eth2 和波卡作为分片架构的不同之处。
Eth2 的分片是清晰的两层,上面一层信标链,下面是各个分片。各个分片的安全性和使用成本是一样。后续的拓展则依靠 Layer 2,Layer 2 的实现方式可以很多样。
波卡则是一种类似分形的架构,最上面一层是中继链,下面可以有第二层中继链,依次可以一直往下迭代。安全性和使用成本会逐层下降,跨链消息传递也会逐层变慢。举例来说,Kusama 将来就可以成为一个第二层中继链。

安全、成本和性能本质上是不可能三角,波卡的特点在于给到应用不同阶段有自己选择的空间,应用最开始跑的时候选择接入第二层中继链来获得基础的安全性保障和跨链功能,如果将来需要更高的安全性和跨链性能,则可以迁移到第一层中继链,需要的操作也就是切换一下平行链插槽或者平行链线程而已。

总结,BTC时代,大家Fork一个BTC链相当于自建机房;ETH时代,大家在上面发智能合约相当于所有应用放在一个IDC机房,抢一个出口带宽;波卡时代,大家终于可以在阿里云上基于自己的需要按量付费了。

小团队启动一个区块链太难了,做好一个DAPP足够了?

启动一个区块链的难点:你要有社区,要有经济激励系统,要让社区有能力来持续的跑节点,为了持续的提供激励需要每年增发通证来奖励矿工,为了让奖励有价值你还需要维持市值。任何一个环节掉链子,这个系统就崩了。
用波卡,上面这些都不需要,你只需要支付一些成本,共享波卡网络的安全性即可。
波卡是如何做到的?简单来说还是用了跨链的特性,让另一条链来验证你的链的出块(再次证明跨链不只是把BTC跨过来这一个应用场景)。

至于说DAPP是不是足够了这个问题,其实程序开发难度和程序复杂度并不直接相关。
举个栗子,现在几乎没有人会徒手写一个复杂的HTML网页出来,都是引入各种第三方库,然后调用一些自己需要的组件和样式。写Solidity智能合约就像徒手写HTML网页,简单的应用是挺方便的;而用应用链结合Substrate的Pallet组件则是一种更解耦、更模块化的工程方案,它能让区块链上复杂系统的出现成为可能。

区块链不能快速试错?

区块链不会仅仅因为时间长就安全,资金规模、攻击成本会是更大的关键因素。

波卡提供的是一个渐进安全的生态,不同规模的项目,能够灵活的迁移到对应的共享安全框架和容器(中继链)中去。
Kusama就是很好的例子,你可以在上面试错,做大规模后迁移到安全性更高的波卡主网上去即可。

要求程序员不出bug是不可能,但可以用Rust这种语言来自动检查和约束,有更多安全的库和代码可以被获得和重用,从而吸引更多的开发者和团队从事区块链开发。

智能合约如何升级,不如搞个Admin Key?

这里又要说到复杂系统的问题,智能合约为什么很难升级,因为需要为了升级引入更多智能合约的代码,从而让原合约更复杂、更不安全。
如何解决?在波卡上可以通过升级应用链的方式解决,将不同的功能解耦、模块化、分而治之。

区块链治理目前意义不大,是形式主义?

治理的意义在于解决区块链系统如何升级的问题,所以能够升级是前提,能够升级后治理才有意义,否则的确是形式主义多一些。
波卡的优点在于升级和治理都是链上完成的,其治理设计思想的目标是让治理结果能够代表多数人的长期利益,要实现这一点是很难的,我们看到现实社会也没有很完美的解决方案,波卡在这方面的尝试也还需要时间验证。(关于波卡治理的流程可以看本号之前的文章)

最后,本文基于作者目前对波卡等区块链网络公开资料的理解撰写而成,如有偏差,欢迎指正。

波卡治理系列(二)提案投票的具体过程

关于什么是链上治理之类的,可以看之前的文章《波卡运行原理系列(二)治理机制》
http://blog.boka.network/?p=374
本文主要基于Kusama网络的实际运行,讨论下治理操作的具体过程

名词翻译

Proposal Pre-images 提案预览
Democracy Proposals 民主提案
Democracy Referenda 公投(民主公投)
Council Motion 议会议案
Tech Comm Proposals 技术委员会提案
Treasury Proposals 财政提案

角色

群众:KSM/DOT 持有人
Council:议会,投票选举产生
Technical Committee:必须是Runtime的开发者,由议会选举

提案分类

更新代码或参数:这种提案有两种方式,分别是公投和Fast-Tracking
申请资金:具体是指从Treasury中申请资金用于社区活动,Treasury的资金来源包括链上交易手续费等

公投

所有人都可以提交
Launch period: 28 天(kusama)

过程:Proposal -> Referendum -> 议会投票 (28天) -> 公投 (28天) -> 实施 (30天)

注:
Kusama 7天
Polkadot 28天

Proposal

每28天,排在第一位的Proposal变成Referendum,进入议会投票。
Proposal阶段所有人可以通过锁定的token,用seconding方式支持,提升该Porposal排位。

议会投票 & 公投

议会投票的意义是为了解决由于关注度低或者度假,大多数用户没有参与投票,而少数参与投票用户不能代表社区意见的情况发生。

议会投票赞成 <50% -> 不通过。

议会投票赞成 >50% 但 <100% -> 普通用户公投 – 按参与投票比例,通过的条件如下黄色曲线

10%投票,超过75%赞成则通过提案
100%投票,超过50%赞成则通过提案

议会投票赞成 = 100% -> 普通用户公投 – 按参与投票比例,通过的条件如下绿色曲线

10%投票,超过25%赞成则通过提案
100%投票,超过50%赞成则通过提案

锁仓时间和投票权重

你可以通过增加锁仓时间来提升投票权重
最长 128 weeks – 32 months – 两年半
也可以不锁 参与投票 但权重很低
最终只有与你意愿一致的投票,才会导致锁定
锁仓的 token 可以同时做其它的投票操作,比如staking、second等

实施

如果公投通过,30天后实施,不赞成的用户可以有机会在此期间离开生态

技术委员会提案

技术委员会成员可以发起Fast-Tracking提案
3天投票时间
投票通过后立即实施

投票通过条件:
3/4 议会成员同意
2/3 技术委员会同意

Treasury提案

Treasury提案本文不做展开,有兴趣的同学可以查看官方Wiki
https://wiki.polkadot.network/docs/en/learn-treasury

将来可能会加入其它治理提案

Oracle Committee – 用于预言机系统的治理

Spontaneous Subject Committee – 用于少数人能够弄懂特定技术投票

波卡运行原理系列(四)BABE共识简述

BABE是目前Kusama、Edgeware等网络使用的共识之一,用于确定出块顺序。

概念定义

Slot,槽,区块生成时间
Epoch,时期,固定长度的Slot的集合
VRF,可验证随机函数,私钥相关,任何人可以通过公钥来证明

解决问题

引入随机性,尽可能让下一个出块验证者不可预测,从而满足出块的去中心化

步骤

验证人使用自己的私钥生成VRF(随机数 + Proof)

验证人计算 SlotNo + Epoch No + 随机数 得到一个值,如果该值小于一个特定值,则获得出块机会

如果一个 Slot 方式如下情况:
1 Slot 没有人的VRF满足要求
2 Slot 多个验证者满足要求
则按照Aura顺序指定验证人出块,被称为次级Aura区块,优先级低

每个Epoch,将根据最新的Staking情况,重新选择验证者集合
重新选择验证者集合的随机数来自上一个Slot的随机值混合

BABE通过这个过程确定了出块验证者的顺序
确定出块(敲定)则需要通过GRANDPA完成,具体可以看波卡运行原理系列(三)
http://blog.boka.network/2020/02/29/bo-ka-yun-xing-yuan-li-xi-lie-san-zu-jian-zi-dian/

区块结构

区块由摘要 Digest 和 封章 Seal 组成

Digest包含:
Pre-digest:VRF输出和证明
运行时处理的 transactions 记录集合
Post-digest:Epoch 切换时才有,输出混合随机值用于重新选择验证者集合

封章即节点的签名

BABE的问题

在很小范围和概率情况下,节点可以影响随机值:
1 节点可以选择不出块,从而随机值不到下个 Epoch,因此能够实现小概率的验证人顺序预测。
2 一个Slot可能存在没有BABE验证者,或有多个验证者的情况

所以在此基础上诞生改良的 Sassafras 共识,具体可以看TangWei的视频,本文不展开讨论
https://www.bilibili.com/video/BV1bz411z73k

Substrate 应用链开发视频教程02 – 如何使用 PolkadotJS 与 Substrate 进行交互

本教程内容覆盖 DAPP 架构、搭建 DAPP 开发测试环境、三个基于 PolkadotJS 的 DAPP 应用 Sample

Screen Shot 2020-04-21 at 10.48.15

腾讯
https://v.qq.com/x/page/o0952vkp0zs.html

B站
https://www.bilibili.com/video/BV1wK4y1k7q1

YouTube
https://youtu.be/fApNFRFPGDs

PPT
https://github.com/ericfish/Substrate-Dev-Book/blob/master/ppt/Sub-Video-02.pdf

代码:
https://github.com/ericfish/Substrate-Dev-Book

推荐开发测试钱包 MathWallet 浏览器插件:
http://mathwallet.org

Substrate 应用链开发视频教程01 – 开发环境的设置和调试技巧

内容覆盖搭建 Substrate 不同版本的环境、如何保证版本一致、如何使用 CLion 进行调试

Youtube:
https://youtu.be/17_uIlxevf0

腾讯视频:
https://v.qq.com/x/page/m09437gz5zz.html

B站:
https://www.bilibili.com/video/BV1Ea4y1t7kp/

PPT
https://github.com/ericfish/Substrate-Dev-Book/blob/master/ppt/Sub-Video-01.pdf

代码:
https://github.com/ericfish/Substrate-Dev-Book

推荐开发测试钱包 MathWallet 浏览器插件:
http://mathwallet.org

PolkadotJS 开发教程 – 查询交易记录

因为区块链上只存储最新的状态,以及状态之间的变化,所以默认情况下无法像数据库那样查询交易记录。
一般查询交易记录的方法有三种:中心化归档、订阅Events、遍历Block。

中心化数据归档

请查看 Polkascan 的开源方案,本文不做展开
https://github.com/polkascan

Events

通过订阅 api.query.system.events

见代码
https://github.com/ericfish/Substrate-Dev-Book/blob/master/02-tx-history/events.js

运行

node events.js

到钱包界面发起一笔转账测试,会发现出现一条新的Event记录

Screen Shot 2020-03-31 at 15.32.01

对Event解析后,可以获得转账操作的各种详细信息:

[
    {
        "phase": {
            "ApplyExtrinsic": "0"
        }, 
        "event": {
            "index": "0x0000", 
            "data": [
                {
                    "weight": 10000, 
                    "class": "Operational", 
                    "paysFee": true
                }
            ]
        }, 
        "topics": [ ]
    }, 
    {
        "phase": {
            "ApplyExtrinsic": "1"
        }, 
        "event": {
            "index": "0x0302", 
            "data": [
                "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY", 
                "5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL", 
                2200000000000, 
                0
            ]
        }, 
        "topics": [ ]
    }, 
    {
        "phase": {
            "ApplyExtrinsic": "1"
        }, 
        "event": {
            "index": "0x0000", 
            "data": [
                {
                    "weight": 1000000, 
                    "class": "Normal", 
                    "paysFee": true
                }
            ]
        }, 
        "topics": [ ]
    }
]

默认情况下,以下操作会产生Event
https://polkadot.js.org/api/substrate/events.html

另一个监听解析 Event 示例
https://polkadot.js.org/api/examples/promise/08_system_events/

另外一个通过监听Event,并写入记录到Mongodb的例子
https://substrate.dev/docs/en/tutorials/tcr/building-an-event-based-off-chain-storage
https://github.com/substrate-developer-hub/substrate-events-listener

遍历 Block

基于 Event 的数据,我们可以通过 range 来查询区块区间的所有数据

const events = await api.query.system.events.range([startHdr]);

示例:
https://github.com/ericfish/Substrate-Dev-Book/blob/master/02-tx-history/range.js

运行

node range.js

TIP

介绍一个可以比较方便的查询和测试 PolkadotJS API 的工具
https://apiexplorer.polkalert.com/
支持本地的ws接口

 

PolkadotJS 开发教程 – Substrate 应用链各个模块的版本

各个模块的说明

首先需要理解一下各个模块都是什么?

Substrate:应用链框架,包含了各种模块,可以快速启动一个自定义的区块链
https://github.com/paritytech/substrate/

Polkadot:基于Substrate的区块链,将来是波卡主网,目前Kusama实验网也基于这套代码
https://github.com/paritytech/polkadot/

PolkadotJS:与Substrate交互的JS框架
https://github.com/polkadot-js/api

PolkadotJS-APP:React开发的基于PolkadotJS API的网页钱包
https://github.com/polkadot-js/apps

因为目前不管是 Substrate,Polkadot,PolkadotJS 还是 PolkadotJS-APP 都在快速迭代中,因此各个版本之间存在大量不兼容的情况。

如何查看当前的版本

可以通过 PolkadotJS-APP 左下角查看当前运行环境的版本

第一行:node的版本
第二行:PolkadotJS版本
第三行:PolkadotJS-APP版本

Artboard

以下是几个配合可用的版本示例:

Substrate 2.0 Node Template

https://substrate.dev/docs/en/tutorials/creating-your-first-substrate-chain/setup
对应可用的 PolkadotJS-APP(麦子钱包运行的老版本网页钱包):
http://app2.substrate.cc

SubstrateKitty

https://substrate.dev/substrate-collectables-workshop/#/?id=substrate-collectables-workshop
对应可用的 PolkadotJS-APP(麦子钱包运行的更老版本网页钱包):
http://app.substrate.cc

Kusama

使用最新的 PolkadotJS-APP:
https://polkadot.js.org/apps

Edgeware

注:
插件钱包的版本与 PolkadotJS-APP 网页钱包类似,同样存在兼容性问题,对于特定版本的 API 需要下载对于版本的插件钱包