详解move语法、解释器和介绍器

move语法
白皮书使用了一种半形式化(semi-formal)的描述语言进行了描叙。至于这套描述语言,主要符号解释如下:
  • =: 定义
  • ::= : 赋值
  • ⇀: 映射
  • ×: product type,也就是表示结构体
  • ∈: 表示属于某个类型或者集合中的一个元素
通过这些符号,Move定义了如下的语法类型:
Global state: 地址到账户的map,账户由Resource和Module构成。形式化定义如下:
Modules:由名字,结构体声明以及过程声明组成, 可以简单理解为c++的class。module通过ModuleId被外部索引(访问),结构体通过structId被外部索引,结构体声明是一个<kind, FieldName->非引用类型>的product类型。
Module定义了资源的作用域,类似于c++的namespace的功能。其中Module内置了几个重要的函数用来进行类型操作:
  • Pack and Unpack 用于从非受限类型创建和销毁模块的资源;
  • MoveToSender/MoveFrom 在当前账户地址下面发布或者删除对应的资源;
  • BorrowField :获得结构体的一个字段的引用
Types: 包含基本类型(bytes是fixed-size字符串,AccountAddress是256bits),结构体类型,非引用类型,以及
在Module里面除去被声明为资源的类型(标记了resource kind),其余的类型统称为unrestricted types(不受限类型)。资源类型的变量或者字段只能被move,并且资源类型变量的引用不能被解引用,也不能被重复赋值。另外an unrestricted struct不能包含restricted field,原因很简单, unrestricted 结构体被赋值或者复制的时候,如果有restricted字段,那这个字段不会实际被操作到。
Values:
Move支持引用,引用是短暂的,因此不能被用来定义结构体的字段,也不能引用引用,应用的声明周期就是交易脚本的执行过程。通过Borrow{Loc, Field, Global}可以分别可以获得局部变量,结构体变量或者全局变量的引用(敲黑板,请学习rust)。
另外因为struct里不能存储reference,所以可以保证struct一定是一个tree而不会有backedge。这也是move比rust简化的最重要的一点,正因此move不需要复杂的lifetime。 因此Resource同样也不可能出现图结构。这样确实大大简化了语言的处理。
Procedures and transaction scripts:
过程的签名包含函数的访问控制修饰符,参数类型和返回值类型。过程声明包括一个过程签名,局部变量和一系列的指令,(作者认为,这个声明理解为定义(definition)更合适一些)。一个交易脚本是一个不关联具体module的过程,因此他不会被复用,交易脚本操作的全局状态转换,这些状态的修改要么全部成功,要么全部失败。
ProcedureID标识一个过程,被moduleId和过程签名唯一确定,并且Call指定将其作为第一个参数,进行调用。这也就意味着函数调用是静态可确定(staticly determined)的,不存在什么函数指针或者函数表。同时模块内的过程依赖是无环的,加上模块本身的没有动态指派,这样就加强了执行期间的函数调用的不可变性:也就是一个procedure在执行过程的call frame必然是相邻的。因此也防止了类似于以太坊里面的re-entrancy攻击(这个就是有名导致分叉出ETC的攻击)。
move解释器
Move的字节码指令在一个栈式的解释器进行执行,栈式虚拟机的好处是易于实现和控制,对硬件环境的要求较少,非常适合区块链场景。同时文中也提到,相对寄存器式的解释器, 栈式解释器在不同的变量之间进行copy和move更容易控制和检测。
解释器的定义如下:
解释器由一个Value Stack,Call Stack以及全局变量引用计数器和一个GasUnits(类似以太坊的Gas Limits)组成。CallStackFrame包含了一个过程执行的所有上下文信息以及指令编号(指令会被唯一编码,减少代码体积,常规处理方法)。Locals是一个变量名到运行时候的Value的map。
字节码解释器支持过程调用(废话啊)。当在一个过程中执行Call指令调用其他的过程的时候,会创建一个新的CallStackFrame对象,然后将对应的调用参数存储到Locals上面,最后解释器开始以此执行新的合约的指令。执行过程遇到分支指令的时候,会在本过程内部(也就是Basic Block之前的跳转)发生一个静态跳转,所谓静态跳转实际上是指跳转的offset是事先已经确定好的,不会像evm一样动态跳转。这也就是之前提到的no dynamic dispath。最后调用return结束调用,同时返回值放在栈顶。
Gas衡量的思路跟EVM是一样的,每个指令有对应的Gas Units,执行一次,减去对应指令的Gas消耗,直到减到0或者所有指令执行完成。
Move的指令包括6大类:
  • 变量操作: CopyLoc/MoveLoc实现数据从本地变量到栈的拷贝和移动,StoreLoc是讲数据存回来到本地
  • 常量/数值/逻辑操作
  • Pack/Unpack/MoveToSender/MoveFrom/BorrowField 等资源操作,具体的解释可以看前一篇文章
  • 引用相关的指令,包括ReadRef/WriteRef/ReleaseRef/FreezeRef, 其中FreezeRef转换一个可变引用到一个不可变引用
  • 控制流结构,包括call和return,branch,BranchIfTrue,BranchIfFalse等
  • 区块链特定的操作,包括获得交易脚本的sender或者创建一个账号等指令。
详细的指令列表在白皮书的Appendix A已经列出。
Bytecode验证器
验证器我们在很多编译器里面都能看到,例如普遍使用的SMT证明器Z3. 验证器的核心功能就是在编译阶段保证语言(合约)的安全特性能够得到满足和增强。验证器静态验证是合约脚本发布的必经步骤。
验证器的状态如下:
对于一段可能包含多个module的交易脚本,进行验证,验证结果返回ok,或者各种不满足条件的报错。
Move的模块的二进制格式里面编码了一系列实体的集合,这些实体都放在一个table里面, 包括常量,类型签,结构体定义以及过程定义。检测过程主要有三类:
  • 结构体合法检查: 保证字节码的table的完整性(well-formed), 检测的错误非法的table index, 重复的资源实体以及非法的类型签名,例如引用了一个引用等
  • 过程定义的语义检测:包括参数类型错误,悬垂索引以及资源重复定义。
  • 链接时错误,非法调用内部过程,或者链接一个声明和定义不匹配的流程。
下面重点解释下语义检测和链接时错误检测。
Control-flow graph construction
验证器会首先创建一个bytescode的BasicBlock的控制流图,一个BasicBlock可以理解为中途没有分支指令的指令块。
Stack balance checking
检测栈里面被调用者的访问范围,保证合约的被调用者不能访问到调用者的栈空间。例如一个过程被执行的时候,调用者首先在CallStackFrame里面初始化局部变量,然后将局部变量放入到栈里面,假设当前栈的高度是n,那么有效的bytecode必须满足不变性: 当到达basic block的结束的时候,栈的高度依然还是n。验证器主要是通过分析每个基本块的指令对栈的可能影响,保证不操作高度低于n的栈空间。这里有一个例外就是,一个以return结尾的block,他退出的时候高度必须是n+m,其中m是过程返回值的个数。(这个特殊的操作有点匪夷所思,难道是把栈的高度默认放在了过程的第一个参数,退出的时候这样可以进一步的进行检测?后面确认了,确实是因为目前不支持多返回值,所以才加在一起)。
Type checking
在二进制格式里面,局部变量的类型是定义好的,但是栈的value确实需要推导的。在每个基本快这种推导和类型检测独立执行的,因为前面保证了调用过程访问的栈的高度是合法的,因此,这个时候就能安全的推导栈里面变量的类型了。具体检测就是给Value Stack维护了一个对应的Type Stack,执行的时候TypeStack也跟这指令执行进行pop和push。
Kind checking
kind和type的区别是type可能包含别名。 kind的检查主要检资源是满足
  • 不可双花
  • 不可销毁
  • 必有归属(返回值必须被接受)
对于非资源类型的话,就没有这些限制了。
reference checking
引用的语法包括可变引用,不可变引用。所以引用检测结合了动态和静态分析。 静态分析利用类似rust类型系统的borrow checking机制,保证:1. 所以引用必须指向的是一个已经被分配的存储上,防止悬空; 2. 所有的引用都有安全的读写权限,引用访问既可以共享,也可以排斥(也就是有限的读写权限)。
为了保证2点, BorrowGlobal调用的时候会动态的对全局变量的引用进行了计数, 解释器会对每个发布了的资源进行判断,如果被borrow或者move了,再次引用就会报错。
Linking with global state
链接的时候还需要对链接的对象和声明是否匹配,过程的访问控制等做再次的检查。
以上就是目前Move的大部分的静态验证了。可以看到每个流程都有非常严格的分析和限制,最大程度的保证Resouce的安全转移和访问。
最后将虚拟机所有的状态和转移总结如下:
Move虚拟机通过执行区块交易里面的脚本实现全局状态Σ的转移。E表示交易脚本产生的针对某个账户的状态修改集(可以理解为XuperChain的读写集):
虚拟机会顺序执行区块的每个交易,产生一系列的E,并且前一个E在后面交易执行的时候是生效的。
当前vm是串行执行交易,然后产生一系列的读写集。 但是Move在设计的时候,已经考虑到了预测执行产生读写集,然后合并的时候根据资源的access path(可以对比与XuperChain的读写集版本)进行冲突检测来解决冲突。。
最后将讲到了未来的规划,重点还是完善类型系统,提供更多类库支持。
这个白皮书分享系列到此为止,可以整体可以看到,Move通过借助logic type,module。 system在资源的转移控制上面做了大量的静态检测来保证资产转移的安全,相对EVM来说,避免了很多问题,Libra主网上线之后,在DeFi领域可能应该会对以太坊的DeFi Dapp造成不小的冲击。

详解LibraBFT共识机制

1. libra共识简介

Libra的共识采用的是LibraBFT共识,是一个为Libra设计的鲁棒的高效的状态复制系统。它基于一种新型的BFT共识算法,HotStuff(BFT Consensus in Lens of Blockchain),在扩展性和一致性上达到了较高的水平。LibraBFT 在HotStuff的基础上引入显示的活跃机制并提供了具体的延时分析。LibraBFT在3f+1个验证节点之间收集投票,这些验证者可能是诚实的节点也可能是拜占庭节点。在网络中有2f+1个诚实节点的前提下,Libra能够抵御f个验证节点的双花攻击和分叉攻击。LibraBFT在一个有全局统一时间(GST),并且网络最大延时(ΔT)可控的 Partial Synchrony的网络中是有效的。并且,LibraBFT在所有验证节点都重启的情况下,也能够保证网络的一致性。
Libra白皮书指出,其将以许可型区块链的方式起步。未来为了确保Libra的真正开放,始终以符合用户最佳利益的方式运作,Facebook的最终目标是让Libra网络成为"非许可型网络",但是其目前的挑战在于,他们目前还没有成熟的解决方案可以通过非许可型网络,提供支持全球数十亿人和交易所需的规模、稳定性和安全性。从“许可型”网络过渡到“非许可型”网络,共识层面还需要做非常大的改进。

2. HotStuff算法

2.1 HotStuff算法特点

HotStuff 是一个三阶段的BFT算法,允许一个新的leader简单地选择一个最新的的QC(Quorum certification)。它引入了一个第二阶段,允许副本在投票后在不需要请求leader请求的基础上改变他的决策。这一改进大大降低了复杂度,同时也降低了leader替换的复杂度。最后,由于长期委任所有的状态,这样HotStuff非常容易通过事件机制的方式实现,适合leader经常切换的场景。HotStuff主要有以下几个特性:
• 线性的视图切换:在GST后,对于一个诚实的leader,一旦被指定,会发给n个验证者来收集签名,以推动共识的决定;
• 乐观的响应:在GST后,对于一个诚实的leader,一旦被指定,只需要等最早的 n-f 个验证者返回消息就可以发起有效的提案,包括leader替换;
• 支持频繁切主:HotStuff还有一个特点是新leader的推动协议达成共识的成本不高于当前领导者的成本,所以其适用于leader切换的协议;
• 决策简单:HotStuff中副本只有两种消息类型和一个简单的规则来决定是否要接受一个提案,其通过投票和提交规则来达成一致性,通过Pacemaker来保证可用性,并且各阶段的算法复杂度低;
• 阈值签名:HotStuff使用阈值签名的方式来收集签名,使得签名的验证会更为简单;

2.2 HotStuff算法流程

Basic HotStuff

Basic HotStuff 协议是HotStuff的基本过程,他在一系列的视图中切换,视图以单调递增编号方式切换。在每个视图内,有一个唯一的达成共识的leader。每个副本在起本地数据结构中会记录所有请求的tree,tree的每个叶子节点是一个已经提出的提案。一个给定节点的分支是该节点到达树根的所有路径。按照HotStuff协议,随着视图的增长,分支会被提交。Leader需要像(n-f)个验证者采用阈值签名的方式收集签名,收集签名的过程主要包括3个阶段,PREPARE、PRE-COMMIT和COMMIT阶段,整个算法包括5个阶段,PREPARE、PRE-COMMIT、COMMIT、DECIDE和FINALLY阶段,如下图所示:
1. PREPARE阶段:该阶段,leader发起一个high的提案(highQC),组成消息,消息内容 m = MSG(PREPARE, curProposal,highQC),并广播给所有的验证节点;验证节点在收到时上述提案消息后会进行投票,如果m的node超过本地已经判决过的node是则会投票,并返回消息给leader,m' = voteMSG(PREPARE,n.node,⊥)。
2. PRE-COMMIT阶段:该阶段,当Leader收到(n-f)个验证节点的PREPARE阶段的投票信息后,会发起一个 PREPARE的提案(prepareQC),组成消息,消息内容为 m = MSG(COMMIT, ⊥,prepareQC),并广播给所有的验证节点;验证节点在收到上述提案消息后会进行投票,并返回消息给leader,m' = voteMSG(PRE-COMMIT,m.justify.node,⊥)。
3. COMMIT阶段:该阶段,当Leader收到(n-f)个验证节点的PRE-COMMIT阶段的投票信息后,会发起一个 PRE-COMMIT的提案(precommitQC),组成消息,消息内容为 m = MSG(COMMIT, ⊥,precommitQC),并广播给所有的验证节点;验证节点在收到上述提案消息后会进行投票,并返回消息给leader,m' = voteMSG(COMMIT,m.justify.node,⊥)。
4. DECIDE阶段:该阶段,当Leader收到(n-f)个验证节点 COMMIT 的投票后,会生成一个COMMIT的提案(commitQC),组成消息,消息内容为 m = MSG(DECIDE,⊥,commitQC),并广播给所有的验证者;验证者在收到该消息后,会执行命令,并返回给客户端。
5. FINALLY阶段:如果系统进入下一个View,各个副本会发送一个消息给下一个View的leader,消息内容为 m = MSG(NEW-VIEW,⊥,prepareQC)。

Chained HotStuff

上图中可以看出来Basic HotStuff的各个phase中的流程都非常相似,作者又提出了一种Chained HotStuff来优化和简化Basic HotStuff。改进的点主要是改变每个PREPARE节点的View。这将大大降低通信消息的数量,并且可以对决策进行管道处理。Chained HotStuff的流程如下所示:
上述Figure1可以看出一个节点可以同时处于不同的View,通过链式的结构,一个提案在经过3个块后能够达成共识。其内部有一个状态转换器,通过genericQC实现提案的自动切换。其主要算法流程如下所示:

3 LibraBft改进

Libra 为了更好地适应其生态,对HotStuff进行了相应的优化,主要有5点:
1.首要的是Libra定义了安全的条件,提供了安全性、活性和乐观响应的扩展证明;
2.第二点:Libra 通过让验证器集体对区块的状态而不是事务的顺序进行签名,使得协议会更加鲁棒。同时还允许客户端使用QC验证从数据库里读出的数据。
3.第三点:Libra 设计了一个Pacemaker 来发出显示的超时信号,验证者通过他发出的提案自动进入下一个视图,而不需要一个同步的时钟;
4.第四点:Libra 希望让矿工变得不可预测,它最新提交的区块信息为种子生成一个可验证的随机数VRF,成为下一个矿工;
5.第五点:Libra 使用聚合签名的方式保留QC中验证者的身份,以提高验签效率,同时为这些验证者提供奖励。

Libra白皮书技术解读

简介
Libra 目前是一个联盟链的组织形式,他的去中心化体现在,由多个 validator 来共同处理交易以及区块链中的状态,但是随着时间的推移,Libra 也计划朝着公有链的方向发展。
对于 Libra,我们可以将其看做是一个通过 Libra 协议管理的带加密认证的数据库,通过 LibraBFT 共识算法,可以保证每个诚实节点中数据库的数据是一致的。与以太坊相似,Libra 也有智能合约和账户的概念,但是不同的是,Libra 将合约和资源是分开存储的,这个会在后续详细展开。
下面这个图是 Libra 协议中两种角色:客户端 client,验证器 validator。validators 就像是元老会,会轮流着产生提议者,用来将当前的交易定序、打包形成区块,并且共同维护着数据库的一致性。client 就是负责发起提交交易,查询信息等,比如钱包就是一个典型的 client。
这里简单介绍上图的流程,当用户通过钱包(client)发起了一笔转账交易后,钱包就会将这笔经过用户签名的交易通过 grpc 发送给 validator(过程 1)。节点在收到 client 提交的交易后,首先会对交易进行预检验,只有有效的交易才会被 validator 节点转发给当前轮次下的 leader,leader 是 validator 集合中在某个轮次下有提议权利的节点,leader 从本地的交易池中获取若干条有效的交易,对其定序打包后,转发给其他 validator(过程 2)。validator(包括 leader)可以理解为是一个状态机,每个 validator 在收到 leader 广播的 block 后,会执行其中的所有交易(过程 3)。由于 validator 存在作恶的可能性,因此每个 validator 在执行完交易后不能直接将结果写入 storage 中,Libra 的共识要求他们对执行完的结果进行投票,只有达成共识的结果才能写入到 storage 中(过程 4)。在交易被提交成功后,validator 不仅会将交易,以及结果写入到 storage,还会生成一个当前交易版本下整个数据状态的签名(其实就是 Merkle Accumulator),client 在进行一些只读的查询时可以从这个数据结构里进行查询(过程 5)。

数据的逻辑结构

相比于以太坊(ethereum),Libra 弱化了区块(block)的概念,只是把它当做是交易(transaction)的载体,实际的最小执行单位是交易。对于 Libra,我们可以看做是一个带版本号的数据库,这里的版本其实就是交易
Ti
的序号
KaTeX parse error: Can't use function '\(' in math mode at position 2: i\)̲\( ,这个序号是严格递增的。在…
i
时,数据库会保存元组
(T_i, O_i, S_i)
数据,这里的
T_i
表示序号为
i
的交易,
O_i
表示执行完交易
T_i
后的输出结果,
S_i
表示账本状态。当我们执行某个程序,过程的大致可以表述为,在某个状态下,程序代码按照给定的参数执行。例如validator收到了一笔序号为
i
的交易
T_i
,当validator执行时交易时,他的状态是基于上一个版本
S_(i-1)
,输入参数则是接收到的交易
T_i
,而需要执行的代码,其实在
T_i\)$ 中指定了需要执行的合约。所以,按照数学归纳法的推导,如果 validator 的最初状态都是一致,并且是诚实的节点(即诚实的执行),那么只要他们的输入是一致的,这些 validator 的账本状态也将是一致的。
通过这种带版本号的数据库,可以方便的查询在各个版本下的账本数据。例如,我们需要查询在版本号为 10 下某个账户的余额信息。
但是随之而来的问题是,我们如何判断上述的交易、状态数据等是有效和没有被篡改的?Libra 针对上述情况,设计了 Ledger History 数据结构。

账本状态

