前沿
从技术上来说,Libra属于区块链2.0 的联盟链,在实现上,整体参考了以太坊的设计,当然,自己实现了一套类似于solidity 的智能合约语言,Move;共识上,使用的是BFT 共识算法蔟,称之为LibraBFT。当然,这里是联盟链,因此,自身也实现了一套联盟准入机制。
1、交易模型
transaction
{
Sender address:交易发起方的账户地址,
Sender public key:交易发起方公钥,
Program:{
script: Move 交易脚本字节码(Move 类似与以太坊的 solidity,作为libra的只能合约语言),
inputs: 所调用合约方法的入参,作为点对点交易,方法入参包括交易接受方address,以及转账额度
},
Gas price: 汽油价格,与以太坊的定义基本一致,以太坊中,其智能合约执行的每一条evm 指令都需消耗汽油,而总汽油消耗量乘以汽油价格,则是发生方所消耗的代笔
Maximum gas amount:最大汽油消耗量,与以太坊中的作用一致,防止交易过度执行(如死循环)
Sequence number:交易序列号,从交易发起方的Account 中获取,用于交易防重放机制(与以太坊的方案基本一致)
Expiration time:交易过期时间,超过该时间的交易如果还没有达成共识,则被视为无效交易
Signature:用于交易验签
}
//上述为交易模型设计,与以太坊中的交易模型类似。
2、交易流程
我们通过一个交易的生命周期来分析整个libra 的各个组建及其依赖:
Accepting the Transaction(接受交易)
(1)transaction T 通过客户端发送至 验证节点【Validator node】V1 ,并由其组件 AC(admission control) 接收,对应AC::SubmitTransaction()。
(2)组件AC收到该交易T后,通过调用组件VM(virtual machine,虚拟机)进行交易的初步验证,例如交易的签名校验,账户余额检验 以及防重校验等(与以太坊的防重放机制一致),对应VM::ValidateTransaction()。
(3)当交易T 通过验证后,AC会将T,通过方法Mempool::AddTransactionWithValidation()发送至 V1 的mempool。
Sharing the Transaction With Other Validators(与别的验证节点共享交易)
(4)这时,Mempool会将T 存放于内存中,当然,Mempool 内存中可能会有多比发送方相同的交易。
(5)通过使用共享内存协议(shared-mempool protocol),节点V1 将会与网络中别的验证节点(Other Validators)共享Mempool 中的交易。
Proposing the Block(发起共识)
(6)libra 所使用的时Leader base 的LibraBFT 共识协议,这时,我们假设V1 位leader节点;然后,V1从Mempool中拉取一定数量的交易集合打包成block,在通过LibraBFT 协议将block 复制到别的验证节点。
(7)共识【consensus】组件作为V1 的协调者,负责与网络中别的验证节点交易,主要处理投票发起、验证 投票请求并收集投票等。
Executing the Block and Reaching Consensus(执行区块,达成共识)
(8)作为达成协议的一部分,区块中的交易集合将有交易执行(Execution) 组件。
(9)交易执行(Execution) 组件管理着虚拟机(VM),并通过VM来执行交易指令,需要注意的是,执行是发生在共识达成之前。
(10)当VM执行交易完成后,Execution组件会将block 中的交易追加到 数据结构Merkle accumulator(账本历史记录),当然,这个追加只是存在于Merkle accumulator的内存中,并将执行结果返回给共识【consensus】组件。(与以太坊的交易执行引擎设计类似)。
(11)leader 节点V1 尝试在 自身交易执行结果 以及 网络中别的验证节点交易执行结果一致后,达成共识。(这里的设计与并行pbft的设计类似)
Committing the Block(提交区块)
(12)当共识达成后,将缓存中的执行结果通过Storage组件持久化到磁盘(该流程与以太坊相似)
3、共识
3.1LibraBFT共识介绍
LibraBFT 是属于leader-based 的BFT共识算法蔟的一种。在leader-based的共识算法中,每一轮(round)的共识都会选举出一个leader 节点,然后由leader节点发起提案,收集投票(vote),最后达成共识。在LibraBFT中,所有参与共识的节点称之为validator,验证节点。
LibraBFT是变体的HotStuff chain(这个链不是block chain ,而是用于共识的链hash 链),在HotStuff 的每轮(round)共识流程中,所有的信息交互都只和leader 节点进行,然后,leader 节点的提案会以一条加密的hash链组成(HotStuff chain)。在每轮共识中,被选举出的leader 节点会基于节点自身最长的HotStuff chain 提出block 提案,如果提案是有效并且及时,剩余的诚实节点会使用自身的私钥签名该提案,并将通过的vote发送会leader节点。当eader 节点收集到足够的(quorum)vote时,会将vote 聚合成Quorum证书(Quorum Certificate,QC),当然,leader 会基于上述已延伸的最长HotStuff chain 继续追加QC,换言之,一轮共识成功后,leader节点会基于自身最长的HotStuff chain,按序追加提案Block(缩写B) 以及 QC(缩写C),然后在将QC再次广播至剩余的节点,并开启下一轮的共识。当然,这是共识成功的情况。在异常情况下,无论任何原因,如果当前leader 节点没法及时共识成功,共识参与者会一直等到当前round 的超时时间,然后在发起下一轮的共识。
最后,如果足够的Blocks 以及QCs 都能连续及时的通过共识,并且其中一个block 达到了被commit 条件,那么,该block 会被commit ,换言之,该block 以及block 中transaction 集合都会被落盘,并被确认。
而[图 HotStuff Chain] 描述的HotStuff Chain,其可以表现为: 【ℎinit ← ????1 ← ????1 ← ????2 ← ????2 … ← ????????+1 ← ????????+1】
3.2LibraBFT共识流程详解
我们通过[图Libra共识流程]中的 round 3来详细分析共识流程:
❶如图所示,node1 被选举为leader节点,然后node1会基于自身最长链尾部C2发起B3 提案,然后将提案广播至剩余节点(node0,2,3),广播完成后,node1会执行B3 中的transaction 列表,得到execute state;
❷当剩余节点(node0,2,3)收到B3提案后,会执行B3中的交易,然后将execute state 打包到vote 中,在将其签名,并发送给node1;
❸一起都正常情况下,node1会收到自身以外的vote 请求,当收集到足够多的vote时,并且vote 验证通过,包括execute state 、签名、round 等,leader 节点会将vote 集合打包成quorum certificate(QC),并将QC广播至剩余节点,到这里,一轮共识完毕。
上面只是共识流程,那么,block会在什么时候被提交呢?
我们先回顾一下共识轮次round,共识轮次用int 表示,并且只会递增。正如上面所介绍的,在每一轮共识轮次中,都仅由一个leader 节点发起一次提案,轮次仅在共识成功后或当前共识轮次超时才会结束,然后轮次自增1,启动下轮次共识。
因此,我们我们假设round(Bi) 为提案Bi的当前轮次值,并且,依据递增的规定,可以得到round(????????) < round(????????+1);
另外,如果round(????????) + 1 = round(????????+1),我们则称之为连续共识成功两轮,代表在这两轮共识中,都没有发生超时,并且共识都成功。
我们还是以上述例子来分析生么情况下,block 会被commit ,如果同时满足以下两个条件:
- ????1 ← ????1 ← ????2 ← ????2 ← ????3 ← ????3
- round(????3) = round(????2) + 1 = round(????1) + 2
那么,B1 则会被commit,换言之,连续三个共识轮次成功的情况下,第一个共识的block 就会被提交。
总的来说,相对于PBFT的三阶段提交来说,LibraBFT 的只需1.5阶段,既可完成一轮共识,上述的round(B3)完成后,round(B1)才会被commit相当于PBFT的commit 阶段。总的来说,共识吞吐翻倍,而且LibraBFT 只与leader 通信,会想读来说更简单。
4、智能合约
Move 作为Libra 的智能合约语言,有三大用处:
- 发行数字货币、Token、数字资产
- 灵活处理区块链交易
- 验证器(Validator)管理
move特性:
4.1自底向上的静态类型系统
Move 采用的是静态类型系统,类型系统本质上是一种逻辑约束。相比以太坊的智能合约语言来说要严格地多。现代的编程语言比如 Rust、Golang、Typescript、Haskell、Scala、OCaml 都不约而同采用了静态类型系统,他们的优点是,很多编程低级错误都可以在编译的时候发现,而不是拖到运行期才爆出 Bug。4.1自底向上的静态类型系统
4.2First-class Resources 理念
First-class Resources这个词相当的学术,中文翻译过来叫资源是一等公民,这究竟什么意思呢?所谓的编程语言的一等公民就是编程语言在编程的时候首要考虑的被编程对象。那么资源,Resources又是什么呢? 这也是一个很学术的名字。Resources是和 Value 相对应的概念。Value是可以随意拷贝的,而Resources只能被消耗,不能被拷贝。
传统的编程语言,包括以太坊智能合约语言中,对于数字资产的记账是采用的Value方式,这会导致一个问题:记账是有可能记错的。事实上记错账的智能合约相当得多,比如:张三向李四转账,李四的账户多了 10 块钱,但是张三的账户余额却没改。过去两年里的各种记账漏洞甚至一度搞得大家已经对智能合约的未来丧失了信心。
Move 合约采用了一种吸收了传统理论「线性逻辑」的类型,叫做资源类型。数字资产可以用「资源类型」来定义,这样一来,数字资产就像资源一样,满足线性逻辑中的一些特性:Move 合约采用了一种吸收了传统理论「线性逻辑」的类型,叫做资源类型。数字资产可以用「资源类型」来定义,这样一来,数字资产就像资源一样,满足线性逻辑中的一些特性:
- 数字资产不能被复制
- 数字资产不能凭空消失
4.3强悍的模块系统
Move 模块系统采用的是一种函数式编程语言(OCaml、Coq、SML)风格的设计,按照白皮书的说法:模块系统可以很好地将数字资产的概念打包封装,对于数字资产的操作比如通过模块的公开接口,并且在这个接口上可以做灵活的权限控制。在写以太坊智能合约的时候,以太坊上的 ERC20 Token 是作为一个合约而存在,而在 Move 语言中,一个 Token 可以被想象成一个箱子,被随意像资源一样传递,但是同时不会暴露箱子内部细节。同时模块系统的抽象也完全基于它的静态类型系统,并且类型安全性完全可以由智能合约虚拟机来检查保证。
总的来说,Move 虽然看起来还略显粗糙和稚嫩,但是这个方向仍然让人激动人心,从 Move 语言层面可以看到 Facebook的野心,是想做一个庞大的数字资产平台。
有疑问加站长微信联系(非本文作者)