Libra 和以太坊一样,采用了账户模型,这里之所以没有采用 UTXO,主要是因为 UTXO 模型不适合用于复杂的合约。
以太坊的账户地址是由公钥衍生出来的,Libra 也是一样,不过 Libra 在创建用户的时候会生成两对公私钥:验证、签名(vk,sk)公私钥对。其中 Libra 的账户地址是由 vk 的公钥经过哈希后生成的。之所以要区分 vk 和 sk 是为了安全起见,Libra 用户可以在不更换地址的情况下,更换新的签名公私钥对。
关于账户状态,Libra 和以太坊的区别比较大。在以太坊中,账户下面会存放余额、合约、nonce 等信息。Libra 的账户状态主要包含了两部分:module、resource。module 类似于以太坊中的合约,resource 则是 module 中定义好的资源。module 和 resource 的归属权是分开来的,如下图所示。方框表示的是 module,椭圆表示的是 resource。例如对于账户0x56来说,他发布了一个 Currency 的 module(合约),那么这个 module 是存储在其0x56的目录下的,如果另外一个账户0x12也拥有了 Currency.T 这个资源,那么该资源是存储在0x12的目录下的,相当于是将代码段和数据段分开来了。
而以太坊的合约并不是这样的,例如我们发布了一个ERC20的合约,我们会定义一个 map 结构 mapping (address => uint256) public balanceOf; 该结构会存储某个账户在这个合约中包含有多少 ERC20 的 token。也就是说,以太坊中的合约是将数据段和代码段混合在一起的。
Libra 之所以这样做,主要是为了保证资源的所属权,从而保证其安全性。

交易

交易中有个 program 字段,包含了需要执行的脚本以及参数,或者需要部署的 module 字节码。由于 Libra 采用 LibraBFT 的共识,当 validator 接收到 block,并不意味着这轮的共识结束了,所以 validator 在执行完接收到的交易后,并不会马上将执行后的状态写入到分布式账本状态(Ledger state)中,只有当大部分的节点关于该交易执行的结果投票达成共识后才会更改 Ledger state。
交易
Ti
执行完后,除了会生成新的状态
Si
外,还会额外产生一个交易输出
Oi
。交易输出可以类比于以太坊的交易收据,包括了 gas 使用、执行状态、event 等。这里的执行状态是指虚拟机的执行状态,并不是具体合约的业务执行状态。例如,执行状态是成功,表示虚拟机在执行过程中没有出现 gas 不足或者导致执行异常的触发条件。
为了能够清晰的了解合约执行的执行过程,Libra 参考了以太坊,加入了 event 事件。event 就像是我们在开发中采用 print 方法打印某些日志数据以此判断代码的执行逻辑。事实上,在以太坊的 ERC20 中,开发者为了判断 token 转账是否成功,会在 transfer 函数执行成功后,加上一个 Transfer event,一旦交易执行完成后,抛出了 Transfer 类型的 event,那么开发者就可以认为此次合约转账是成功的(除去分叉的概率外)。

账本历史

账本历史(Ledger History)存储了已经执行并提交(达成共识)的交易,以及 event 信息等。这些信息对于 validator 执行交易来说是不需要的,之所以存储了上述信息,主要的目的是为了保证 validator 的可信度。client 通过查询 validator 的数据,以此监督 validator 在正确的执行交易。

交易执行

再来看一下 Libra 区块链的交易执行,Move 语言会在后续通过实际编写和部署合约的时候仔细介绍。
在 Libra 中,能够触发状态变化的只能是通过执行交易,目前 Libra 的测试网络还不允许普通用户发布合约,并且能够调用的脚本也是有限的,下面是 Libra 中 config 的配置信息,Locked 表示不允许普通用户发布和调用非白名单里外的脚本。
不过最新的 Libra 代码,在 testnet 分支中已经将该限制打开了,普通用户可以在本地进行合约的部署。

交易执行的条件

对于区块链中每个诚实 validator 节点,我们可以把它当做一个状态机,他会在当前的状态下,按照既定的逻辑诚实的执行输入。
那么在最初的时刻,这个初始状态是如何确定的呢?我们用以太坊来进行对比。下面是以太坊的 genesis.json,这个文件确定了以太坊网络最初的状态,比如在 alloc 中设定了两个地址的初始 eth 数量,以及最初的难度值等信息。
Libra 对 genesis 的处理与以太坊的不同,正如 Libra 在白皮书中说的,能够改变状态的唯一方式是交易的执行,而 genesis 作为初始状态的输入,其实也是一个交易,只不过这个交易的序号是 0(
T0
)。这个交易相比于其他交易的特殊点在于,这个交易是一个 writeset 类型的,我们暂时可以将其理解为是一个写入类型的交易,不需要执行。另外,writeset 类型的交易只能在 genesis 阶段运行发布。
既然 genesis 作为
T0
交易,那么必然需要满足他的发送者有足够的费用支付交易费用,同时由于 Libra 是联盟链,因此
T0
会指明当前的 validator 集合以及他们的验证信息等,另外由于 Libra 的 token 是通过合约发布的,因此在
T0
中还会部署上 Libra 的 account 和 coin 两个合约,如果大家有兴趣可以查看下 genesis.blob 来验证下,不过 genesis.blob 有部分是乱码,但是基本上足够支撑上述的论点了。这里之所以这么关注 genesis,是因为通过了解这个方便我们可以自己搭建 Libra 的测试网络。
另外,白皮书提到了确定性,这个比较好理解,如果无法保证确定性,那么意味着不同 validator 对同一个交易的执行结果是不同的,那么就无法达成一致,分叉就开始了。Libra 的 gas 机制与以太坊的比较相似,例如:
1. 影响 gas 的是 gas price 和实际消耗的 gas cost;
2. 一旦交易执行中的 gas 使用超过了 gas limit,那么就会立马 halt,并且将数据回滚到上一个版本,虽然该交易没有执行成功,但是还是会出现在 block 中。
Libra 和以太坊关于 gas 的最大区别是,Libra 设定 gas 的主要目的是为了防止 DDoS,而以太坊的 gas 除了这个目的外,还将 gas 作为激励的一部分给 miner。之所以有这个区别,是因为以太坊是公有链,简单说,你要吸引 miner 来挖矿执行交易,必然需要激励。但是 Libra 是强联盟链, 不太需要这种激励模式。

交易结构

Libra 的交易结构与以太坊的比较相似,对于一个已经签名的交易,他的结构如下:
sender address:很好理解,就是这笔交易发起者地址。
sender public key:表示交易发起者的公钥,这里之所以还要额外再增加这个,是因为 Libra 的账户有两对公私钥(vk,sk),sk 用来签名,因此为了验证交易是否被篡改,需要表明 sk 的公钥。
program:这个就和以太坊的 data 字段一样,用来存放需要执行的 script 或者需要部署的 module。
gas price:和以太坊的一样。
maximum gas amout:就是以太坊的 gas limit。
sequence number:就是以太坊的 nonce,防止双花的。
交易执行
交易执行表示在 VM 中执行阶段,他的行为不会对外部有影响,只有达成共识后,该交易执行的结果才会反应到账本状态。在虚拟机中执行交易一共分 6 个步骤。
1. 验证签名。根据交易的签名数据以及交易的字段中的sender public key来验证内容是否被篡改。
2. 前置校验。一些执行前的前置条件的检验,主要有:
* 身份认证:签名验证确保了数据没有被篡改,这块验证发送者的身份。具体的做法是读取账户的 authentication key,判断和交易中的 sender public key 相同。这个信息在 LibraAccount module 中被定义了。
3.
* 检验 gas 是否足够:因为交易执行过程需要 gas,确保账户有足够的余额来执行交易。通过判断 gas_price * max_gas_amount <= sender_account_balance 来检查。
* seq 检查:检查当前用户的 seq 与交易的 seq 是否一致,防止双花。这个 seq 也是在 LibraAccount module 中定义好的。
4. 验证script和module。这个步骤是 Libra 特有的,以太坊在做完上述检查后就直接进入到了执行步骤。由于 Libra 主打 move,他的特性就是资源的所有权,因此为了保证能够安全的操作这些资源,Libra 相当于做了一个在线的编译器(bytecode verifier),在执行前先做静态分析,确保 module 或 script 对资源的操作是安全。对于这个,有些人认为做成线下的 bytecode verifier 在性能上会更加友好,但是一旦线下的话,Libra 主打的安全其实也就失效了。不过,既然都是 validator 执行交易,那么能否设计成,validator 放出官方的 bytecode verifier,用户的 script、module 需要线下经过官方 bytecode verifier 验证并签名后,才可以发布,此时对于 Libra 来说只需要验证这些 script、module 是否经过官方签名即可,这样也避免影响了 Libra 网络的性能。不过这种方式听起来不是很去中心化,似乎不太符合大家对区块链的理解。我倒是觉得,能够避免一家独大,各家能够充分博弈,这才是比较符合现状。去中心化并不银弹。
5. 发布合约。就是将 module 部署到这个账户下面,注意同一个账户下是不允许发布同名的 module 的。
6. 执行脚本。这块展开的内容比较多,后续会作为重点来讲。这里就认为 VM 根据 program 的 script 执行对应的逻辑。
7. 扫尾工作。在执行完后,就会对账户 seq 自增,以及扣减实际消耗的 gas 等操作。

Move 语言

Move 是 Libra 面向其合约开发者的编程语言,通过 move 可以实现:
1. 我们可以创建 script 从而让交易能执行更多地逻辑;
2. 允许用户按照实际的业务逻辑来自定义数据类型和代码,并发布到链上。
3. 允许配置和扩展 Libra 的协议(包括 Libra 的 token 铸币,validator 管理等)。
Move 最大的一个特性就是,将 resource(资源)当做了一等公民,并且可以自定义 resource。例如上面贴出的 LibraAccount 中的 resource T,就定义了账户的一些基本属性。
Libra 一共有三种编写 Move 程序的方式:source code,intermediate representation(IR),byte code。对应起来就是,高级语言(C 语言),汇编语言,字节码。现在 Libra 还没提供高级语言。
和以太坊一样,Libra 的虚拟机也是基于栈的,基于栈的虚拟机的好处是指令比较精简,不像基于基于寄存器的,指令集满天飞。基于栈的虚拟机是没有堆区的,所有的局部变量和入参以及返回值等都是加载到栈中,每次函数调用完成后,栈的高度应该是和调用前相同的,Libra 基于这个特性做了一个 stack depth 检测,从而增加了交易执行的安全性。

【资料】Libra中文技术解读

Overview

Admission Control

Bytecode Verifier

Consensus

Crypto

Execution

Mempool

Move IR Compiler

Move Language

Network

Storage

Virtual Machine

Other

Libra 加密货币的分析与思考

本文将 Libra 与支付宝、央行数字货币和传统金融基础设施进行了全面对比,并对 Libra 监管层面做了深入解剖,指出 Libra 本身的一些特性为监管带来了难题和挑战,同时 Libra 也必将会对中国支付体系及相关清算机构产生重大影响。
编者按:本文版权属于 CoinDesk 中文,作者: 姚名睿。

前言

自 Facebook 推出 Libra 项目以来,Libra 已引起了全球监管部门、金融机构、科技公司和区块链从业者等高度关注,关于 Libra 的讨论也是层出不穷。本文将 Libra 与支付宝、央行数字货币和传统金融基础设施进行了全面对比,并对 Libra 监管层面做了深入解剖,指出 Libra 本身的一些特性为监管带来了难题和挑战,同时 Libra 也必将会对中国支付体系及相关清算机构产生重大影响。学界、业界应摒弃成见,为未来数字货币“战争”做好准备。全文干货满满,见解独到,CoinDesk 中文版特获作者授权,刊登以飨读者。

全文

Facebook 推出加密货币 Libra 后,各方极为关注。本文将 Libra 与支付宝、传统金融基础设施和央行数字货币进行了全面比较,指出 Libra 或跨越了我们曾经引以为傲的支付宝模式,一举跃进支付新时代。其中,“加密货币”是最核心的关键词。加密货币的创新价值不仅仅只是加密,保护个人隐私,它还赋予用户高度的自主性,点对点交易亦可开创自金融模式,全面提升金融普惠的广度和深度。在价值内涵上,Libra 主动对接传统金融基础设施,锚定一篮子货币和债券,但在金融业务模式上,或将模糊直接金融和间接金融的边界,实现各类金融业务的一体化,其特有的技术特性也提升了国际金融业务的效率,从而对传统金融基础设施形成替代和竞争。与央行加密货币相比,Libra 的技术设计存在差异,但两者均采用了加密货币技术,技术路线一致。本文还指出了 Libra 面临的可能监管及其发展的不确定性。

Libra 与支付宝的区别:加密货币的创新价值

有人认为 Libra 是一个跨国界的“大”支付宝,无非加了密。实质上,这样的理解并不准确。作为拥有 27 亿用户的互联网公司,Facebook 要想拷贝支付宝模式,早就做了。Facebook 的今日之举,是其看出了加密货币是一种新一代的支付工具之后的战略宣言。如果将支付宝的技术比拟为“4G”,Libra 的技术则更像是“5G”。
1. 用户自主性:点对点支付与自金融模式。Libra 采用的是全新的价值交换技术——区块链技术,进行点对点支付,而支付宝则是围绕传统商业银行的各类账户或者自有的虚拟账户,通过一层层中心化系统的转接清算,来完成支付。支付宝的数据传输过程加了密,不代表它就是加密货币。加密货币的核心要义在于,通过加密技术与经济激励相容设计的结合,基于技术中立构建分布式互信体系,实现价值的点对点交换。
其最大的特点是用户的自主性,私钥本地生成,非常隐秘,从中导出公钥,再变换出钱包地址,自己给自己开账户,不需要中介,公私钥体系取代了商业银行的账户体系,这在金融史上是一个非常重大的变化:
一是用户可通过数字身份运用安全技术对金融资产进行自主控制,有助于实现纯线上的金融服务,改变线上线下两层皮的状况,提升用户体验;
二是用户之间点对点之间进行金融资产交易,可以独立于任何第三方服务机构,降低成本,提升效率;
三是用户对数字身份的保管,直接承担交易责任,自金融商业模式应运而生,或将对现有的金融服务模式带来直接冲击;四是用户隐私得到了极大的保护,欧洲实施 GDPR 给金融机构带来了很大的触动,再结合国内最近频发的聚合支付风险事件,基于密码学的隐私保护是未来金融机构投入的重点领域。
在自金融模式下,客户对自己的资金、资产甚至是交易行为有着极大的掌控力,不再被捆绑于银行以及第三方支付机构,个人能动性大幅加强,这是一个全新的赛道,长期来看或将对支付宝、微信支付等第三方支付机构,Swift、Visa、银联、网联等转接清算机构,银行电子渠道,大数据征信机构等带来较大冲击,这也是为何 Libra 白皮书出来之后众多机构关注的原因之一。
2. 金融普惠性:成本潜力与自由开放。目前的支付体系为了满足多主权货币以及区域性监管的要求,建设多层次账户系统以及相应的信息传输专用通道,成本耗费巨大,尤其是跨国支付,比如 Swift,专网建设,运营成本较高,这种以区域为边界的系统割裂局面导致金融服务费用和门槛高企,金融发展严重不平衡,损害金融普惠。
诚如 Libra 白皮书所言:“当被问及为什么仍然徘徊在现行金融体系的边缘时,那些仍‘未开立银行帐户’的人往往指出:没有足够的资金,各种不菲且难以预测的费用,银行距离太远,以及缺乏必要的手续材料。”相较而言,加密货币省去了“铺路架桥”的费用,不受传统账户体系和封闭网络限制,直接复用现有的互联网基础设施,任何能连接互联网的人皆可参与其中,万物互联,开放自由,赋予任何参与方技术上的对等性。
Libra 白皮书着重强调了区块链技术的普惠金融意义,“希望创造更完善、更实惠的开放式金融服务,人们不论身份、地位、不论职业、不论贫富,均可享受这种服务”。目前基于中本聪共识的支付效率没有那么高,为此,Libra 对性能与开放性做了平衡处理。它没有采用原教旨主义的工作量证明机制(PoW),而是采用改良版的拜占庭容错共识机制(LibraBFT-Hotstuff)。
与 PoW 共识机制相比,BFT 具有效率高、吞吐量大等优势,且不使用工作量证明的耗电模式,节能环保。但 BFT 容错性只有三分之一,要求的节点数量也不能太多,通常是几十个,同时节点需要选举或者许可,不像 PoW 节点那样可以自由加入,因此可扩展性和开放性有所降低。
Libra 采用许可链,实体通过权限授予方式,运行验证者节点。Facebook 邀请第三方机构作为“记账节点”,需缴纳至少 1000 万美金,普通用户使用终端轻钱包不参与共识没有抵押责任。Libra 白皮书提出,未来可能成为非许可型网络,届时的共识机制或将随之发生变化。
3. 用户隐私保护。在支付宝等传统中心化模式下,处于中心节点的数据控制者对于数据具有强大的控制力,而普通个人却无法完全控制自己的数据,中心节点容易滥用用户数据,不仅如此,个人数据大规模集中,极易成为被攻击的目标,一旦爆发风险,对个人和平台的危害巨大。Facebook 就曾经发生过 5000 万用户数据泄露事件。
而区块链技术创造了一种全新的不依赖中心、多方共享环境下、基于密码学、用户自主可控的隐私保护新模式:数据不集中存储于第三方机构,用户自主可控地对个人数据匿名化,无需让渡数据权利。数据可向哪些人透明?透明到什么程度?可否被追踪?这些都可以由用户自主掌控。Libra 采用区块链技术方案,增强了数据隐私保护,在一定程度上可降低公众对 Facebook 数据隐私保护的批评和质疑。

Libra 与传统金融基础设施:竞争,还是合作?

Libra 白皮书剑指金融基础设施,开篇明义:“Libra 的使命是建立一套简单的、无国界的货币和为数十亿人服务的金融基础设施”。那么,Libra 是对现有金融基础设施的替代,还是补充?是竞争,还是合作?
1. 价值内涵上的合作:类稳定代币。目前看,以比特币为代表的虚拟货币仍无法有效履行计价单位、交易媒介和价值储藏三大货币基本职能(当然,许多虚拟货币拥蹙者、自由主义者和无政府主义者在主观上依然坚持虚拟货币可以颠覆法币,但客观上虚拟货币确实难以成为社会公众广泛接受的货币),根本原因在于价值不稳定。针对这一问题,价值“锚定”法定货币的数字稳定代币成为潮流。一种方式是虚拟货币的主动对接。
2018年9月,纽约州金融服务局(NYDFS)批准了两种受政府监管并锚定美元的数字稳定代币:Gemini Dollar(GUSD)和 Paxos Standard Token(PAX)。监管的介入使稳定代币对法币的价值锚定得到增信。另一种方式是传统金融机构发行数字结算币。2019 年 2 月,美国摩根大通推出使用区块链技术进行即时支付的数字货币 JPM Coin,JPM Coin 与银行存款 1:1 兑付。
在价值内涵上,Libra 主动与现有银行体系挂钩,采用了类稳定代币的模式,盯住一篮子货币和低风险资产。Libra 白皮书提出,创造新的 Libra 币,必须使用法定货币按 1:1  比例购买 Libra,并将该法定货币转入储备。储备将投资于低风险资产,获得投资收益。收益将首先用于支付协会的运营开支,包括:为生态系统的成长与发展投资,资助非政府组织,以及为工程研究提供资金等等。支付这些费用后,剩余的一部分收益将用于向 Libra 的早期投资者支付初始投资的分红。
从这角度看,Libra 与现有金融体系是合作关系,其价值基础来源于在现有金融体系的投资收益。倒过来看,Libra 亦可看作是现有金融体系的延伸安排。某种意义上,银行存款其实是央行货币的“稳定代币”。首先,银行存款虽具有支付功能,但没有计价功能。它们以央行货币计价,最终以央行货币偿付,事实上它们是央行货币的一种延伸性支付安排,是央行货币的“代币”。其次,通过存款准备金、存款保险、最后贷款人、隐性担保等制度安排,银行存款与央行货币维持平价锚定。
所以,数字稳定代币在价值锚定银行存款的同时,也锚定了央行货币。或许可以这么说,数字稳定代币是央行货币的“稳定代币”的“稳定代币”。从货币层次看,央行货币是 M0 层次,银行存款等传统信用货币在 M1 和 M2 层次,而 Libra 等数字稳定代币则是在更高的货币层次。如果 Libra 挂钩美元,它就是美元货币体系的延伸安排。从白皮书看,Libra 挂钩的尽管是一篮子货币,但这一篮子货币当中,美元很可能唱主角。
2. 金融模式上的竞争:自金融模式。Libra 采用区块链技术架构和智能合约平台,意味着它可以“嫁接”目前所有的金融业务模式,包括存贷汇、证券通证发行 STO、数字资产发行、中心化/去中心化资产交易等,从而与传统金融模式形成竞争。
一是货币替代。Libra 作为一种全新跨主权稳定代币,可被视为新一代 SWIFT,在支付功能上,或将对现有的支付体系形成替代,因此有人担忧 Facebook 和美联储合作,将 Libra 与美元挂钩,借助 Facebook 高达 27 亿的用户和全球生态体系,可摧毁或取代各国的支付体系。
二是不同的金融生态。传统上,直接金融市场和间接金融市场“泾渭分明”,分割程度较高,而 Libra 集各种金融模式为一体,既做存、贷、汇,同时又自带交易场所,并横跨国界,或将创造完全不同于传统的金融生态。
三是激活边缘资产。通过数字化,各类之前不可或难以流转的边缘资产(比如知识产权、收益权等)都能在 Libra 的生态网络上流转起来,同时用户在生产数据的同时,也在创造自己的数字资产,为创新性数字金融服务提供新型底层资产。

Libra 与央行数字货币:公权与私权的对立统一

Libra 与当前的央行数字货币研发代表了两种模式:私人部门创新和公共部门创新。两者各有优劣:公共部门有资源和信用上的优势,但创新动力和能力不足,而私人部门的创新动力和能力较强,公共精神却略显不足。最好的方式或许是公私合营,政府信用加市场创新,但很可能优势没有互补,劣势反而叠加。所以如何做到公权与私权的激励相容是最大的挑战。
此次 Libra 发行也触动了各国央行的神经。有人将其看作是 SDR 和 SWIFT 的合体,对主权货币形成了挑战。甚者有人认为,Libra 将可能成为超主权信用货币。实际上,这种可能性不高。Libra 虽然看起来和 SDR 一样,锚定一篮子货币,但锚定一篮子货币并不一定能成为 SDR。SDR 的本质其实是一种货币兑换权利:会员国在发生国际收支逆差时,有权用它向基金组织指定的其他会员国自由换取外汇。而 Libra 并没有这种机制保障,它可能会在支付功能上对国际货币形成替代,但在价值储藏上并不一定能成为国际储备货币。
某种意义上,Libra 的发行凸显了这么一个事实:央行数字货币的研发绕不开央行加密货币(CBCC)。如前所述,Facebook 没有简单模仿支付宝,而是推出了 Libra,说明了其对加密货币潜力和趋势的高度认可。由于第三方支付的异军突起,我国的帐户体系走在世界前列,但实际上,从全球来看,无论是学术界,还是业界,无论是私人部门的创新,还是公共部门开展的法定数字货币试验,真正代表未来技术发展方向的数字货币很可能是基于加密货币技术的数字货币。
央行加密货币(CBCC)可以让客户真正自主管理自己的货币、资金和资产,而不是托付给第三方,真正赋予客户自主掌控的能力,目前看,应是最热的前沿焦点。
从公开资料看,我国央行的研究起点就是 CBCC。姚前(2016)曾强调:“我们需充分吸收借鉴国际上先进成熟的知识和经验,深入剖析数字货币的核心技术。一方面,从理论入手,梳理国内外学术界对密码货币的研究成果,构建中国法定数字货币的理论基础;另一方面,从现实入手,对运营中的各类典型电子与数字货币系统进行深入分析,博采众长,构建中国法定数字货币的基础原型。”
姚前提出的 CBCC,其核心要素可概括为“一币、两库、三中心” 。在技术上,它利用分布式账本不可篡改、不可伪造特性,构建了一个 CBCC 确权账本,对外通过互联网提供查询服务。这种设计一方面将核心的发行登记账本对外界进行隔离和保护,同时利用分布式账本优势,提高确权查询数据和系统的安全性和可信度;另一方面,由于分布式账本仅用于对外提供查询访问,交易处理仍由发行登记系统来完成,有效规避现有分布式账本在交易处理上的性能瓶颈 。同时,它还采用了“总/分双层账本结构”,既减轻了中央银行压力,又保障中央银行的全局掌控能力 。
与其相比,Libra 在技术平台、发行方、可追溯性、匿名性、与银行账户耦合程度、是否支持资产发行等方面存在差异,相同点在于:一是均采用了加密货币技术,技术路线一致;二是均进行了分层,Libra 白皮书提出,客户不直接接触储备,协会授权经纪商开展 Libra 买卖,不过具体账本如何设计,尚需更详细的材料剖析。

Libra 与政府监管:私人部门的公共治理

在数字资产的世界里,数字法币的缺失是问题的根本,数字稳定代币的出现正是这一症结的体现。为维持“数字稳定代币、银行存款、央行货币”整个货币链条的价值平价锚定及其可信,中央银行或相关监管部门必须承担相应的监管任务、压力和成本。对于 Libra 而言,首要的监管焦点在于储备资产如何托管?如何保障 Libra 持有者的权益。
其次,Libra 具有多重属性,它通过 STO 的方式向每一家加入该协会的机构筹集总计 10 亿美元的初始资金,对于这一行为,不同司法管辖区有不同判定,比如,美国 SEC 倾向认为是证券发行。Libra 白皮书也强调,需要与政府监管机构合作,争取批准创建和发行这种货币。同时 Libra 作为支付工具,用于交易流转,需要获得各司法管辖区的支付牌照,接受客户识别(KYC),反洗钱(AML)监管等。
Libra 本身的一些特性将带来监管上的难题和挑战:一是模糊了“离岸”与“在岸”的边界,对跨境资本流动管理框架形成冲击;二是小额、分散、高频的特点,提高了资金监测的难度;三是匿名性、去中介化、弱实名等特征,对监管提出了更高的要求;四是引入 STO 资产发行的方式,对传统企业与高成长科创企业都具有一定的吸引力,也对监管提出了新的挑战;五是超主权生态体系带来的数据开放与价值的高流动性,对现行的法律框架也带来了很大的冲击。近期,法国央行行长表示,该国正在设立一个 G7 特别工作组,研究中央银行如何确保像 Libra 这样的加密货币受到各种法规的监管。

Libra 发展的四个不确定

1. 流通范围能否出生态圈。Libra 的区块链是 Facebook 主导的联盟链,成员虽然囊括了 Paypal、Visa、万事达、Coinbase 等知名公司,并接入现有金融基础设施和基础制度,但本质上仍然是商圈币,流通范围是否能超越生态圈,有待观察。
2. 能否充分发挥出 27 亿用户的潜力。Libra 的白皮书提出,Facebook 创立受监管的子公司 Calibra,以确保社交数据与金融数据相互隔离,同时代表其构建 Libra 网络系统并提供服务。一旦 Libra 网络发布,Facebook 及其关联机构将与其他创始人享有相同的权利并承担相同的义务和责任。也就是说,Libra 与 Facebook 是两个不同网络,运营实体也不一样。Facebook 的 27 亿用户是否能直接移植到 Libra 网络,涉及用户隐私保护与商业应用之间的平衡,需要做到社交数据与金融数据的合理有效分隔和良性互动,如何实现有待观察。
3. 如何解决客户“挤兑”问题。与 1:1 兑付的摩根币(同数量的银行存款是摩根币的备付金,得到存款保险制度保护)不一样,Libra 发行后筹集的储备资产将投资于一篮子货币和债券,它在很大程度可视为既可交易,又可用于支付的货币基金份额。尤为关键的是,Libra 白皮书仅规定了储备资产投资收益的分配:归初始会员所有,普通持有者不能享受这一收益,但没有规定如果储备资产投资亏损了,由谁来填补和兜底,普通持有者的权益如何保障?甚至白皮书没有明确规定客户赎回资金的具体程序和相应价格,应对极端情况下用户“挤兑”的机制和措施也不明确。
4. 各国的监管态度。Libra 的支付牌照、STO 发行、KYC、AML/CTF、数据隐私保护、货币兑换、资金跨境流动均需受到各国监管部门的规制,监管上的不确定性将极大影响着它的未来发展。另外,Libra 的跨国流通和交易使单一国家的监管不容易生效,尚需多国响应,协同监管。

结语与启示

有一种推测是美元战略正在从以纽约为全球金融中心的单核模式向以纽约与硅谷为核心的线上线下全覆盖双核模式切换。毋庸置疑,Libra 将会对中国支付体系及相关清算机构产生重大影响。如果国内市场对其开放,那么将带来直接冲击;即便挡在墙外,Libra 也会在国际市场与“走出去”的国内机构展开竞争。
无论如何,Libra 的出现,揭示了加密货币技术强大的爆发力,数十亿量级用户和加密货币技术的结合,不仅会影响全球支付体系与资金流动,同时还可能重构整个金融生态,创建全新的数字金融模式,值得我们高度关注。尤其是,加密货币俨然成为了一种不可阻挡的技术趋势,无论是支付宝、腾讯支付等私人部门,还是研发法定数字货币的公共部门,抑或是相关监管部门,都应严肃正视这一事实。
经济是躯体,金融是血脉。数字经济的发展离不开数字金融与数字技术的探索进步。在我国,虚拟货币的名声似乎不佳。但加密货币不见得一定就是虚拟货币,所以一定要把这两者区分开来,要把脏水泼掉,把婴儿抱起。
相比支付宝和微信支付,加密货币的技术门槛显然要高出一筹。我们不应“抱残守缺”,止步于支付宝模式,更不应“画地为牢”,仅局限于数字 M0 的探索,禁止商业机构的加密货币试验。与数字 M0 相比,M1、M2…Mn 等高层次货币的数字化更具有想象空间,更有意思。
为创新考虑,也为未来考虑,学界业界应摒弃成见,深入研究加密货币,并在征得监管部门理解和支持的基础上,开展沙箱实验。这样一个众所瞩目的阵地,我们不应不做准备,轻言放弃。

Libra 区块链技术白皮书(中文版)

Libra 区块链

白皮书作者:Zachary Amsden, Ramnik Arora, Shehar Bano, Mathieu Baudet, Sam
Blackshear, Abhay Bothra, George Cabrera,Christian Catalini, Konstantinos
Chalkias, Evan Cheng, Avery Ching, Andrey Chursin, George Danezis,Gerardo Di
Giacomo, David L. Dill, Hui Ding, Nick Doudchenko, Victor Gao, Zhenhuan Gao,
François Garillot,Michael Gorven, Philip Hayes, J. Mark Hou,Yuxuan Hu, Kevin
Hurley, Kevin Lewi, Chunqi Li, Zekun Li, Dahlia Malkhi,Sonia Margulis, Ben
Maurer, Payman Mohassel, Ladi de Naurois, Valeria Nikolaenko, Todd Nowacki,
Oleksandr Orlov,Dmitri Perelman, Alistair Pott, Brett Proctor, Shaz Qadeer,
Rain, Dario Russi, Bryan Schwab,Stephane Sezer,Alberto Sonnino, Herman Venter,
Lei Wei, Nils Wernerfelt, Brandon Williams, Qinfan Wu, Xifan Yan, Tim
Zakian,Runtian Zhou*
翻译:巴比特资讯 (洒脱喜,Kyle)

摘要

Libra 区块链是一个去中心化、可编程的数据库,其旨在支持一个低波动性的加密货币,能够作为服务全世界数十亿人的有效交易媒介。我们提出了一个关于 Libra 协议的提议,它会实现 Libra 区块链,旨在创建一个可促进创新、降低进入壁垒,并改善访问金融服务机会的金融基础设施。为了验证 Libra 协议的设计,我们已构建了一个开源原型实现
—— Libra Core ,并在全球范围内共同推进这一新生态系统。
Libra 协议允许来自不同实体的一组副本(称为验证者)共同维护一个可编程资源的数据库。这些资源由经过公钥加密验证的不同用户帐户拥有,并遵守这些资源开发者指定的自定义规则。验证者处理事务(transaction)并相互作用,就数据库的状态达成共识。事务是基于预定义的,在未来的版本中,用户自定义的智能合约会使用一种称为 Move 的新编程语言编写。
我们使用 Move 语言定义区块链的核心机制,例如货币和验证者会员。这些核心机制能够创建一个独特的治理机制,其建立在现有项目早期已建立的稳定基础之上,但 Libra 系统会随着时间的推移,完全开放。
(图片来自: Libra.org)

一、引言

互联网的普及以及由此产生的产品和服务的数字化,提高了效率,降低了进入壁垒,降低了大多数行业的成本。这种连通性已通过让更多的人进入金融生态系统,而驱动了经济赋权。尽管如此,对于那些最需要金融服务的人来说,获得金融服务的机会仍然有限,这是由成本、可靠性以及无缝发送资金的能力影响的。
这篇技术论文为 Libra 协议提出了一个提议,旨在支持这个新生的
Libra 生态系统,并解决这些挑战,扩大资本准入,并作为创新金融服务的一个平台。这个生态系统将提供一种新的全球货币 ——
Libra 币,它将由优质的中央银行一篮子银行存款和国债充分支撑。
这些基准货币都经历了相对较低的通货膨胀,因此,Libra 稳定币继承了这一属性,且其还拥有在地理上呈现多样化的组合优势。Libra 协议必须扩展,以支持其货币成长为一个全球金融基础设施,提供以实施经济和治理的灵活性,支持其操作策略。Libra 协议的设计从一开始就以整体解决这些需求,它建立在现有项目以及研究的基础之上。Libra 结合了新颖的方法以及已被广泛理解的技术。
金融服务业健康竞争和创新的一个关键前提,是依靠处理事务、维护账户以及确保跨服务和组织的互操作性公共基础设施。通过降低进入壁垒和转换成本,Libra 协议将使初创企业和现有大型企业能够在公平竞争的环境中竞争,并试验新的商业模式和金融应用。区块链技术能够很好地解决这些问题,因为它可以用于确保没有单个实体能够控制生态系统或可单方塑造其进化优势 [2]。
Libra 区块链将是去中心化的,它由一组共同工作的验证者组成,用于处理事务并维护区块链的状态。这些验证者也构成了 Libra 协会的成员,这将为网络的管理以及支持货币的储备提供一个框架。最初,该协会(验证者)将由一组地理分布广泛的创始成员组成。这些成员是根据客观参与标准选择出来的,包括它们在引导 Libra 生态系统和为其成功而投入的权益。随着时间的推移,成员资格将转变为完全开放,只基于 Libra 的持有量。Libra 协会已发表了报告,概述了其愿景 [1]、提议的结构 [3]、货币的经济学 [4] 以及向无许可系统转变的路线图 [5]。
而本文,则是构建支持 Libra 生态系统的技术基础设施的第一步。
我们发布这份早期报告,是为了征求社区对 Libra 的初步设计、系统的发展计划以及当前未解决的研究挑战的反馈意见。因此,协会建立了一个开放源码社区 [6] 以供大家讨论以及支持项目的开发。
Libra 协议。Libra 区块链是使用 Libra 协议进行维护的密码学证明数据库 [7, 8,
9]。该数据库存储了一个可编程资源(例如 Libra 币)的账本。资源(resource)遵循其声明模块指定的自定义规则,该模块还存储在数据库中。资源由使用密码学公钥进行验证的帐户拥有。帐户可代表系统的直接最终用户以及实体(例如托管钱包),代表他们的用户。帐户的所有者可签署对帐户内的资源进行操作的事务(transaction)。
图 1 显示了使用 Libra 协议进行交互的两种类型的实体:(1)验证者,其负责维护数据库,(2)客户端,它们对数据库执行查询,并提交事务以修改它。
图 1:Libra 协议的纵览图
验证者维护这个数据库,并处理由包含在数据库:
(1)的客户端提交的事务(transaction)。验证者使用一个分布式共识协议来商定不断增长的,已提交到数据库的事务列表,以及执行这些事务的结果。即使少数验证者存在恶意或错误,此共识协议也必须是可靠的。验证者轮流驱动接受事务的过程。当验证者充当领导者时,它会向其他验证者
(2)提出客户端直接提交给它的事务,以及通过其他验证者间接提交的事务。所有验证者执行事
(3)并形成一个经验证的数据结构,其中包含新账本历史记录。作为共识协议
(4)的一部分,验证者对该数据结构的确认者进行投票。作为在版本 i 提交一个事务 ti 的一部分,共识协议在版本 i 输出数据库完整状态的签名(包括整个历史),以确认对来自客户端
(5)查询的响应。
客户端可以向验证者发出查询,以从数据库中读取数据。由于数据库是经验证的,因此可保证客户端对其查询的响应的准确性。作为对读取查询的响应的一部分,验证者返回验证者已知数据库最新版本 i 的签名验证器。
此外,客户端还可以选择通过与验证者同步事务历史,来创建整个数据库的副本。在创建副本时,客户端可检查验证者是否正确执行了事务,从而改善了系统的问责制和透明度。其他客户端可以从保存副本的客户端读取副本,这和从验证者处读取副本以验证响应真实性的方式相同。
为了简单起见,本文的其余部分假设客户端直接查询一个验证者,而不是副本。
组成(Organization)。本文讨论了 Libra 协议的组成部分:
  1. 逻辑数据模型 :(第 2 节)描述了逻辑数据模型,该模型组织了对验证者和客户端可见的去中心化数据库。
  2. 执行事务:(第 3 节)描述了 Move [10] 编程语言的使用,这是一种用于定义和执行数据库事务的新编程语言。
  3. 经验证的数据结构和存储:(第 4 节)描述了基于 Merkle 树的逻辑模型到经验证数据结构的映射 [11]。
  4. 拜占庭容错共识:(第 5 节)描述了 HotStuff 协议 [13] 的变体 LibraBFT [12],允许具有潜在恶意验证者的网络,通过执行 Move 语言事务,并在使用经验证的数据结构执行事务时达成一致,来维护一个单一的、一致的数据库。
  5. 网络:(第 6 节)描述了使验证者能根据协商一致的需要,安全地相互通信的协议。
而在之后,我们展示了开源的 Libra Core 原型 [6]。第 7 节内容则讨论了 Libra Core 如何结合了 Libra 协议的组件来处理事务。
第 8 节内容则探讨了性能考虑。
最后,我们将解释如何使用该协议来支持 Libra 生态系统政策的经济稳定和治理。
第 9 节内容展示了我们如何使用 Move 语言来实现低波动性、储备支撑的 Libra 货币,以及反映 Libra 协会治理的验证者管理系统。
第 10 节内容,讨论了有关 Libra 生态系统的未来计划,及其当前正面临的挑战,这也将是这篇文章的结尾。

二、逻辑数据模型

Libra 区块链中的所有数据都存储在单一版本的数据库当中 [14,
15]。版本号是与系统已执行的事务数相对应的无符号 64 位整数。在每个版本 i 中,数据库都包含一个元组 (Ti, Oi, Si) ,它们分别表示事务
(Ti),事务输出(Oi)以及账本状态
(Si)。给定一个确定性执行函数 Apply,这个元组的含义是:对账本状态 Si−1 执行事务 Ti 会产生输出 Oi 以及新账本状态 Si,即 Apply(Si−1,
Ti) → ⟨Oi, Si⟩。
Libra 协议使用 Move 语言来实现确定性执行函数(请参见第 3 节内容)。在本节内容中,我们将重点介绍版本化数据库,它允许验证者:
  1. 根据最新版本的账本状态执行事务;
  2. 响应客户端有关当前和以前版本的账本历史记录的查询;
我们首先解释存储在单个版本中的账本状态的结构,然后讨论版本化账本历史视图(History view)的目的。

2.1 账本状态

账本状态代表了有关 Libra 生态系统的基本事实,包括每个用户在给定版本中持有的 Libra 币的数量。每个验证者必须知道最新版本的账本状态,以便执行新的事务。
Libra 协议使用基于帐户的数据模型 [16] 对账本状态进行编码。状态被构造为一个键值存储,它将帐户地址键映射到帐户值。账本状态下的账户值是已发布 Move 资源和模块的集合。这个
Move 资源存储数据值,而模块则存储代码。初始帐户集及其状态在创始账本状态中指定(见第 3.1 节)。
帐户地址:帐户地址是一个 256 位的值。要创建新帐户,用户首先为签名方案生成一个新的验证 / 签名密钥对 (vk,
sk),并使用公共验证密钥 vk 的加密哈希作为帐户地址 a = H(vk)。当从现有账户发送的事务调用这个 create_account(a)
Move 指令时,则这个新账户就会在账本状态中创建。这通常发生在一笔事务尝试将 Libra 发送到尚未创建的地址 a 的帐户时。
在地址 a 中创建新帐户后,用户可使用私人签名密钥 sk,签署要从该帐户发送的事务。该用户还可以在不更改其地址的情况下,更改用于签署交易的密钥(例如,主动更改密钥或响应密钥可能被盗的情况)。
Libra 协议不会将帐户链接到用户的真实身份(即没有 KYC)。用户可通过生成多个密钥对来自由创建多个帐户。由同一用户控制的帐户没有固有的相互联系。该方案参照了比特币和以太坊,为用户提供了假名性

(又称半匿名)[19]。

资源值:所谓资源值或资源,是将命名字段绑定到简单值(例如整数或复杂值)的记录。
(脚注 1: 具体地说,我们使用 SHA3-256 [17] 实例化哈希函数,并使用 edwards25519 曲线 [18] 实现 EdDSA 数字签名)
图 2:具有四个帐户的账本状态示例。
在这个图中,椭圆表示资源,矩形表示模块。从资源到模块的定向边,意味着该模块声明了资源的类型。地址为 0x12 的帐户,包含由货币模块声明的 Currency.T 资源。该货币模块的代码存储在地址 0x56。地址 0x34 处的帐户,同时包含了一个 Currency.T 资源以及 StateChannel.T 资源,这是由存储在地址 0x78 的模块声明的。
每个资源都有一个由模块声明的类型。资源类型是名义类型 [20] ,其由类型的名称和资源的声明模块的名称和地址组成。例如,图 2 中的
Currency.T 资源的类型是 0x56.Currency.T. 这里,0x56 是存储货币模块的地址,Currency 是模块的名称,而 Currency.T 则是资源的名称。
要在帐户地址 0x12 取回资源 0x56.Currency.T,客户端将请求 0x12/resources/0x56.Currency.T.
这种设计的目的,是让模块为顶级帐户值定义一个可预测的模式——也就是说,每个帐户都将其 0x56.Currency.T 资源存储在同一路径下。因此,每个帐户最多可存储一个给定类型的资源。但是,这一限制是没有约束的,因为程序员可定义包装器(wrapper)资源,以自定义的方式组织资源。(例如,resource
TwoCoin { c1: 0x56.Currency.T, c2: 0x56.Currency.T })。
用于改变、删除和发布资源的规则,编码在创建资源并声明其类型的模块当中。
Move 的安全和验证规则,会阻止其他代码对资源进行修改。
模块值:所谓模块值或模块,包含声明资源类型和程序的 Move 字节码(更多细节见第 3.4 节)。与资源类型一样,模块由声明模块的帐户地址识别。例如,图 2 中 Currency 模块的标识符是 0x56.Currency。
模块必须在一个帐户中唯一命名,每个帐户最多只能声明一个具有给定名称的模块。例如,图 2 中地址 0x56 处的帐户无法声明另一个名为 Currency 的模块。另一方面,地址为 0x34 的帐户可以声明 Currency 的模块。此模块的标识符将为 0x34.Currency。注意,0x56.Currency.T 和 0x34.Currency.T
是不同的类型,它们彼此不能互换使用。
在当前版本的 Libra 协议中,模块是不可变的。一旦在帐户地址下声明模块,就不能修改或删除它,除非通过硬分叉的方式。我们正研究在未来的版本中启用安全模块更新的方案选项。

2、2 事务(Transactions)

Libra 区块链的客户端是通过提交事务来更新账本状态的。从高维度来讲,事务由事务脚本(以 Move 字节码编写)和事务脚本的参数(例如,接收方帐户地址或要发送的 Libra 币数量)组成。验证者通过运行脚本及其参数和当前账本状态作为输入来执行事务,以生成完全确定的事务输出。在共识(第 5 节)期间,通过同意对事务输出的约束性承诺(第 4 节),在事务被承诺之前,账本状态不会改变。
我们将在第 3 节中更详细地讨论事务的结构和执行。
事务输出:执行一个事务 Ti 将生成新的账本状态 Si 以及执行状态代码、gas 使用量以及事件列表(汇总在输出 Oi 中)。执行状态代码记录了执行一个事务的结果(例如,成功、因错误 e 退出、gas 耗尽等)。
gas 使用,记录了执行事务时使用的 gas 单位数量(有关如何使用 gas,来管理与事务处理相关费用的详细信息,请参见第 3.1 节)。
事件(Events):事件列表,是由执行事务时产生的一组副作用(2)。Move 代码可通过一个事件结构触发事件。每个事件都与一个唯一的 key 相关联,它标识事件发出的结构,以及提供活动详细信息的有效载荷。一旦按照共识协议提交了事务,事务生成的事件将添加到商定的账本历史记录中,并提供成功执行事务导致特定效果的证据。例如,一笔付款交易会发出一个事件,允许接收方确认已收到付款并确认付款金额。
乍一看,事件似乎是多余的。相比通过一笔事务 Ti 查询事件,客户端可询问事务 Ti 是否包含在区块链中。但是,这很容易出错,因为包含 Ti 并不意味着成功执行(例如,gas 用完后可能会中断)。在事务可能失败的系统中,事件不仅提供了特定事务已执行的证据,而且还提供了它已以预期效果成功完成的证据。
事务只能生成事件-它们不能读取事件。这种设计允许事务执行仅为当前状态的函数,而不是历史信息(例如以前生成的事件)。

2、3 账本历史

账本历史记录存储已提交和已执行事务的序列,以及它们发出的关联事件。账本历史的目的,是为了记录最近的账本状态是如何被计算的。
账本历史中不存在一组事务的概念(3)。共识协议将事务批处理至区块,作为优化并驱动这一共识协议(有关共识的详细信息,请参阅第 5 节内容)。然而,在逻辑数据模型中,事务按顺序发生,而不会区分哪个区块包含每个事务。
(脚注 2: 事件的作用,类似于以太坊中的日志和事件概念 [16],然而,Libra 协议中的事件机制是完全不同的。
脚注 3: 这与比特币和以太坊相反,在比特币和以太坊中,区块和区块最大值的概念扮演着重要的角色。 )
尽管验证者不需要知道账本历史就可以执行新的事务,但是客户端可以对账本历史记录执行经验证的查询,并使用账本历史来审核事务执行。
响应客户端查询:验证者可使用账本历史来回答客户端关于以前账本状态、事务和输出的查询。例如,客户端可能会询问有关特定版本的账本状态(例如,在第 30 个版本的地址 x 的帐户余额是多少?),或者特定类型事件的历史(例如,Y 地址的账户在最后 20 分钟收到了哪些付款?)。
审核事务执行:客户端可通过重新执行历史记录中的每个事务 Ti,并将计算的账本状态与版本数据库中相应的账本状态 Si 和事务输出 Oi 进行比较,来检查账本状态是否正确。
此机制允许客户端审计验证者,以确保正确执行事务。

三、执行事务

在 Libra 区块链中,更改区块链状态的唯一方法是执行一个事务。
本节内容概述了事务执行的要求,定义了事务的结构,解释 Move 虚拟机(VM)如何执行一个事务,以及描述 Move 语言的关键概念。
在最初版本的 Libra 协议中,只有有限的 Move 功能子集可提供给客户端。虽然 Move 是用于定义核心系统概念,如
Libra 货币,但用户无法发布声明自己资源类型的自定义模块。这种方法允许 Move 语言和工具链在暴露给用户之前能够变成熟。这种方法还推迟了事务执行和数据存储中的可扩展性挑战,而它们正是通用智能合约平台所固有的问题。
正如我们在第 10 节中所讨论的,我们致力于通过 Move 语言来展示全面的可编程性。

3、1 执行要求

已知初始状态:所有验证者必须同意系统的初始或创始账本状态。
因为 Libra 区块链的核心组件(比如账户逻辑、事务验证,验证者选择以及 Libra 币)是由 Move 模块定义的,创始状态必须定义这些模块。创始状态还必须具有这些核心组件的足够实例化,以便事务可被处理(例如,至少有一个帐户必须能支付第一个事务;必须定义验证器集,以便集的法定数量的团体可对致力于第一个事务的确认者进行签名)。
为了简化系统的设计,系统的初始状态表示为空状态。然后通过定义特定模块的特殊事务 T0 创建创始状态,该事务定义要创建的特定模块和资源,而不是通过正常事务过程。客户端和验证者被配置为只接受以特定 T0 开头的账本历史记录,该 T0 是由其加密哈希标识的。
这些特殊事务不能通过共识协议添加到账本历史中,只能通过配置。(4)
确定性:事务执行必须具有确定性和密封性。这意味着事务执行的输出是完全可预测的,并且仅基于事务和当前账本状态中包含的信息。事务执行并不具有外部效应(例如与网络交互)。确定性和封闭性执行可确保多个验证者可以就同一事务序列产生的状态达成一致,即使事务是由每个验证者独立执行的。
这也意味着区块链的事务历史可从创始区块重新执行,以生成当前的账本状态(见第 2.3 节)。
计量:为了管理对计算能力的需求,Libra 协议收取以 Libra 币计价的交易费用(5)。这参照了以太坊普及的 gas 模型 [16]。
我们采用的方法,是选择具有足够容量的验证者来满足 Libra 生态系统的需求(见第 8 节内容)。这项费用的唯一目的,是在系统负载高于系统所提供承载能力时(例如,在遭到拒绝服务攻击)减少需求,系统的设计是,当其处于正常运行期间,当有足够的容量可用时,费用会是较低的。
这种方法不同于一些现有的区块链,这些区块链有时处理事务的需求会大于吞吐量。在这些系统中,费用会在出现高需求时激增,这是验证者的收入来源,但给用户造成了成本方面的问题。
费用的大小由两个因素决定:gas 价格和 gas 消耗。每个事务都规定了提交者愿意支付的每单位 gas 的价格(以 Libra 为单位)。事务的执行动态地说明了它以 gas 消耗的计算能力。当系统发生堵塞时,验证者会优先执行 gas 价格更高的事务,并可能放弃价格较低的事务。这就减少了在系统高负荷状态下,事务的发起需求。
此外,一笔事务还包含了一个最大 gas 量,它指定了提交者愿意以规定价格支付的最大 gas 单位数量。在执行期间,虚拟机会跟踪使用的 gas 单位数量。如果在执行完成前达到最大 gas 限制,虚拟机将立即停止。这种事务所导致的部分更改都不会提交给状态。但是,事务仍会出现在事务历史记录中,而发送者的账户仍然是要为使用的 gas 付费的。
正如我们在本节中讨论的,Libra 区块链核心逻辑的很多部分,是使用 Move 定义的,这包括 gas 费用的扣除。为了避免循环,虚拟机在执行这些核心组件期间禁用 gas 计量。这些核心组件必须在创始状态下定义。必须以防御性的方式编写,以防止恶意事务触发执行计算代价很高的代码。执行此逻辑的成本,可包括在为事务收取的基本费用中。
资产语义:正如我们在第 2.1 节中所解释的,账本状态直接对具有实际价值的数字资产进行编码。事务执行必须确保,在未经授权的情况下,不得复制、丢失或转让 Libra 币等资产。Libra 协议使用 Move 虚拟机(第 3.4 节)安全地执行事务以及具有这些属性的自定义资产。
(脚注 4:我们正在探索使用这种形式的特殊事务,来清晰地定义硬分叉的想法。客户端可指定
一种首选配置,声明类似的特殊事务(它对标准交易处理规则之外的模块和资源进行了特定的更改),应在第 i 版附加到账本历史当中。由于 Libra 协议的很多部分是使用 Move 语言表示的,所以这个类型的更新是可以表示出来的,但只需要对客户端软件进行配置更改。
脚注 5:在第 4.4 节中,我们讨论了管理存储容量需求的方法。 )

3、2 事务结构

所谓一笔事务,是指包含以下数据的签名消息:
  1. 发送方地址:即事务发送者的账户地址。虚拟机会读取序列编号、身份验证密钥以及存储在地址的 LibraAccount.T 资源的余额;
  2. 发送方公钥:与用于签署事务的私钥相对应的公钥。此公钥的哈希必须与发送方的 LibraAccount.T 资源存储的身份验证密钥匹配。
  3. 程序:要执行的 Move 字节码事务脚本、脚本输入的可选列表以及要发布的 Move 字节码模块的可选列表。
  4. Gas 价格:发送方愿意支付每单位 gas 的数量,以便执行此事务。
  5. 最大 Gas 量:事务中止前允许消耗的最大 Gas 单位数量。
  6. 序列号:一个无符号整数,必须等于发送方 LibraAccount.T 资源中的序列号。执行此事务后,序列号会增加 1。由于对于给定的序列号只能提交一个事务,因此无法重放事务。

3、3 执行事务

执行事务,是通过在虚拟机内执行六个步骤来实现的。执行独立于账本状态的更新。首先,执行一个事务,是试图就其顺序达成共识尝试的一部分。由于执行是封闭的,因此它不会造成外部副作用。随后,如果达成共识,则将其输出写入账本历史。
执行一个事务,会执行以下这 6 个步骤:
1、核对签名:事务上的签名必须与发送方的公钥和事务数据匹配。此步骤只是事务本身的一个作用,它不需要读取来自发送方帐户的任何数据。
2、运行 prologue:prologue 对事务发送方进行身份验证,确保发送方有足够的 Libra 币支付交易中规定的最大数量的 gas 单位,并确保该事务不是前一个事务的重播。所有这些检查,都是通过 LibraAccount 模块的 prologue 过程在 Move 语言中实现的。在 prologue 执行期间,Gas 计量是被禁用的。具体来说,这个 prologue 会做如下这些工作:
(1)检查发送方公钥的哈希是否等于发送方帐户下存储的身份验证密钥:如果没有这个检查,虚拟机将错误地接受具有密码学有效签名的事务,即使没有与帐户相关联密钥的通信。
(2)检查 gas_price * max_gas_amount <= sender_account_balance
:如果不进行此检查,虚拟机将执行可能在 epilogue 中失败的事务,因为它们将无法支付 gas 费用。
(3)确保事务序列号等于存储在用户帐户下的序列号:如果没有这项检查,恶意方可重放旧的事务(例如,Bob 可以重放 Alice 支付给他的 10 个 Libra 币的这笔交易)。
3、验证事务脚本和模块:一旦事务 prologue 成功完成任务,虚拟机将使用 Move 字节码验证器对事务脚本和模块执行良构的检查。在实际运行或发布任何 Move 代码之前,这个字节码验证器检查诸如类型安全
(type-safety)、引用安全(reference-safety,即没有悬空引用)和资源安全(resource-safety,即资源不会被复制、重复使用或意外销毁)等关键属性。
4、发布模块:事务的程序字段中的每个模块,都在事务发送方的帐户下发布。重复的模块名称是被禁止的,例如,如果事务尝试将名为 M 的模块发布到已包含模块名为 M 的账户中,则该步骤将会失败;
5、运行事务脚本:虚拟机将事务参数绑定到形式参数并执行事务脚本。如果此脚本执行成功完成,则脚本执行的写入操作和脚本发出的事件将提交给全局状态。如果脚本执行失败(例如,由于 gas 耗尽或 runtime 执行失败),则脚本中的任何更改都不会提交到全局状态。
6、运行 epilogue:最后,虚拟机运行事务 epilogue,向用户收取所用 gas 的费用,并增加发送方帐号序列号。就像 prologue 一样,这个事务 epilogue
是 Move
LibraAccount 模块的一个过程,且其是在禁用 gas 计量的情况下运行的。如果执行跃了步骤(2),包括步骤(3)、(4)或(5)失败,这一 epilogue 步骤也会始终运行。这个 prologue 步骤和 epilogue 步骤会一起工作,以确保在账本历史中的所有事务都是通过付费 gas 完成的。而不超过步骤(2)
的事务,不会被附加到账本历史。如果一笔事务超过了步骤(2),这个 prologue 步骤会确保账户拥有足够的 Libra 币以支付事务允许的最大 gas 单位数量。
即使事务用光了 gas,epilogue 步骤也可以按这个最大金额收取费用。

3、4 Move 编程语言

正如我们所看到的,一笔事务是围绕一个 Move 字节码程序,经证实的包装器(wrapper)。
Move [10] 是我们在设计 Libra 协议期间创建的一种新的编程语言,它在系统中扮演了三个重要的角色:
  1. 通过事务脚本启用灵活的事务;
  2. 允许用户定义的代码和数据类型,包括通过模块的“智能合约”;
  3. 支持 Libra 协议的配置和可扩展性(见第 9 节);
Move 语言的关键特点是能够定义自定义资源类型,这些类型是受线性逻辑 [21] 启发的。用于编码可编程资产的资源类型,其表现类似于普通程序值:
资源可以存储在数据结构中,作为参数传递给过程,等等。然而,这个 Move 类型系统为资源提供了特殊的安全保障。资源无法被复制,只能移动。此外,资源类型只能由声明该类型的模块创建或销毁。这些保证,都是通过 Move 虚拟机静态地强制执行的。这使我们能够在 Move 语言中将 Libra 币表示为一种资源类型(这与以太币和比特币是不同的,它们在各自的语言中具有特殊的地位)。
我们已发布了一份关于 Move
[10] 设计的更为详细的文章。在本节的其余部分内容中,我们简要地概述了用于事务执行的关键 Move 概念:开发 Move 事务脚本和模块,并使用虚拟机执行 Move 字节码。
编写 Move 程序。Move 程序有三种不同的表示形式:源代码、优化中间代码
(IR) 以及字节码。我们目前正在设计 Move 源语言,这将是一种符合人体工程学的语言,旨在使编写和验证安全代码变得容易。同时,程序员可以在 Move
IR 中开发模块和事务脚本。Move IR 足以用于编写人类可读的代码,它也可直接转换为 Move 字节码。未来的 Move 源语言和 Move
IR 都可以编译成 Move 字节码,而后者是 Libra 协议所使用的格式。
我们使用可验证的字节码作为 Move 的可执行表示,原因有两个:
  1. 上述安全保证必须适用于所有 Move 程序。执行这些编译器中的保证是不够的。恶意方总是可选择通过直接使用字节码编写恶意代码来绕过编译器(作为事务执行的一部分,运行编译器会使执行速度变慢和更复杂,并且需要验证者信任完整编译器代码库的正确性),因此,该协议通过字节码验证(类型安全、引用安全和资源安全)来强制 Move 的所有安全保证,从而避免了对编译器的信任。
  2. 与高级源语言相比, Move 基于栈的字节码指令更少。此外,每个指令都有简单的语义,可以通过更小的原子步骤来表示。这减少了 Libra 协议的规范足迹,并使得开发者更容易发现实现错误。
事务脚本:事务脚本是 Libra 协议的主要程序。事务脚本负责启用灵活的事务,因为脚本是一个任意的 Move 字节码程序。脚本可使用条件逻辑,以及执行本地计算,调用在账本状态下发布的模块的多个程序,这意味着脚本可执行富有表现力的一次性操作,例如为特定的一组接收者支付。
我们期望大多数事务脚本将执行一个包含通用函数的程序调用。例如,LibraAccount.pay_from_sender(recipient_address,
amount)
程序封装了执行一笔对等式支付的逻辑。以 recipient_address (接收方地址)和 amount (金额)为参数并调用此过程的事务脚本与以太坊中的以太币传输事务相同 [16]。
模块:模块是发布在账本状态中的代码单元。模块负责声明结构类型和程序。结构值包含可保存基元值的数据字段,例如整数或其他结构值。
每个结构必须标记为资源或不受限制(即非资源)。不受限制结构不受上述复制和销毁限制。但是,不受限制结构不能包含资源结构(直接或传递),并且不能在账本状态下的账户发布。
从高维度来说,模块 / 结构 / 程序的关系,类似于面向对象编程中的类 / 对象 / 方法的关系。但是,这里有一些重要的区别。一个模块可以声明多个结构类型(或零个结构类型)。在其声明模块之外不能访问任何数据字段(即,没有公共字段)。模块的过程是静态过程,而不是实例方法;过程中没有 this 或 self 的概念。Move 模块类似于没有高阶函数的有限版本的 ML 样式模块
[22]。Move 模块与以太坊和其它区块链平台的“智能合约”概念相关,但也有不同。一个以太坊智能合约包含了账本状态下发布的代码以及数据。而在 Libra,模块包含代码值,资源包含数据值。在面向对象术语中,以太坊智能合约就像是在单个帐户地址下发布的单例对象。模块是创建资源的方法,它可以创建任意数量的资源,这些资源可以在不同的帐户地址下发布。
Move 虚拟机:Move 虚拟机为 Move 字节码实现验证程序和解释程序任务。字节码以基于栈的虚拟机为目标,使用过程本地操作数栈和寄存器。非结构化控制流通过 goto 和标签(label)进行编码。
开发人员在 Move
IR 中编写事务脚本或模块,然后将其编译成 Move 字节码。编译将结构化控制流构造(例如,条件、循环)转换为非结构化控制流,并将复杂表达式转换为少量的字节码指令,以控制一个操作数栈。这个 Move 虚拟机通过验证然后运行这个字节码来执行一笔事务。
这个 Move 虚拟机支持少量类型和值:布尔运算(booleans)、无符号 64 位整数,256 位地址、固定大小字节数组、结构(包括资源)和引用。结构字段不能是引用类型,这将阻止在账本状态中存储引用。
这个 Move 虚拟机并没有堆(heap):本地数据在栈(stack)上分配,并在分配程序返回时释放。所有持久性数据必须存储在账本状态中。

四、经验证的数据结构和存储

在执行事务之后,验证者将对逻辑数据模型的更改,转换为用于表示数据库的已验证数据结构 [7、8、9] 的新版本。此数据结构的简短验证器是对账本历史的约束性承诺,其中包括新执行的事务。与事务执行一样,此数据结构的生成也是确定性的。
共识协议使用这个验证器来同意事务的顺序及其结果的执行(我们将在第 5 节内容详细讨论共识)。作为提交事务区块的一部分,验证者将短验证器集体签名至结果数据库的新版本。
使用这种集体签名,客户端可信任数据库版本代表数据库账本历史的完整、有效和不可逆状态。
客户端可查询任意验证者(或数据库的第三方副本)来读取特定的数据库值,并使用验证器以及简短的证明来验证结果。
因此,客户端不需要信任执行查询的一方,以确保结果读取的正确性。
Libra 协议中的数据结构基于 Merkle 树,并受到其他区块链的启发;但是,在某些情况下,我们做出了一些稍微不同的决定,下面我们会进行强调。首先,我们简要讨论创建验证器的 Merkle 树方法。然后我们描述经验证的数据结构,从数据结构的根开始,然后我们讨论其中的子结构。图 3 描述了数据结构,并提供了本节内容的可视化指南。
图片 3:
(1)账本历史结构的根哈希是系统完整状态的验证器,即(2)由法定人数验证者签署。当事务添加到数据库时,提交到账本历史的验证器(第 4.2 节)将增长(用虚线箭头表示)。账本历史的每个子叶都提交至一个(3) TransactionInfo 结构。此结构承诺(4)签署的事务(Ti),(5)该事务(Ei, 第 4.5 节)期间产生的事件列表,以及(6)该事务
(Si, 第 4.3 节) 执行后的状态。该状态是一颗稀疏 Merkle 二叉树,其中每个子叶上都有一个 (7) 帐户斑点。

4、1 认证数据结构的背景

认证数据结构允许验证者 V 控制一个简短的验证器 a,它对更大的数据结构 D 形成了约束承诺。一个不受信任的证明者 P,其控制了数据结构 D,计算 f(D) →
r 并向验证者返回 r (数据结构 D 上某些函数 f 的计算结果)以及π(正确计算结果的证明)。验证者 V 可以运行 Verify(a, f, r, π),当且仅当
f(D) =
r 时返回真(true)值。在 Libra 区块链的背景中,证明者通常是验证者,而验证者是执行读取查询的客户端。但是,客户端(即使只有部分数据库副本的客户端)也可以充当验证者,并为其他客户端执行经验证的读取查询。
图片 4: 一颗存储 D = {0 : s0, . . .}的 Merkle 树。如果 f 是获取第三项(用虚线显示)的函数,则 r = s2 ,π = [h3,
h4] (这些节点用虚线显示)。Verify(a, f, r, π) 会验证 a ? = H(h4∥H(H(2∥r)∥h3)).
Merkle 树 [11] 是一种常见的认证数据结构形式,其用于存储整数和字符串之间的映射。在一颗大小为 2^k 的 Merkle 树中,结构 D 将每一个整数键 i ∈
[0, 2^k) 映射到一个字符串值 si。
验证器由字符串创建的完整二叉树的根组成,将子叶标记为
H(i||si), 将内部节点标记为 H(left||right),其中 H 是一个加密哈希函数(我们称之为哈希)(6)。证明者希望验证的函数 f,是一个包含键值对

(k, v) 在映射 D 中的证明。

P 通过返回由节点 i 的每个祖先的兄弟姐妹的标签组成的证明π,来验证对 D 中项目 i 的查找。图 4 显示了对大小为 4 的 Merkle 树中项目 3 的查找。项目 3 的节点用虚线表示,π中包含的节点用虚线表示。
(脚注 6:
安全 Merkle 树必须使用不同的哈希函数,哈希子叶和内部节点,以避免两种类型的节点混淆。为了简单起见,我们在示例中省略了这个细节,而 Libra 协议使用了一种独特的哈希函数,用于区分不同的哈希函数类型,以避免基于类型混淆的攻击 [23]。)

4、2 账本历史

从比特币 [24] 开始的大多数区块链,用一个包含单个祖先哈希的区块,维护一个共识一致的每个交易区块的链接列表。
这一结构就导致了客户端效率低下。例如,信任某区块 B 并希望验证祖先块 B’ 中的信息的客户端,需要获取和处理所有的中间祖先区块。
Libra 协议使用单个 Merkle 树,为账本历史提供一个经验证的数据结构。图 3 解释了支持 Libra 数据库的完整数据结构,包括包含事务的账本历史,这些记录依次包含有关数据库状态、事件和帐户的信息。账本历史表示为一颗 Merkle 树,它将顺序数据库版本号 i 映射到一个 TransactionInfoi 结构。每个 TransactionInfoi 结构都包含一个已签名的事务
(Ti), 执行 Ti (Si,在第 4.3 节中讨论)后的状态验证器,以及 Ti (Ei, 在第 4.5 节中讨论)生成的事件验证器。
与其他 Merkle 树一样,这个账本历史支持 O(log n) 大小的证明(其中 n 是已处理的事务总数),以验证一个特定 TransactionInfoi 的查询。
当客户端希望查询版本 I 的状态,或查找在版本 I 中生成的事件时,它将使用包含的状态或事件列表验证器对 TransactionInfoi 执行已验证的查找。
具体来说,账本历史使用 Merkle 树累加器 [25,26] 方法来形成 Merkle 树,其还提供有效的附加操作。此操作很有用,因为可以通过将新事务附加到旧账本历史来进行递增计算。Merkle 树累加器还可以生成一个有效的证明,证明在给定验证器 a 提交到事务 I 之前的账本信息时,验证器 a′提交到账本信息最多
j > i 具有与事务 i 相同的历史。换句话说,这证明了 a 是 a′的前缀。这些证明可有效地验证一个账本历史承诺是另一个承诺的延续。
修剪存储:账本历史 Merkle 累加器的根哈希,是系统完整状态的验证器。它在系统的每个现有版本、发送的每个事务以及生成的每个事件上提交状态。虽然第 4.3 节中描述的状态存储允许有效地存储账本状态的多个版本,但验证者可能希望减少以前版本占用的空间。验证者可自由地删除旧状态,因为它们不是处理新事务所必需的。Merkle 树累加器支持修剪历史数据,其只需要 O(log
n) 大小的存储来附加新记录 [25]。
系统的任何副本都可以自由保留整个状态,并可以将其数据的真实性跟踪到由共识协议签名的根哈希。副本比验证者更易于扩展。副本不需要得到保护,因为它们不参与共识,可创建多个副本来并行处理读取查询操作。

4、3 账本状态

一个账本状态 Si 表示版本 i 中所有账户的状态,作为键值对的映射。密钥基于 256 位帐户地址,它们的对应值是账户确认者(在第 4.4 节中讨论)(7)。使用类似于图 4 的表示法,将映射表示为大小为 2^256
的一棵 Merkle 树,虽然一棵大小为 2^256 的树是一种难以处理的表示,但可以应用优化来形成一棵稀疏 Merkle 树。图 5 显示了两种用于将简单实现(1)转换为有效实现的优化方法。首先,完全由空节点组成的子叶将替换为证书透明度系统(certificate
transparency system) [27] 中使用的占位符值 ( 2 ) 。
这种优化创建了一个可跟踪大小的表示,而没有实质性地改变 Merkle 树的证明生成。然而,子叶总是存储在二叉树的底层,这意味着结构需要在每次子叶修改时计算 256 个哈希。第二种优化,用单个节点 (
3 ) 替换由一个子叶组成的子树。预期中,任何给定项的深度都是 O(log n),其中 n 是二叉树中项目数。这种优化减少了在映射上执行操作时要计算的哈希数。
(脚注 7:
地址的哈希作为密钥。即使地址是作为公钥的哈希,恶意方也可以在与真实地址几乎冲突的地址创建一个新帐户。虽然无法从此帐户发送任何事务,因为与该帐户地址对应的私钥未知,但树中存在此近似冲突,会增加邻近地址的证明长度。在将地址用作密钥之前对其进行哈希处理,可减少此类攻击的影响。)
图 5 : 一棵稀疏 Merkle 树存储 D = {01002 : A, 10002 : B, 10112 : C}的三个版本 有效实现,如 Libra
Core,可以优化它们的磁盘布局和节点的批处理层,以避免在查找过程中的请求。(8)
(脚注 8: 这种优化使磁盘性能与以太坊中使用的 16 元帕特里夏 Merkle 树方法相似,但其证明时间更短。)
当稀疏 Merkle 树在执行事务后更新时,新的树将重用上一版本的未更改部分,形成一个持久的数据结构 [28,29]。如果一个事务修改了系统中 n 个帐户中的 m 个帐户,则在与以前版本不同的新账本状态树中平均创建了 O(m
· log n) 个新分支和子叶。这种方法允许验证者有效地存储账本状态的多个版本。此功能还允许在处理事务后高效地重计算账本状态验证器。
我们考虑过基于 AVL 树结构,它比稀疏 Merkle 二叉树结构提供了更优的最坏情况证明长度 [30]。然而,稀疏 Merkle 树方法允许实现者进行优化,例如跨服务器共享存储以及并行根哈希计算。

4、4 账户

从逻辑层来讲,帐户是存储在帐户地址下的资源与模块的集合。从物理层来讲,帐户被视为字节数组值访问路径的有序映射。访问路径是一个分隔字符串,类似于文件系统中的路径。
在协议的第一次迭代中,我们将一个帐户序列化(serialize)为按访问路径排序的访问路径和值列表。帐户的验证器是此序列化表示的哈希。注意,此表示要求在对帐户进行任何修改之后,对整个帐户重新计算验证器。这个操作的开销是 O (n),其中 n 是完整帐户的字节表示长度。此外,从客户端读取,需要完整的帐户信息来验证其中的任何特定值。
我们在账户中存储数据的策略与其他系统(如以太坊)不同(9)。我们的方法允许 Move 语言通过将帐户表示为访问值路径的有序映射,以提供更好的编程抽象。这种表示允许 Move 通过虚拟机有效地管理资源的保护。Move 鼓励每个用户在他们自己的账户当中持有资源。在最初发布的 Libra 当中,我们针对小客户进行了优化。而在未来的版本中,我们可能会考虑支持更高效的结构来代表更大的账户,比如说 Merkle
AVL 二叉树结构 [30]。
(脚注 9:
相反,以太坊 [16] 使用 Merkle 树将数据存储为稀疏 memory 映射,该二叉树表示 256 位 key 到 256 位值的无序映射。这种方法使以太坊能够有效地处理大的账户。)
账户收回和重加工:我们预计,随着系统的使用,最终与帐户相关的存储增长可能会成为一个问题。正如 gas 鼓励负责任地使用计算资源(见第 3.1 节),我们预计存储可能需要一种租赁机制。我们正在评估最适合生态系统的租赁机制。我们讨论了一个可应用于任何确定过期时间的策略选项,在时间到期之后,数据就可以被收回。
在每个影响账户的事务执行之后,虚拟机计算逻辑过期时间,在该时间内,为帐户分配的存储可被释放。虚拟机可自由地应用任何确定性方法来确定到期时间。这种政策的一个例子是收取以 Libra 币计价的费用,该费用是基于账户的存储时间及其大小确定的。
帐户的验证器表示为 H(H(AccountBlob)||(ExpirationTime),它对帐户的过期时间进行编码。到期后,虚拟机拒绝访问帐户,从而引发一个错误。由于 AccountBlob 是不可访问的,因此在 ExpirationTime 之后,验证者可以自由删除此数据。然而,验证者允许事务在过期后通过重新计算其内容来重新激活帐户。该事务必须包含 AccountBlob 的预映射(preimage),并具有包含进一步存储成本的关联交易费用。通过重新计算和检查与帐户关联的哈希值(不删除)来确保重新获取内容的真实性。这种租赁实现方法是对现有帐户收回方案的改进,而现有方法要求第三方发送一个事务来删除帐户的存储。

4、5 事件

Ei 是 Ti 执行期间发出的事件列表,每一个事件都以一个子叶存储在 Merkle 树中,该二叉树 Ei 形成一个验证器。事件被序列化为 form (A, p,
c) 的一个元组,它表示发出事件(A)、数据有效负载(p)以及计数器值(c)的事件结构访问路径。这些元组按 Ti 执行期间发出的事件顺序 j 进行索引。根据惯例,我们把事件 j→(a,p,c)包含在 Ei 中,表示为
(j,(A, p, c)) ∈ Ei。Ei 的验证器包含在 TransactionInfoi 中,因此,验证者可构造一个包含证明,证明在第 i 个事务中,第 j 个事件是
(A, p, c)。
包含在每个事件中计数器 c,在允许客户端检索给定访问路径 A 的事件列表方面发挥了特殊作用。客户端也可以确保列表是完整的。在 Move 语言中,表示具有访问路径 A 的事件的事件结构,为其已发出的事件总数维护一个计数器 C。
此计数器存储在账本状态中,并在每次事务执行,在访问路径 A 上发出事件后进行递增。
客户端可获取最近账本状态的验证器,查询与事件结构关联的计数器以获取访问路径 A,并检索事件总数 C。
然后,客户端可以查询不受信任的服务,以获取访问路径 A 上的事件列表。查询响应由一组元组 (i, j, A, p,
c) 组成,每个元组对应一个事件,其中 i 是发出事件的事务序列号,j 是此事务中事件发出的顺序。可以为每个事件提供 (j,(A, p, c)) ∈
Ei 的关联包含证明。由于客户端知道访问路径 A 发出的事件总数,因此它们可确保不受信任的服务提供了此数量的不同事件,并按其序列号 0 ≤ c <
C 对其进行排序。这使客户端确信为 A 返回的事件列表是完整的。
此方案允许客户端保存对访问路径 A 上事件的已验证订阅。客户端可定期为事件访问路径 A 触发总计数器 C,以确定订阅是否是最新的。例如,客户端可使用它在监视的地址上维护对传入付款事务的订阅。不受信任的第三方服务可为按访问路径索引的事件提供源,而客户端可有效地验证返回的结果。

五、拜占庭容错共识

拜占庭容错共识协议允许一组验证者创建单个数据库的逻辑层次。这种共识协议在验证者之间复制提交的事务,对当前数据库执行潜在的事务,然后就事务顺序和结果执行的绑定承诺达成一致。因此,所有验证者都可以按照状态机器复制范式 [31] 为给定的版本号维护相同的数据库。
Libra 区块链使用了一种 HotStuff
[13] 共识协议的变体,叫做 LibraBFT 协议。在传统的 DLS[32] 和 PBF[33] 以及更新的 Casper[34] 和 Tendermint[35] 的部分同步模型中,它提供了安全性和活力。本节概述 LibraBFT 共识机制中的关键决策。LibraBFT 的完整报告 [12] 中包含了更详细的分析,包括安全性和活性的证明。
即使存在拜占庭错误 [36],验证者之间也必须就数据库状态达成一致。拜占庭错误模型允许一些验证者不受约束地任意偏离协议,除了在计算上的界限(因此不能破坏密码学假设)。拜占庭错误是最坏的情况下的错误,在这种情况下,验证者串通一气,恶意破坏系统。一种可以容忍由恶意或被黑客攻击的验证者引起的拜占庭错误的共识协议,也可以减轻任意的硬件和软件故障。
LibraBFT 假设一组 3f +
1 的投票分布在一组验证者中,这些验证者可能是诚实的,也可能是拜占庭式的。当最多 f 票由拜占庭验证者控制时,LibraBFT 仍然是安全的,它可以防止双重支出和分叉等攻击。LibraBFT 保持活性——向客户端提交事务,只要存在一个全球稳定时间(GST)之后,诚实的验证者之间的所有消息将在一个最大的网络延迟δ(这是引入的部分同步模型 [32] 发送到其他诚实的验证者。
除了传统的保证之外,LibraBFT 还在验证者崩溃和重启时维护安全性——即使所有验证者同时重启。
LibraBFT 的概述:验证者接收来自客户端的交易,并通过一个共享的 mempool 协议来彼此共享这些事务。然后 LibraBFT 协议按顺序进行。在每轮中,都有一个验证者会扮演领导者(leader)的角色,并提出一个事务区块来扩展一个包含完整的以前事务历史的经认证的区块序列(请参阅下面的法定人数证书 quorum
certificate)。
验证者接收提议的区块并检查其投票规则,以确定是否应投票支持对该区块进行验证。这些简单的规则确保 LibraBFT 的安全性——它们的实现可以被清晰地分离和审计。如果验证者打算为这个区块投票,它将执行该区块的事务,而不受外部影响。这将导致验证器对数据库的计算,从而促成了区块的执行。
这个验证者然后发送一个为这个区块和数据库验证人进行的投票给这个 leader。leader 收集这些投票,形成一个法定人数证书(quorum
certificate (QC)),它为这个区块提供 2f +1 票的证据,并将该 QC 广播给所有验证者。
当满足连续的 3-chain 提交规则时,区块就会被提交。如果在第 k 轮有 QC,并且在第 k + 1 轮和第 k +
2 轮有两个区块和 QC 确认,则区块被提交。提交规则最终允许诚实的验证者提交一个区块。LibraBFT 保证所有诚实的验证者最终都将提交该区块(以及从它链接的区块的序列)。一旦提交了一个区块序列,执行事务所产生的状态就可以持续下去并形成一个复制的数据库。
HotStuff 范例的优点:我们针对验证者的性能、可靠性、安全性、健壮实现的易用性和运营开销等方面评估了几个基于 BFT 的协议。我们的目标是选择一种协议,该协议最初将支持至少 100 个验证者,并且能够随着时间的推移发展到支持 500
-1000 个验证者。选择 HotStuff 协议作为 LibraBFT 的基础有三个原因:(1) 安全性参数的简单性和模块化;(2) 容易将共识与执行相结合;(3) 早期实验中的性能表现良好。
这个 HotStuff 协议分解为安全模块(投票和提交规则)以及活性模块(pacemaker)。这种解耦提供了独立开发和并行测试不同模块的能力。由于投票和提交规则简单,协议安全性易于实现和验证。将执行作为共识的一部分进行集成是很简单的,以避免在基于领导者的协议中由非确定性执行引起的分叉问题。
最后,我们的早期原型证实了 HotStuff 中独立测量的高吞吐量和低事务延迟 [13]。我们没有考虑基于工作量证明(PoW)的协议,因为它们的性能差,能源(和环境)成本高 [24]。
HotStuff 扩展及修改:在 LibraBFT 中,为了更好地支持 Libra 生态系统的目标,我们扩展和调整了核心 HotStuff 协议,并以多种方式进行实现。
重要的是,我们重新制定了安全条件,并提供安全、活力和乐观反应的扩展证明。我们还实现了一些附加功能。首先,我们让验证者集体签署区块的结果状态,而不仅仅是事务序列,从而使协议更能抵抗不确定性错误。这还允许客户端使用 QC 来验证从数据库中读取的内容。第二,我们设计了一个传出明确超时的 pacemaker 资源管理器,验证者依赖于这些 pacemaker 中的法定数量来进入下一轮,而不需要同步时钟。第三,我们设计了一个不可预测的 leader 选举机制,其中一轮的 leader 由最新提交区块的提议者使用可验证随机函数(VRF)

[37] 确定。

这种机制限制了恶意方对 leader 发起有效拒绝服务攻击的时间窗口。第四,我们使用聚合签名 [38] 来保留签署 QC 的身份验证者。这使我们能够向有助于 QC 的验证者提供激励(详见 9.3 节内容)。它也不需要复杂的阈值密钥设置 [39]。
验证者管理:Libra 协议使用了一个 Move 模块管理一组验证者。这在共识系统和定义可信验证者集的密码学经济系统之间创建了一个清晰的分离。我们将在第 9.2 节中讨论 Libra 区块链对该合约的实施。以这种方式抽象验证者管理,是通过定义 Move 中的核心区块链原语而获得的灵活性的一个例子。
对验证者组的每次更改,都定义了一个新的 epoch 期。如果一个事务导致验证者管理模块更改验证者集,该事务将是当前 epoch 期提交的最后一个事务。该区块或该 epoch 期以后的区块中的任何后续事务,都将被忽略。一旦事务被提交,新的验证者集就可开启共识协议的下一个 epoch 期。
在一个 epoch 期内,客户端不需要同步每个 QC。由于已提交的 QC 包含对所有以前状态的绑定承诺,客户端只需要同步到当前 epoch 期的最新可用 QC。如果此 QC 是其 epoch 期的最后一个,则客户端可以看到新的一组验证者,更新其 epoch,然后再次同步到最新的 QC。如果验证者选择按照第 4.2 节的描述删减历史记录,那么它需要保留至少足够的数据,以向客户端提供验证者集更改的证明。
验证者管理合约,必须提供满足由共识协议要求的安全属性的验证者集。拜占庭验证者不能控制超过
f 的投票权。投票权必须在 epoch 期间以及 epoch 之后的一段时间内保持诚实,以允许客户端与新配置同步。离线时间超过此时间段的客户端需要使用一些外部真实性源重新同步,,以获取他们信任的检查点(例如,从其用于接收更新软件的源重新同步)。此外,验证者集不能过于频繁地转动,以致于破坏系统的性能,或者导致客户端为过多数量的 epoch 期下载 QC。我们计划研究最佳的 epoch 期长度,预计这个时间会小于 1 天。

六、网络设计

Libra 协议,与其他去中心化系统一样,需要一个网络基层来支持其成员之间的通信。验证者之间的共识和共享的 mempool 协议都需要通过互联网进行通信,如第 5 节和第 7 节所述。
这个网络层在设计上是通用的,灵感来自 libp2p
[40] 项目。它目前提供了两个主要接口:(1)远程过程调用 (RPC) 和(2) DirectSend,实现了向单个接收方发送“即发即弃”(fire-and-forget)类型消息。
验证者之间的网络实现为一种点对点系统,使用了 Multiaddr
[41] 方案进行对等(peer)寻址,使用 TCP 用于可靠传输,Noise[42] 用于身份验证和完整的端到端加密,Yamux[43] 用于在单个连接上的多路复用子流,push 式 gossip 用于对等节点发现。每个新的子流都被分配了一个由发送方和接收方都支持的协议。每个 RPC 和 DirectSend 类型都对应一个这样的协议。
这个网络系统使用与共识系统相同的验证者集管理智能合约,作为当前验证者集的一个真实性来源。这种合约持有每个验证者的网络公钥和共识公钥。一个验证者通过监视这个智能合约中的更改来检测验证者集中的更改。
要加入这个验证者间网络,一个验证者必须使用这个合约定义的最新验证者集中的网络公钥进行身份验证。启动一个验证者则需要一组种子对等节点(peers),首先对要加入的验证者进行身份验证,使其成为验证者间网络的合格成员,然后与这个新对等节点共享它们的状态。
Libra 协议中的每个验证者都维护着系统的完全成员关系视图,并直接连接到需要与之通信的任何验证者。不能直接连接的验证者则被假定为属于系统拜占庭错误的范围。
图 6:写入事务通过 Libra Core 内部组件的流程
每个验证者的健康信息,使用周期性活性试样来确定,不会在各验证者之间进行共享;相反,每个验证者直接监视它的对等节点验证者的活动。我们期望这种方法在需要部分成员视图、复杂的故障检测器或通信中继之前,可以扩展到几百个验证者。

七、Libra Core 实现

为了验证 Libra 协议,我们构建了一个开源的原型实现 Libra Core[6]。这个实现是用 Rust 语言编写的 ,
我们选择 Rust 是因为这种语言专注于实现安全的编码实践,及其对系统编程的支持和高性能属性。我们将系统的内部组件拆分为 gRPC
[44] 服务。模块化允许更好的安全性 ; 例如,共识安全组件可以在单独的进程中运行,甚至可以在不同的机器上运行。
Libra 区块链的安全性取决于验证者、Move 程序和 Move 虚拟机的正确实现。目前,我们正在解决 Libra
Core 存在的这些问题。这包括隔离代码中有助于一个验证者在共识期间签署一个事务区块的部分,并应用措施来增强这些组件正确性的保证(例如,广泛的测试、正式规范和正式验证)。高保证性方面的工作,还包括确保代码依赖项的安全性(例如,代码评审过程、源代码控制、开源库依赖项、构建系统和版本发布管理)。

7.1 写入请求生命周期

图 6 展示了 Libra Core 中支持对去中心化数据库进行写入操作的事务的生命周期。本节深入研究事务如何通过验证者的内部组件进行流动。
当客户端希望向数据库提交事务时,就会发起一个请求(request)。我们目前假设客户端有一个带外机制来查找要提交事务的验证者地址——这一机制的最终版本尚未设计出来。
准入控制(Admission
control)。在接收一笔事务时,一个验证者的准入控制组件会执行初始语法检查(1)抛弃那些永远不会被执行的畸形事务。尽早进行这些检查可避免把资源用在垃圾事务上。准入控制可能访问 VM (2),VM 使用存储组件执行检查,如确保账户有足够的余额支付事务所需的 gas。接纳控制组件设计 , 组件的验证器可以运行多个实例。这种设计允许验证者处理规模的事务和减轻拒绝服务攻击。这个准入控制组件的设计,可以使一个验证者运行多个组件实例。这种设计允许验证者扩展传入事务的处理,并减少拒绝服务攻击。
Mempool。通过准入控制组件的检查的事务将被送入验证者的 Mempool,Mempool 容纳着等待在内存缓冲区被执行的事务(3)。Mempool 中可能容纳着来自同一个地址的多笔事务。因为 Mempool 可以一次处理多笔事务,它能执行检查,比如验证同一地址上的一系列操作是否都能够支付准入控制系统无法支付的 gas。使用这个共享 Mempool 协议(4),一个验证者可以在自己的 Mempool 中与其他验证者共享事务,将从其他验证者接收的事务放到自己的 Mempool 中。
共识。验证者通过从其 Mempool 中选择一系列事务来创建区块。当验证者充当共识协议的领导者(leader)时,它从其 Mempool(5) 中组成一个事务区块。它将此事务区块作为一个提议发送给其他验证者 (6)。共识组件负责协调所有验证器之间关于这些事务区块的顺序及其使用 LibraBFT 协议的执行结果的协议 (第 5 节)。
事务执行。作为达成协议的一部分,事务区块被传递给执行器组件(7), 负责管理 VM (8)中事务(第 3 节)的执行。这种执行发生在事务达成协议之前。这种早期执行是安全的,因为事务是具有确定性的,并且没有外部影响。在执行区块中事务之后,执行组件会构建一个这些事务的账本历史(第 4.2 节)。这个账本历史验证者将返回到共识组件(9)。
这个 leader 然后将尝试组成一个法定数量证书链(第 5 节)来就这个账本验证者达成共识,其中每一个证书都由一组验证者来进行签名,至少获得 2f+1 个投票。
提交一个区块。一旦共识算法达成一致,任何诚实的验证者都能确保所有其他诚实的验证者最终将提交一个一致的账本历史。验证者可以从执行组件的缓存中读取区块执行的结果并更新其本地数据库存储(10)。

7.2 读取请求生命周期

客户端还可以提交读取请求,为去中心化数据库中帐户的内容查询验证者。读取请求不会改变状态,可以在本地处理,而不需要经过共识。读取请求被提交到验证者的准入控制组件。准入控制组件执行初步检查,从存储中读取数据,然后将结果发送回客户端。这个响应附带一个法定数量证书(如第 5 节中描述),其中包含一个根哈希(如第 4 节中描述)。
QC 允许客户端对查询的响应进行身份验证。这个客户端使用与虚拟机相同的技术,使用逻辑数据模型(第 2 节)来解释帐户的原始字节。例如,要读取地址 a
的账户余额,客户端需要解码嵌入到该帐户的原始字节中的 LibraCoin.T 资源。

八、 性能

Libra 协议的使命是支持一个全球金融基础设施。性能是实现这一目标的一个组成部分。我们将讨论区块链性能的三个组成部分 :
  1. 吞吐量:区块链每秒可处理的事务数;
  2. 延迟:客户端向区块链提交事务与另一方看到这笔事务之间的时间;
  3. 容量:区块链存储大量帐户数的能力;
Libra 协议还处于原型阶段,因此我们还没有具体的性能指标,但我们预计 Libra 协议在最初发布时可支持每秒 1000 笔支付事务,事务提交到确认的最终时间为 10 秒。随着时间的推移,我们希望能够增加系统的吞吐量,以满足网络的需求。我们预计,许多支付事务将发生在链下进行,例如,在托管钱包内或通过使用支付通道 [45]。因此,我们认为链上每秒支持 1000 笔事务,将满足生态系统的初始需求。Libra 协议旨在通过以下几种方式来实现这些目标 :
协议设计:Libra 协议的很多元素都是基于性能挑选的。例如,LibraBFT 算法在三轮网络通信中获得共识结果,不需要任何实时延迟就区块进行提议或投票。这使得提交延迟只受验证者之间的网络延迟的限制。
我们还考虑采用并行化和分片(sharding)来选择协议的元素。计算验证者的稀疏 Merkle 树方法允许跨多台机器对数据库进行分片((这增加了容量)或并行处理更新(这增加了吞吐量)。初始事务验证(包括计算昂贵的签名验证)也可以实现并行化。
验证者挑选:与大多数服务一样,Libra 区块链的性能取决于操作它的底层验证器的性能。去中心化与性能之间存在着一种妥协。对资源非常充足的验证者需要,限制了可执行该角色实体的数量。然而,资源极度不足的验证者的存在,将限制整个系统的性能。
我们倾向于采取一种平衡的方法,将目标锁定在可以在商用硬件上运行的节点,许多实体都能买到这些硬件。但是,我们假设了这些节点运行在服务器级别硬件上,并且与数据中心能够连接良好。
根据我们进行的一次近似分析显示,该系统很可能能满足每秒 1000 笔事务的需求。
带宽:如果我们假设每笔事务需要 5
KB 的流量——包括通过 mempool 接收事务、重播事务、接收来自 leader 的区块以及复制到客户端的成本——那么验证者需要 40
Mbps 的网络连接来支持每秒 1000 笔事务。这种级别的带宽还是能够广泛获得的。
CPU:签名验证是与支付转换操作相关的重要计算成本。我们设计了允许并行验证事务签名的协议。采用 Modern 签名方案,一个普通商用 CPU 就可以支持每秒 1000 多个事务验证。
磁盘:从大型服务器供应商那里,我们可以获得 16TB SSD 存储的服务器。由于当前状态是验证者处理事务所需的惟一信息,所以我们估计,如果帐户大小约为 4
KB(包括所有形式的开销),那么这将使得验证者可存储 40 亿个帐户。我们预计,磁盘存储的发展、验证器向多个分片的扩展,以及经济激励措施将允许商用系统保持使用这个系统。
历史数据的增长可能会超出单个服务器所能处理的数量。验证者可随意丢弃那些在处理新事务的过程中所不需要的历史数据 (参见第 4.2 节);但是,那些希望查询来自过去事务事件的客户端可能对这些数据感兴趣。由于验证者签署了对该数据的绑定承诺,客户端可自由地使用任何系统访问数据,而不必信任交付数据的系统。我们希望这种类型的读取流量能够很容易地通过并行进行扩展。

九、 用 Move 来实施 Libra 的生态系统政策

Libra
区块链是一个独特的系统,它平衡了传统金融网络的稳定性和由加密经济手段管理的系统所提供的开放性。正如我们在第 1 节中讨论的,Libra 协议旨在支持 Libra 生态系统实现新的经济 [4] 和治理 [3] 策略。该协议指定了一个灵活的框架,该框架在关键系统组件(如本地货币、验证者管理和事务验证)中是参数化的。在本节中,我们将讨论 Libra
区块链如何使用 Move 编程语言定制这些组件。我们的讨论集中在协调网络参与者和验证者激励的挑战,以及支持 Libra 生态系统的运行、治理和演化的挑战。

9.1 Libra 币

许多加密货币没有真实世界资产的支持。因此,投资和投机一直是这些加密货币主要用例。投资者购买这些货币时,往往认为它们会大幅升值,然后可以以更高的价格卖出。对这些货币长期价值的信念波动,导致了相应的价格波动,有时会导致价值的大幅波动。
为了推动广泛采用,Libra 被设计成一种货币,任何用户都会知道,Libra 今天的价值与明天甚至更远未来的价值都是接近的。储备是实现价值保值的关键机制。通过储备,每枚币都有一套稳定的流动资产作为后盾。有了与储备挂钩的一群具有竞争力的流动性提供者的存在,用户就可以放心,他们所持有的任何一枚币都可以以高于或低于底层资产价值的狭窄价差,以法定货币出售。这从一开始就赋予了 Libra 内在价值,并有助于防范现有加密货币所经历的投机性波动。
Libra 的储备资产是一个低波动性资产的集合,包括来自稳定且声誉良好的国家央行发行的法币和政府证券。由于 Libra 的价值实际上与一篮子法定货币挂钩,从任何特定货币的角度来看,Libra 的价值都会有波动。储备金的组成旨在减轻这些波动的可能性和严重性,特别是在负面方向(例如,经济危机中)。为此,该货币篮子的结构考虑到了资本保值和流动性。
该储备由 Libra 协会管理(见第 9.2 节),该协会发布了一份关于该储备运行的详细报告 [4]。用户不直接与储备接口。相反,为了支持更高的效率,会有一些授权转售商,他们是由 Libra 协会唯一授权的实体,来处理大量的法定货币和 Libra 在储备中的流入和流出。这些授权转售商与事务所和其他买卖加密货币的机构相结合,为那些希望将现金与 Libra 进行来回兑换的用户提供流动性。
为了实施这一计划,Libra 的合约允许 Libra
协会在需求增加时铸造新的 Libra 币,以及在需求减少时销毁它们。该协会不制定货币政策。它只能根据授权经销商的要求铸造和销毁币。用户不必担心这种关联会导致通胀或货币贬值:要铸造新硬币,必须有相应的法定存款准备金。
使用 Move 自定义 Libra 合约的能力,允许在不修改底层协议或实现该协议的软件的情况下定义此计划。此外,还可以创建其他功能,比如需要多个签名来铸造货币和创建有限数量的密钥来提高安全性。

9.2 验证者管理和治理

共识算法依赖于验证者集管理 Move 模块来维护当前的验证者集,并管理验证者之间的投票分配。这种合约负责维护一个验证者集,其中 3f +
1 的总投票中最多有 f 票由拜占庭验证者控制。
最初,Libra 区块链只向创始成员(Founding
Members)授予投票权,这些实体:(1)满足一组预定义的创始成员资格标准 [46],(2)拥有 Libra 投资代币(Libra Investment
Tokens)。这些规则有助于确保对拥有一个安全且活动的验证者集的安全性需求。使用创始成员资格标准确保了创始成员都是已建立起声誉的组织,使其不太可能出现恶意行为,并暗示他们将勤奋地捍卫自己的验证者来抵御外部攻击。Libra 投资代币代表对准备金利息回报的预期,进一步激励验证者去维持系统的运行。由于储备中的资产风险低、收益低,只有当网络成功、储备规模大幅增长时,早期投资者才能获得超额回报。
虽然这种评估验证者资格的方法是对传统许可区块链(通常形成一组封闭的业务关系)的改进,但我们希望 Libra
区块链完全没有许可。为此,我们计划逐步过渡到权益证明(PoS)[47] 系统,在该系统中,验证者的投票权与他们所持有的 Libra 币数量成正比。这将把生态系统的治理移交给它的用户,同时通过要求验证者持有稀缺资源并将它们的动机与健康系统操作结合起来,以防止 Sybil 攻击 [48]。这种过渡需要(1)生态系统足够大,以防止单个坏行为者造成破坏;(2)为不想成为验证者的用户提供一个具有竞争性和可靠的委托市场;(3)解决 Libra 在 Staking 过程中面临的技术和可用性挑战。
Libra 生态系统治理的另一个独特点是验证者形成了一个真实世界的实体,即非盈利的 Libra 协会,由一个验证者委员会管理。该协会的每一个理事会成员代表着每个验证者。理事会中成员的投票权重与共识协议中验证者的投票权重相同。协会执行的任务包括管理储备、评估验证者资格标准以及指导 Libra 协议的开源开发。
Move 使将验证器管理和治理规则编码为一个模块成为可能。Libra 投资代币可以使用 Move 资源来实现。Move 通过将投资代币或 Libra 币包装在资源中,从而防止获得底层资产,从而允许对它们进行抵押。已抵押的资源可用于计算验证者的投票权。这个合约可以配置变更生效的时间间隔,以减少验证者集的变动。
Libra
协会的运作也得到了 Move 的帮助。由于该协会是储备的运营商,它可以创建 Move 模块,将 Libra 的铸造和销毁权力委托给与授权经销商进行交互的操作部门。该业务部门还可以评估潜在创始成员是否符合资格标准。Move 允许灵活的治理机制,比如允许理事会行使其权力,通过投票收回其授权。
该协会发布了一份详细的文件,概述了其拟议的结构 [3]。协会中的所有治理都源于验证者理事会——该理事会拥有最终的权利来维护提供给协会的任何授权。因此,随着验证者集从最初的创始成员集更改为基于 PoS 的集,整个 Libra 生态系统的治理也在不断发展。

9.3 验证者的安全与激励

在初始设置中,使用创始成员作为验证者,我们认为每个验证者的机构声誉和经济激励足以确保拜占庭验证器控制的投票不超过 f。然而,在未来,一个以币所有权为代表的开放系统将需要一个完全不同的市场设计。我们已开始了解基于利益相关者和消费者对钱包和其他代表的信心的区块链系统的治理和均衡结构。在这个过程中,我们在 Libra 方法和更成熟的方法(如工作量证明(PoW))之间确定了新的市场设计妥协。
然而,要确定如何在确保网络安全和效率的同时,还能最好地保持生态系统中的长期竞争,这需要更多的研究。此外,由于基于份额(stake)的治理引入了对影响力的路径依赖,因此有必要探索保护较小利益相关者和服务提供者的机制。
Move 允许灵活界定相关激励计划,如 gas 定价或 staking。例如,通常讨论的 stake
slashing 机制可以在 Move 中实现,方法是锁定 stake 一段时间,如果验证者违反 LibraBFT 算法的规则,影响安全性,则自动惩罚验证器。
类似地,当验证者在 LibraBFT 算法中投票时,这些投票可以记录在数据库中。该记录允许 Move 模块基于算法中的参与度来分发奖励,从而激励验证者保持活动。Libra 储备的利息和 gas 支付也可以作为激励的来源。这两个来源都由 Move 模块管理,这增加了它们分配的灵活性。虽然需要更多的研究来设计一种方法来支持 Libra 生态系统的进化,但 Move 的灵活性确保了所需的方法可以在对 Libra 协议进行很少(如果有的话)更改的情况下实现。

十、 Libra 接下来要做什么?

我们为 Libra 协议提出了一个提案,允许一组验证者提供一个去中心化数据库来跟踪可编程资源。我们讨论了 Libra 协议的一个开源原型——Libra
Core,并展示了为智能合约引入的 Move 编程语言如何允许 Libra 协议实现 Libra 生态系统的独特设计。
本文描述的协议和实现目前都处于原型阶段。我们希望从新成立的 Libra 协会和更广泛的社区收集反馈,把这些想法变成一个开放的金融基础设施。我们目前正在运行一个测试网络,以允许社区对这个系统进行试验。
我们正致力于这个系统的首次启动,为了将其保持在可管理的范围内,我们计划在第一个版本中进行几个简化。在系统的早期,使用一组外部认可的创始成员减少了对共识激励系统的需求,并允许更快的更新速度。我们预计只对系统定义的模块使用 Move 语言,而不是让用户定义自己的模块,这将使 Libra 生态系统能够在完全形成 Move 语言之前启动。这还允许在不损害使用 Move 定义核心系统行为所带来的灵活性的情况下中断所做的更改。然而,我们打算在 Libra 协议的未来版本中提供对 Move 语言的开放使用。
最后,我们目前正在 Libra 协会的框架内工作,以启动这个新生态系统背后的技术基础设施。我们发布了一个路线图 [50] 的工作,我们计划为支持这个启动做出贡献。Libra 协会的首要目标之一是将 Libra 的生态系统迁移到一个没有许可的系统中。我们已经记录了 [5] 在进行此迁移时所面临的技术挑战。该协会的开源社区 [6] 提供了有关如何开始使用 Libra 测试网、试用 Move 语言和为 Libra 生态系统做出贡献的信息。

致谢

感谢以下人士对本文的讨论和反馈:
Adrien Auclert,Morgan Beller,Tarun Chitra,James Everingham,Maurice
Herlihy,Ravi Jagadeesan,Archana Jayaswal,Scott Duke Kominers,John
Mitchell,Rajesh Nishtala, Roberto Rigobon,Jared Saia,Christina
Smedley,Catherine Tucker, Kevin Weil,David Wong,Howard Wu,Nina
Yiamsamatha,和 Kevin Zhang。

Libra区块链论文解析

本文由陈智罡博士撰写

摘要中的第一句话就表明了facebook做Libra区块链的目的(做什么):

建立一个能够支持稳定加密货币的区块链,从而为全世界人民提供便捷的电子支付

论文中特别强调该区块链是一个去中心化的可编程数据库。体现了Facebook满满的诚意,就是要落地应用。换成其它公司,哪敢称自己的区块链是数据库。在区块链界是存在鄙视链的,公有链鄙视联盟链,联盟链鄙视私有链,私有链只好看着数据库笑笑。

所以整个Libra技术论文紧紧围绕建立一个电子支付的区块链平台展开。

如何做呢?

为了建立该电子支付区块链平台,提出了Libra协议。该协议的目标是促进创新,降低进入门槛,改善金融服务。所以在Libra协议里,不仅包含技术,还有社区管理、生态建设等。

为了测试Libra协议,目前开发实现了一个协议原型:Libra核。“核(core)”在这里的含义是开发出了一个区块链大厦的地基,期望全世界都参与到Libra协议建设中,为其改进提高做出共同努力。

Libra协议具体功能是什么?

摘要第2段指出:Libra协议允许系统中的验证者(即记账者)共同维护这个具有可编程资源的数据库,而这些验证者们是来自于不同参与方的代表。这里有一个新名词:可编程资源。该资源由用户账户所拥有,并且遵守资源开发者所制定的规则。

具体的资源可以是币,或者其它具有可编程特性的东西。例如还可以是债券等。

验证者处理交易并且与其它验证者共同执行协议,以达到对数据库状态的共识,即账本的一致性。交易是基于系统中已经定义好的规则,在将来版本中,用户通过使用Move编程语言可以自定义智能合约来处理交易。这里引出了Libra区块链中另外一个重要的特征,就是内置了用于交易场景的编程语言Move。但是目前该编程语言还未完全成熟,没有发布正式版本。

Libra区块链中的核心机制都是通过Move定义,例如币,验证成员。这些核心机制有助于建立一种独特的治理机制,目前这种机制是建立在现有参与方的稳定性和声誉的基础上,但随着时间的推移将过渡到完全开放的系统。

以上就是摘要的全部内容。通过读论文中的摘要,可以领会论文的概貌,例如:目的,做什么,怎么做,效果。

从我们对论文摘要的解析,可以体会到Libra区块链的目的很明确,就是要建立一个全世界通用的区块链支付系统。该系统的核心是Libra协议,该协议是Libra区块链的基石。针对的对象是维护一个可编程资源的数据库。

目前Libra区块链只实现了Libra协议的原型,更多的开发留待更多的参与者共同开发。Libra协议的核心机制都是通过Move编程语言定义的,所以具有灵活性、可扩展性。但是目前为了落地与测试,用户还不能自定义规则。从摘要就能看到,Libra区块链是一个联盟链,记账者(论文中称为验证者)都是Libra区块链的参与方代表,是一个封闭的圈子。当然愿景是未来逐步开放到所有持有Libra币的参与者。

宁波格密链网络科技有限公司已经开展对Libra协议的研究与扩展,欢迎广大技术人员参与,共同推动区块链支付技术的发展与繁荣。

 

如果说摘要是对整个论文描述的一个浓缩,引言就是对论文的一个概览。横看成岭侧成峰,远近高低各不同,引言会进一步介绍论文的出发点,技术轮廓,创新点以及挑战。所以,引言一定要写好,读者或者审稿人能够通过引言对论文打出印象分,这个分数直接影响了该论文的前途。

读Libra技术论文的引言,就能够对它整个技术框架,创新点,性能等有个了解。对于一般非技术人员,读完引言就可以理解Libra区块链的特性了。

引言第1段就引出Libra区块链想解决的问题

尽管互联网极大的促进了金融服务业的发展,但是对于那些最需要金融服务的人来说,获得金融服务仍然是有限的——受成本、可靠性和跨境汇款能力的影响。

为解决上述问题,论文提出了Libra协议。该协议支持Libra生态系统,旨在解决这些挑战,扩大资本准入,并作为创新性金融服务的平台。

为了实现上述宏观目标,这个生态系统中提供了一种全新的全球货币——Libra币。那么和现实中的货币有什么关系呢?

Libra币是与一些不同国家信誉良好的央行存款和国债绑定的,而且这些货币都经历了相对较低的波动,因此Libra币天生继承了这一稳定性,以及地理上来自不同地方的资产组合的优势。

这里指出Libra币的国际性,与一些央行都挂钩,凸显了Libra币的信用。

为了发展成为全球金融基础设施,Libra协议必须能够满足大规模的交易量。除此之外,还提供实现其经济和管理政策的灵活性。

交易规模是目前区块链技术的痛,这里论文里强调需要解决该问题。不禁让人想看看是如何解决的。

Libra协议从一开始就从整体设计上解决这些需求,并建立在前人的项目和研究基础之上,结合了目前一些新颖的方法和成熟的技术。

注意,新颖和成熟是并列的,前者说明了创新,后者说明了落地应用。

读到这里,是不是感觉很像比特币的技术路线,都是采用前人已有的技术,然后进行改造,为我使用。一切围绕着落地应用为目标。

金融服务业健康竞争和创新的一个重要前提是能够依赖共同的基础设施处理交易、维持账户,以确保不同服务和组织之间能够沟通合作。这句话很关键,说出了需要为多方合作提供一个公共平台的必要性,显然该平台应该是开放、公平以及有良好信用保证的。

为了提供上述平台,Libra协议使用区块链技术,利用区块链的去中心化特性,不受某一方控制,通过降低进入壁垒和成本,使得初创企业和现有企业能够在公平竞争的环境中竞争,并尝试新的业务模式和金融应用。

上面层层递进,从宏观金融问题,引入到区块链平台。下面将说到Libra区块链中的各个角色。

提醒一下,我们解读的是Libra技术论文,而不是Libra的介绍。整个技术论文分为10部分:

1 Introduction–引言

2 Logical Data Model–逻辑数据模型

3 Executing Transactions–交易的执行

4 Authenticated Data Structures and Storage–可认证的数据结构和存储

5 Byzantine Fault Tolerant Consensus–拜占庭容错共识

6 Networking–网络

7 Libra Core Implementation– Libra 内核实现

8 Performance–性能

9 Implementing Libra Ecosystem Policies with Move–使用Move实现Libra生态系统规则

10 What’s Next for Libra?– Libra发展规划

 

引言的上一部分(引言1)讲了Libra的商业应用以及宏观目标。下面分别从项目的管理和技术方面,具体说说Libra区块链。

Libra区块链的管理

Libra区块链是去中心化的,由一些称为“验证者”的角色共同处理交易和维护区块链的账本状态。这些验证者们构成了Libra联盟成员,他们提供网络治理和Libra币的储备。

初始阶段,Libra联盟由来自不同区域的基金会会员组成。基金会会员是按照一定的标准选出,会员包括那些促使Libra生态系统发展以及注入资本的股东。以后,会员资格将逐步完全开放,Libra币持有者都可以进入。

Libra联盟已经发布了一些报告,包括发展规划愿景,管理结构,币的生态,以及朝着公链发展的路线图。

这篇技术论文是为了建立Libra区块链技术框架所迈出的第一步。发布这些早期的报告是为了对整个设计方案、发展计划以及研究方面为解决问题的挑战,征求社区的意见和反馈。为此,Libra建立了社区,以便大家参与讨论,共谋发展。下面具体说技术。

Libra协议

论文直接指出:Libra区块链是一个基于密码学认证的数据库,是通过Libra协议支持其运行。

数据库?那么区块链的账本又在哪里呢?

紧接着论文说:该数据库存储一个可编程资源的账本。可编程资源是什么东东。例如可编程资源可以是Libra币,当然也可以是其它的资源,例如债券等。资源是遵守由声明模块所制定的规则,也是存储在数据库中。

一个资源属于某个账户所有,该账户是由公钥所认证。一个账户直接代表系统的终端用户,或者某个实体,例如钱包,账户的行为代表着用户。

Libra区块链中有了两个核心角色:验证者和客户。读者要牢牢记住,Libra是一个区块链支付系统,所以一切都是以交易为中心。由于是去中心化的,所以达成共识是技术关键。

验证者的职责是维护数据库,将客户提交的交易存入数据库,然后更新数据库的状态。验证者是通过执行分布式共识算法,以达成对提交到数据库中的交易以及执行交易结果的共识。这些交易在数据库中形成一个不断增长的交易列表。

共识协议必须具有可靠性,能够抵御来自少数验证者可能的恶意行为。验证者轮流对已提交到数据库的交易进行处理。

在验证者中有一个“验证者头目”的角色,该验证者头目负责将收到的交易分发给其它验证者,这些交易可能来自于客户直接提交给验证者头目的交易,或者来自于其它验证者提交给头目的交易。

所有验证者执行头目发给自己的交易,并且形成一个可认证的数据结构,该结构包含了账本的最新状态。为了达成共识,验证者对数据结构的验证进行投票。

为了确认处于数据库状态第i版本的交易Ti,共识协议输出对第i版本下数据库整个状态的签名,包括数据库的全部历史。该签名用于响应来自客户的查询。

客户能够向验证者提出读取数据库中数据的查询,由于数据库是基于密码技术认证的,所以必须对能够保证对客户查询提供准确的响应。为此,当客户向验证者提出查询数据库时,该验证者返回他所知道的目前数据库最新状态版本认证的签名。这样就把时间和数据联系起来,已保持数据库状态的一致性。

此外,客户也可以通过验证者同步整个数据库,建立一个数据库的副本。客户通过数据库的副本能够校验验证者执行交易的正确性。这提供了系统的可审计性和透明性。客户端也可以从其他客户端中读取其保存的数据库副本。

图1显示了使用Libra协议进行交互的两种实体类型:(1)验证者(维护数据库)和(2)客户(对数据库执行查询并提交交易来更新数据库)。

图1:Libra协议的概述

至此,Libra区块链协议的轮廓介绍完了。为了大家更清楚,我们通过一个例子来说明。

例如,客户端A想要向客户端B转1个Libra币,那么客户端A就向Libra区块链提交一个交易。区块链平台收到交易,可能是验证者头目收到,也可能是其它验证者收到,无论谁收到交易都要提交给验证者头目。然后验证者头目再将交易分发给其它验证者去验证。验证者收到头目发来的交易后,执行交易并且对其验证,形成一个可认证的数据结构。注意这里我们所说的认证,就是指通过密码学手段达到的。然后验证者们对该认证进行投票。最后共识算法输出对整个数据库状态的一个签名,从而对该交易入库进行确认。

引言就此解析完毕,论文下面就是对各个方面进行详细描述。

读完引言,似乎感觉整个论文缺少技术创新点。在论文中也确实说是系统由已经存在的技术组成。所以在引言中看不到对创新点的描述。

不过通过摘要以及引言看出,Libra不在于技术创新,而在于系统落地应用的商业模式的创新。

 

在比特币里面有个很重要的概念:时间戳。通过时间戳把交易与时间绑定,时间戳还控制着整个比特币系统运行的节奏。我们在解读比特币白皮书的文章里(解析比特币白皮书之时间戳服务)详细解释了其背后的含义。

Libra区块链是一个数据库,如何把数据与时间进行挂钩,交易与时间的关系,以及历史交易如何查询(也是一个与时间有关的问题),这些都属于数据逻辑模型需要阐述的。

Libra区块链中的所有数据都对应于数据库的某一个版本号,数据库的版本号表明了该数据库在某一段时间的状态。所以在描述Libra区块链中的交易时,必须指明是在哪一个版本状态下进行的。

一个版本号是一个无符号64位整数,与系统执行的交易数量相对应。

所以在Libra区块链中,通过一个三元组(TiOiSi) 来刻画交易的状态。其中Ti 表示当前的交易,Oi表示交易执行的结果,Si 表示账本状态。通过这三个元素刻画了交易的状态。例如对执行某个交易的操作Apply,可以用三元组来刻画,即在账本状态Si-1下执行交易Ti ,执行的结果为Oi ,新的账本状态是Si 。形式化表示为:

Libra协议通过Move语言实现区块链支付系统中对操作的执行。本节主要关注带有版本号的数据库。通过版本号控制的数据库允许验证者完成以下操作:

1. 在最新版本的账本下,执行某个交易

2. 对客户查询当前以及历史账本记录做出响应

问题来了,能够反映某个版本下的账本数据结构应该是什么样的呢?为什么要让账本的历史数据都是可查的呢?

首先从账本状态说起。

账本状态

账本状态根本上反映了Libra系统的客观状态。例如在某个时间某个用户持有多少Libra 币(当然这里时间是通过版本号来反映的)。而且为了执行交易,验证者必须知道目前账本的状态。

所以账本状态是执行操作依赖的基础,也是反映Libra系统的状态晴雨表。

Libra协议采用的是基于账户的模型。这是与比特币不同的地方,比特币采用的UTXO模型可以参考我们的比特币白皮书解析文章(解析比特币白皮书之交易)。

账本状态通过“键值对”存储在数据库中。学过数据库的人对“键值对”的概念不陌生。键值对将账户地址(key)映射到账户值(value)。账户值是由已发布的Move资源和模块构成,其中Move资源存储的是数据值,而模块存储的是代码。账户的初始状态是由创世块赋值。

下面解释账户地址。

账户地址

账户地址是一个长度为256位的值。为了建立一个账户,首先需要用户生成一个公钥私钥对(vk, sk),公钥 vk用于验证,私钥sk 用于签名。通过对公钥vk计算哈希值后产生一个账户地址a = H(vk)。

当某个账户将一笔交易发送给某个用户时,将调用create_account(a) Move指令产生一个账户,该新账户与这个用户对应。这种情况一般是发生在交易产生时,目标地址a还没有账户的情况下。

注意有了地址,还需要创建与之对应的账户

一旦账户建立后,用户就可以使用该账户下的私钥sk 对交易签名。有时为了防止密钥可能被攻击的危险,可以采用密钥替换机制,每隔一段时间采用新密钥,终止原密钥的使用。当然使用新密钥意味着需要建立新的账户地址。所以一个用户可以有多个账户。

Libra协议允许一个用户建立多个账户,而且不会把账户与现实世界的身份对应起来。属于统一用户的账户之间没有关联关系。因此Libra协议提供了一种伪匿名的特性,与比特币和以太坊类似。

资源

资源也称为资源值,是一条将字段名与数值绑定的记录,该数值可以是整数,也可以是复数,甚至可以是嵌入到资源内部的资源。

每个资源都属于一种类型,该类型由模块所定义。资源的类型由资源名称、资源所在模块的名字与地址构成。例如在图2中,Currency.T资源类型是0x56.Currency.T,其中0x56 是Currency模块所在的地址,Currency是模块的名字,Currency.T是资源的名字。

图2:一个包含四个帐户的账本状态示例。在这个图中,椭圆表示资源,矩形表示模块。从资源到模块的有向边意味着该模块声明了资源的类型。地址0x12的帐户包含一种Currency.T资源,该资源由Currency模块所定义。Currency模块的代码存储在地址0x56。在地址0x34的帐户包含Currency.T资源和StateChannel.T资源,这两个资源都是由存储在地址0x78的模块所定义。

如何找到某个资源呢?

例如在账户0x12下,为了检索到0x56.Currency.T资源,客户端通过如下地址提出请求:

0x12/resources/0x56.Currency.T

这样设计的目的使得每个账户使用相同的路径存储0x56.Currency.T资源,让模块为账户值定义一个使用上方便,而且是可提前预知的使用方法。因此对于每个类型,每个账户至多存储一个资源。但是这个限制并不是一个硬性条件,程序员可以自定义一个封装资源,例如resource TwoCoin { c1: 0x56.Currency.T, c2: 0x56.Currency.T }。

资源的建立以及资源类型的定义都是在模块中进行,对于建立好的资源进行转换、删除以及发布的这些规则都被编码在模块里。Move的安全和校验规则阻止了其它代码对资源的修改。

模块

模块也称为模块值,它包含由Move对资源类型和过程的字节编码。如何标识模块呢?是通过在该模块中的账户地址来标识模块。例如图2中,Currency模块被标识为0x56.Currency,其中0x56是账户的地址。

模块在一个账户中的命名是唯一的,即每个名字只能被每个账户使用一次用于定义一个模块。例如0x56账户不能再将其它模块命名为Currency,但是其它账户,例如0x34,可以给属于它的模块命名为Currency,例如命名为0x34.Currency。注意,0x56.Currency.T 和 0x34.Currency.T属于不同的类型,不能混淆使用。

目前版本的Libra协议不允许对模块修改,即模块具有不可篡改性。一旦一个模块在账户中被创建,就不允许对其修改、删除,除非进行分叉。

对模块进行安全更新是Libra协议将来扩展的功能,目前正处于研究中,也算是一个挑战。

交易

Libra区块链的客户提交一个交易后,账本的状态将会被更新。这和现在的银行是一个道理,产生一笔交易后,我们的账户的余额会发生变化。

总体上来说,一个交易是由交易脚本和输入该脚本的参数构成,其中脚本是通过Move字节编码写成,参数可以是接收账户的地址或是发送Libra币的数量。

交易的执行是通过验证者运行脚本程序来实现的,脚本参数和账本状态作为程序的输入,产生一个完全确定的输出结果。

交易发生后,账本状态就被更新了吗?不是的,就像比特币系统中,交易经过6个块的确认后账本才被更新确认。在Libra区块链中,经过共识算法对交易输出结果达成一致确认后,将确认与交易结果绑定,账本状态才被更新。交易的结构与执行将在第3节详细讨论。

交易输出

执行一个交易Ti会产生一个新的账本状态Si 以及执行状态代码、gas使用量、事件列表,这些内容都集中放到输出Oi 中。执行状态代码记录了执行交易的结果,例如执行成功、因某个错误退出、gas使用量耗尽等。gas使用量记录了执行交易所使用的gas数量,具体细节看3.1节。事件是什么呢?

事件列表

事件列表是在执行交易过程中产生的“副产品”,类似于以太坊中日志和事件的概念,但是使用目的完全不同。

Move代码通过事件结构体触发事件。每个事件与唯一一个公钥关联,该公钥通过已触发的事件及其支付金额来标识事件结构体,从而提供事件的详细信息。

一旦交易被共识协议所确认,由该交易产生的事件就被记录在账本历史中,为交易成功执行所产生的结果提供证明。例如,某个支付交易触发了一个事件,允许接收者对支付到账的确认以及支付金额的确认。

乍一看,事件概念似乎是多余的,客户可以通过查询交易是否已经存储在区块链中,来代替对该交易触发的事件的查询。但是如果这样代替,极容易产生错误,因为交易存放在区块链中并不意味着交易已经成功执行,很可能由于执行过程中gas耗尽而中断执行。因此在一个交易可能执行失败的系统中,事件不仅能够对交易的执行提供证明,还可以对交易成功的执行并且与预期相符提供证明。

注意,交易仅仅能够生成事件,并不能读取事件。这种设计仅仅允许交易的执行基于当前状态,而不是基于历史信息,例如读取以往产生的事件是不允许的。

账本历史

账本历史保存了交易的提交和执行的顺序过程,以及它们所触发的事件。账本历史的目的是记录最近账本状态形成的过程。在账本历史中没有“块”的概念。

共识协议将交易打包成块,只是作为一种优化来驱动共识的执行。但是在逻辑数据模型中,交易是按顺序产生,并不需要区分哪个块包含了哪个交易。

尽管验证者执行新的交易时并不需要知道账本的历史,但是账本的历史可以用于客户审计交易的执行,例如客户可以对交易的历史提出认证查询。

客户查询响应

验证者是通过账本的历史来响应客户对以往账本状态、交易以及输出的查询。例如:一个客户可能会查询在某一版本号下的账本状态,例如:在版本30下,地址为x的账户余额是多少? 客户还可能会查询某一特定类型的历史事件,例如:地址为y的账户在最近20分钟内接收了哪些支付?

交易执行的审计

客户对账本状态的验证,是通过重新执行以往的每一笔交易Ti,将执行结果与相应版本数据库中对应的账本状态Si、交易输出Oi进行比较。

这一机制允许客户对验证者进行审计,从而确保交易的正确执行。

本节分析完毕。本节中,区块链本是存储在某一个版本的数据库中。而账本的历史状态是很重要的,因为交易是有顺序的。当前交易是基于前一个交易,否则就会乱套。现在要把银行帮我们记账搬到区块链上记账。因此账本的历史状态、当前状态都是需要刻画的。

此外,客户可以对账本审计,优点是透明,缺点是隐私无法保护。

 

本节第一话就开宗明义的指出:在Libra协议中,改变区块链状态的唯一方式就是执行交易。千万别忘了Libra是一个支付系统,是基于区块链的支付系统,所有的内容都是围绕着这个主题在转

本节概括了交易的执行条件,定义了交易的结构,解释了Move虚拟机如何执行一个交易,描述了Move 语言的核心概念。

在Libra 协议的最初版本里,只对用户提供了很小一部分Move语言功能。事实上,Move语言通常用来定义系统的核心概念,例如Libra币。用户是不允许发布模块来声明自己的资源类型。这种设计理念让Move语言在构建Libra 核心系统中逐步成熟,而且也回避了在智能合约中,执行交易与数据存储所带来的扩展性问题的挑战。

可见,在Libra 系统构建中,采用的是逐步求精的原则,尽量简单实用,不断进化。采取的很务实的态度。

至于Move语言的全部功能特性,将在第10节展开描述。如果你着急知道,可以跳到第10节,不过是英文的。

由于最近比较忙,我会坚持更新。写作和跑步对于我来说,都是一种放松和愉悦。

3.1交易执行之前的规则制定

比特币里有创世块的概念,即区块链中第一个块(称为创世块)是如何形成的呢?在Libra 系统中,系统一开始就设置好了创世状态,所有验证者默认即可,非常方便。

在Libra创世状态里,通过“模块”定义了系统的核心对象,例如:账户间的逻辑关系、交易验证、验证者的选择、Libra币等。在Libra创世状态中,必须考虑周全,例如至少有一个账户,能够支付得起第一笔交易产生的费用;必须要有一些验证者,能够对交易的认证进行签名确认。

账本的初始状态是什么?创世状态如何产生呢?注意,初始状态是系统原始状态,而创世状态是系统开始第一笔交易的状态,也就是启动系统的状态。

为了简化设计,系统的初始状态通过“空状态”表示。而创世状态是通过一个特殊的交易T0所创建,并且定义了所需要的模块与资源。注意,这里并没有通过正常的交易过程来建立创世状态,系统直接默认的设置执行特殊交易T0。因此,客户和验证者也被设置为只接受T0开始的账本记录,可以通过密码学的哈希技术标识T0的开始。

值得注意的是像T0 这样的特殊交易,只能通过设置的方式加入账本记录,而不能通过正常的共识算法加入账本记录。

这种方式的好处是处理简单,例如通过设置一个特殊交易来定义分叉的开始。像客户也可以设置一个特殊交易对模块和资源进行改变。这种特殊交易的执行都是在正常交易执行之外进行的,增加了系统对特殊事件的响应处理能力。当然,中心化的色彩就很浓了。不过,凡事都通过共识来完成,效率也太低。

●确定性

交易的执行具有确定性和封闭性。这意味着交易的输出结果完全是可以预计的,仅依赖于交易包含的信息和账本的当前状态。而且交易的执行不受外部的影响。

对于相同的交易序列号,确定性和封闭性使得不同验证者产生相同的验证结果。所以从创世块开始执行交易,一直到当前账本状态,可以重复获得相同的区块链的交易历史记录。

●可度量的

为了管理对计算资源的需求,Libra协议对每一笔交易收取交易费,通过Libra 币支付该费用。该方法遵循了以太坊的Gas理念。

在Libra系统中,选择具有充分计算资源的验证者,以满足Libra系统的正常运行。收取交易费用的唯一目的,是为了当资源需求超过系统所能提供的资源时,降低系统资源的需求量,从而保证系统正常的运行。

系统正常运行时,对于正常的操作只收取较低的费用。这与目前一些区块链的思路不同,有些区块链选取不具有充分计算资源的验证者。当资源需求变高的时候,交易费急剧增加,对于验证者能得到可观的回报,但是对于客户就是成本。

一笔交易的执行是以消耗的Gas成本来表示所消耗的计算资源的多少,该成本是动态的,因每个用户而不同。验证者会优先选择价格更高的交易执行,当系统繁忙时可能会漏掉价格低的交易。

交易中包含一个Gas的最大值,该值说明了在某个具体Gas价格下,发送者愿意支付的最大数量Gas。

在交易执行期间,虚拟机会跟踪Gas使用数量。如果在执行完成前,最大Gas数量用完,则虚拟机立刻终止。该交易不会对当前账本状态有任何影响,但是交易任然会出现在交易历史中,并且会对发送者收取交易费。

在这节我们看到,区块链中的核心逻辑的许多部分都是使用Move进行定义的,包括Gas费的扣除。为了避免循环扣除费用,虚拟机禁止在核心组件执行期间对扣Gas费。这些核心组件都是在创世状态下定义的,而且具有写保护以防止恶意交易触发的高额交易费用的代码执行。执行核心组件的费用将包含在后面对交易的收费中,是一项基础费用。

●资产语义

账本状态直接通过现实世界的数值对数字资产进行编码。交易执行中必须保证Libra币不能够被复制、丢失以及非授权转移。Libra协议只用Move虚拟机来实现交易和客户资产具有这些安全属性。

3.2交易的结构

一个交易是通过数字签名认证的信息,其内容如下:

发送者的地址:就是交易发送者的账户地址。虚拟机通过存储在发送者地址下的LibraAccount.T资源,来读取序列号、认证公钥、余额等内容。

发送者的公钥:该公钥对应于该交易数字签名所使用的私钥。公钥的哈希值与存储在LibraAccount.T资源中的认证公钥相匹配。

程序:包括用于执行交易脚本的Move字节编码,脚本所需的输入参数列表,所需发布的Move字节编码模块列表。

Gas价格:执行交易是需要掏钱的,和我们用的银行转账不一样。为了执行交易,发送者需要给出愿意支付每一Gas单元的Libra币数量。

Gas数量的最大值:执行交易允许被消耗的最大Gas数量值。

序列号:是一个无符号型整数,与在发送者在LibraAccount.T resource下的序列号相同。交易执行完后,序列号加1。由于每个交易有唯一一个序列号,所以不能重复交易。

Facebook的野心

看完Libra技术文档,感觉这更像是一个RFC文档。可能有些朋友不知道RFC是什么意思。RFC的中文含义就是“请求评论”。例如互联网的标准发布前,会公开该标准的所有内容,请求全世界的人去提意见,然后不断修改完善,最终形成草案,最后形成标准。

Facebook的意图蕴含在这个技术文档里,我明显感觉到Facebook是想形成一个基于区块链的支付标准。这个目标相当具有挑战性的,而且很诱人。

首先我们想一个问题,谁能做支付标准?

我想它必须是一个具有社交属性的公司,因为支付本质上是人和人的连接,如果手上没有拥有人和人连接的资源,支付可以做,但是谁来用呢?

所以掰手指头想想,只有像Facebook,阿里,腾讯,推特这些具有社交属性的公司可以做。

国内因为限制区块链上的币交易,所以区块链上的支付标准,阿里腾讯是错失江山的。而恰好Facebook窥视垂涎支付业务已经好久,如何杀入这一领域,是具有挑战性的和危险性的。但是Facebook并没有硬闯,霸王硬上弓只会杀人500自损3000,所以一定要绕道而行。

如何既能进入支付领域,又能坐上头把交椅,还能兵不血刃呢?似乎不可能。

然而Facebook的策略做到了,最起码路线非常合理与科学。

我们来说说其策略合理性的原因。

首先,区块链还属于一个原始地带,新生事物,就像一个刚开张的酒吧,来的都是新面孔,所以没有老大,还没形成圈子,也不需要交地盘费,来的都是客。

此外,目前在区块链界混的都是初生牛犊,都是发发白皮书不干活,吹的天花乱坠,所以这些人是最好对付的。你只要稍微有些技术,立马显现出来,何况Facebook的强大团队。

另外,国外移动支付并不发达,如果想搞移动支付,必须和银行要挂上钩。而银行的根基何其深,与其分羹还不如去无人的矿场去淘金。

由于区块链上的数字货币已经发展了10年了,技术储备已经初见端倪,现在正是进场的好时机。

如果想做区块链生态,必然需要以虚拟货币为基础,否则全是空谈。而发行数字货币必须要有足够强的人气,Facebook是社交界的老大,这方面是无敌的。

所以,Facebook通过区块链发行数字货币,绕开了银行,绕开了国家。相比之下,阿里和腾讯就惨多了,银行是他们心中的痛,步步受限。而且Facebook通过发行的数字货币自然就打开了支付之门,这把金钥匙得来全不费工夫。

但是千万别忘了,Facebook野心是形成区块链上支付的标准。就像当年TCP/IP形成了互联网的标准一样。Facebook的Libra就像是一个安卓操作系统,开放的,人人都可以在其上做二次开发。

看来,区块链上的操作系统真的要来了。

Libra技术概览

本文由陈智罡博士撰写

我们是最早将Libra技术论文发到了格密链区块链群里,第二天一大早就看到有人翻译出该论文。粗粗阅览了一下,只有两个字“汗颜”。错误百出,居然把transaction翻译成事物,显然是机器翻译的。当然也反映出缺少专业性,所以无法胜任。

学术圈和商业界是一个生物链,有空我会好好说说。在一个新生技术面前,学术界是有极大的优势的,尤其是当这一技术具有高门槛,例如密码学技术,没有专门的学习与修炼是很难撼动的。

话说回来,这两天我们先后发表了对Libra的解读(解读1解读2),引起了大家广泛的共识与讨论。接下来我们想对技术进行解读,好让大家对Libra有个清晰的认识。这个事情估计只有我们能够做的最好(可参考我们的比特币白皮书解析),因为我们即在学术圈,也在工业界,格密链一贯的思路是做区块链上密码技术的研发,也是国内首家专注于区块链上密码技术研发的公司。

对于普通大众,最关心的就是Libra是个啥区块链,能挖矿吗,激励机制怎么样。在高阶一点的朋友,就关心共识算法用的是什么,性能如何,用什么编程语言等等。下面一一解释。

细读完整个技术论文,我体会到Facebook满满的诚意。因为整个论文对Libra的称呼就是数据库,一个基于密码技术的可认证的数据库。换成其他白皮书,深怕别人说自己不是区块链,哪敢用数据库三个字。

然而,Facebook却很诚实。因为他们是想把该项目落地的,请看论文最后一部分第2段的第1句话:

We are working toward an initial launch of the system, and to keep it within a manageable scope, we plan to make several simplifcations in the frst version.

这句话啥意思,就是为了落地Libra,在第一版中简化了一些东西。

所以这也是我称呼该技术文档为论文的原因。整个文章都是按照论文风格写的,有理有据,和你见过的白皮书完全不一样。

既然Libra是一个去中心化的数据库,那么它是什么类型的区块链呢?

它是一个许可链,通俗的说就是联盟链。因为要落地使用,所以只有联盟链技术上最可行。论文中也指出,将来会慢慢朝着公有链方向发展。何年马月无从知晓。总之,目前要想真的开展应用,只有联盟链最合适。

紧接着可能很多人会问:有激励机制吗?可以挖矿吗?

既然是联盟链就没有激励机制,也不可能挖矿了。谁来记账呢?

Libra在这方面给出了详细解释,为了系统的性能,记账成员来自于基金会成员。将来Libra会把记账权推广到拥有Libra币的成员。

那么激励机制有吗?准确的告诉您:没有。都是自家人何须激励,Libra系统中没有外人,只有自家成员。

有人记账了,那么如何达成共识呢?

该系统用的是一个称为LibraBFT的共识算法,它是HotStuff共识协议的改进版。它具有拜占庭容错功能,能够在3f + 1个结点间达成共识,只要其中 f个结点是诚实的。这是技术上的需要和防范,其实你想想结点都是股东和基金会成员,大范围恶作乱是不可能的。

Libra并不是自己从头构建一个共识算法,这和有些白皮书截然不同(明明用的是别人的算法,偏偏说是自己革命性的创造)。在选择共识算法上,Libra选择的标准是至少能够支持100个结点,而且未来能够扩展到500-1000个结点。

鉴于以上的标准,Libra 选择了HotStuff共识协议。该协议安全性证明简单,便于执行,而且性能较快。Libra系统通过3轮网络通信即可达成共识。

这一切再次说明,Libra不是玩虚的,一切为了落地应用。想想EOS吧,一比较就可以看出高低。

Libra性能如何呢?

论文明确的说明了,支持每秒1000笔交易,每笔交易从产生到最终确认需要10秒钟。熟悉比特币的同学,一定想到了比特币每10分钟出一个块,确认还要6个块后。Libra假设需要交易在链下进行,而且也可以通过支付通道完成。

那么Libra如何出块的呢?

遗憾的告诉你,Libra没有块这个概念。因为它自始至终是一个数据库,只有交易列表的概念。

Libra是用什么开发语言构建的?

用的是RUST。选择该语言也很明智,除了保障安全性外,该语言还有一个大的特征是高度契合支付交易场景。从语言上的选择,说明了Facebook确实冲着支付交易场景去的。

除了以上一些特性外,论文中反复说了,目前只是一个系统原型,某些方面做了简化。但是主要有的几个部件都有了,剩下的工作可以在此基础上进行开发。在Libra早期阶段,使用外部认可的基金会成员作为记账员,简化了激励机制以及提高了系统响应速度。为了落地应用,用户不能自己定义规则,等到MOVE语言参数规范之后,将来Libra系统会逐步开放。

Facebook发行的Libra与支付宝的关系

本文由陈智罡博士撰写

这几天关于Facebook发行的虚拟货币Libra沸沸扬扬。国内虚拟货币市场很大,关心的人也很多。尤其是Facebook这么大牌的国际公司也发了币,不禁让人产生好奇。

想理解Facebook发行的Libra,其实拿支付宝做比喻最好。

现在支付宝是移动支付领域的领头羊,大街小巷都可以用支付宝支付,那么支付宝里的钱可以看成是阿里发的币吗?

当然,不仅可以看成是阿里发的币,还可以看成是一种稳定币。该币锚定人民币,而且略微有些上涨,例如每次支付后可以获得积分,放到余额宝里还有相应的利息。

那么它是不是所谓的去中心化电子货币呢?显然不是,它不是点对点的支付,因为它是以阿里为中心的,所有的支付都绕不开阿里的服务器。如果阿里想改你的账户,分分钟的事情。所以它不是区块链上的虚拟货币。

好了,假设现在国家放开了政策,阿里想把支付宝放到区块链上。为什么要放到区块链上?因为放到区块链上有一个非常大的好处,可以成为国际虚拟货币,全世界通用,尤其是解决跨境支付那是相当的方便。

但是如果只是阿里自己搞,缺少国际性,怎么办呢?拉人入伙,可以把国际上的各个寡头拉入形成阵营。由于是区块链上的虚拟货币,所以把银行直接就绕开了,这是最好的一张国际牌。你想想,如果不是在区块链上做文章,例如成立一个国际结算联盟,始终还是绕不开银行,也绕不开国家。

现在好了,有阿里这样良好的生态圈,又加上国际寡头公司的加入,信用通过区块链放大了好几倍。未来所有的地方都可以用阿里币来支付,无论是偏远,战乱或是跨境支付等。

此外,还衍生出用于移动支付场景的编程语言,使得开发环境的生态一片大好。

所有的一切,都是因为区块链实现的点对点的支付,成功的把银行,国家绕开了。然而这既是它牛的地方,也是它致命的地方。未来如何,就要看它如何演化了。