王玮
渡鸦区块链专栏作者
上文介绍了R3 Corda的基本概念与模型,本文将重点介绍下R3 Corda交易流程的相关细节。
交易流(Flow)
交易流(flow)是Corda系统的重要概念也是特色之一,简单说flow就是复杂交易的具体实现协议:如同比特币核心系统本身支持的动作只有“花钱”一样,Corda最基本的交易能力也只是{输入、指令、输出}。这样一来,现实世界中所出现的涉及多方的、多环节的、有条件的交易等复杂处理流程,只需要通过简单交易的组合、包装来完成。
由于Corda的交易通讯都是点对点的,而非全网广播的,因此交易流程实现起来相对简单、直接:就像一个流程图,我们只要描述节点之间的连接、数据传输的方向,以及从一个节点向下一个节点流转的条件等等,就可以设计出交易流程了。
把这个流程通过代码实现,并且交由Corda系统去运行,就成了一个个在系统中的flow,支撑着Corda系统的日常运转交易处理,这实际上就是Corda系统的Dapp,又称CorDapp。
Corda有大量的内置flow,基本覆盖了日常交易流程中所用到的功能和典型交易的过程,例如:获取交易数据、变更Notary、交易组中确认,还包括典型的两个参与方的交易(模板)等等,都在net.corda.flows中定义。由于支持子流程调用,因此新开发一个flow需要的实际代码量应该也很少。
一个有意思的事情特别强调一下,Corda的flow实现,使用到了一个“黑科技”——quasar。
这是一个JVM系统上实现fiber/co-routine形态的纤程/轻线程的类库,同时也是一套实现了actor模型的类库,可以说是目前actor领域内除Akka之外唯一一个比较有影响力的实现。
Corda系统中主要是使用到了quasar的纤程能力,通过quasar字节码级别的注入,实现了一个flow的执行流程可以随时被挂起和恢复,并且挂起是可以在持久化层面实现的,从而大幅度提高了系统的可伸缩性和可靠性。
由于quasar目前只对Java和Kotlin提供完整支持,对Clojure提供部分支持,对Scala等其他JVM语言的支持还相当不完善(Scala由于有Akka,对于quasar是不是感兴趣也是问题)。因此笔者相信,quasar应该是Corda采用Kotlin开发的最主要原因。
不过,这里要回到开头提出过的一个话题:quasar的选用,显然是Corda作为一个系统在高并发和高可靠性方面的解决方案,与“类区块链”这个领域并没有本质的关系,因此这应该是本文唯一一个脱离区块链概念讨论的议题,主要是因为这个黑科技的吸引力还是蛮大的。
R3首席技术官Richard Brown说,Corda的名字来源有两个:该名字前半部分听起来像“accord”(协议),后半部分来自于“chord”(弦,圆上两点间最短的直线)的定义。这个圆就代表R3网络中的银行。
Notary与共识机制
Notary是Corda网络交易验证和确认的核心机制,这个机制的采用本质上想要解决两方面问题:一是避免因为分布式共识机制而导致交易信息在全网广播,这主要是为了支撑交易信息“适度可见”的能力。
另一个目的是将共识机制与交易流程分开,变成一种标准服务,从而可以采用不同形态的共识实现方式,而非绑定到某种特定算法上。
Notary
Notary是公证人的意思,从字面上就能看出来其作用:就是有一个独立的、交易双方(多方)都信任的角色,来最终确认这笔交易的有效性。
根据前面描述的基本概念可以知道,交易的输入、执行动作以及输出三者关系的有效性是通过智能合约来判断和保证的,因此本质上需要Notary进行判断和保证的就只有交易输入的有效性——某项输入数据没有曾经或正在成为其他交易的输入,也就是保证没有发生“双花”。从这个角度讲,Notary就是比特币的共识机制——区块链——的替代物。
本质上讲,能采用Notary机制来替代区块链模式的共识机制,还是Corda的定位所决定的:一个半信任的网络,参与方和节点的加入都是可以事先经过审核的,即使存在恶意攻击,其种类和形态也和比特币面临的情况完全不同。
事实上,基于Notary进行交易确认的方式,最早是InterLedger提出的——由于InterLedger的目标是跨账本的交易,一个“类区块链”账本系统内部的节点共识算法是无法应用在不同账本之间的,为此必须有账本间认可的(半)信任中介来承担交易确认的职责,Corda的技术白皮书中也确认其Notary的概念来自InterLedger。
Notary的具体实现机制比较简单,交易参与方将交易发送给Notary,发送过程也采用flow的机制实现。Notary接收到交易后,根据自己以往记录的所有交易的输入,查询这个交易的输入是否曾经出现在另一个交易的输入项当中。
如果确认这个交易的输入项都没发生过“双花”,则可以签署交易,此时交易就达到了最终生效(finality)的状态,也就完成了。如果Notary判断交易无效(其实就是发生了“双花”),就会返回异常,交易也就终止了。
从这里也可以看出,使用Notary来做交易确认,本质上是要把交易的所有输入项发给他——由于系统的状态都是不可变的,所以只发输入项就够了。这也就解释了前面所提到的,Corda网络中的状态具有一个Notary属性,这个Notary是当初产生这个状态的交易验证时所使用的Notary。
同时,为了实现上述验证过程,Corda网络也要求一个交易的输入项必须指向同一个Notary,也就是这个交易要提交验证的Notary。如果有些状态不是指向这个Notary,则首先要对这些状态执行Notary变更交易来实现转移。
此外,所谓单一的Notary服务,完全可以是一个网络,其中有多个Notary节点,但是他们依赖同一个数据库来存储信息,或者依赖一个能保证一致性的分布式数据。换句话说,只有各自独立运作,并不依赖一套数据存储的Notary,才能被认为是不同的Notary服务。上面提到的状态在Notary之间转移,指的是真正各自独立Notary之间的关系。
共识机制
提到Corda网络的共识机制可能会有些奇怪,前面刚刚提到Notary从某种意义上说就是“信任中介”,是比特币的区块链模式共识机制的替代物,防止双花由它来保证,Corda网络怎么还会有共识机制呢?
我们首先看看InterLedgr提出的Notary相关的共识机制:由于多个账本的一连串交易应该会有多个中介,因此中介间也要达成共识,并且由于网络复杂性和没有统一的信任机制,这种共识算法也要能够防止拜占庭失效/攻击。
笔者通过对InterLedger描述的共识机制和Corda当中的相关描述,发现一个问题:基于Notary的网络,其“共识概念”存在着歧义:
某个Notary服务本身作为一个分布式系统,节点之间受到网络的影响,可能存在拜占庭失效,这是一个技术问题。各个节点之间需要达到状态同步或者数据一致,需要一个BFT的算法,有时候也称为共识机制。
多个真正相互独立的Notary,如果要共同参与某个交易,由于各自的信息掌握并不完整,如何来达成共识即这个交易没有发生“双花”?本质上这又回到了信息的全局可见性问题。
原则上来说,比特币层面的共识机制指的是后者,通过“信息全局可见+PoW+区块链”的方式实现了共识。目前无论是InterLedger还是Corda,所讨论的共识机制都是前者,这是一个很明显的歧义。
网上有个精彩评论从另一个角度谈到了这一点:Corda网络的Notary可以有很多实现,其中比特币就可以作为Notary的实现——一个全球唯一的、相对低速的Notary;反过来也可以说,区块链就是比特币网络的全局唯一Notary。
由此可见,在Corda网络中,Notary机制的有效性是严格限定在其覆盖范围内的,更大范围的交易验证,必须依赖于一个更广范围的Notary的建立,或者多个原本无关的Notary的协同作业。
而这一点,目前在Corda网络中没有给出参考实现或者实现方面的指导意见,因此Corda网络中Notary的使用、迁移和共识机制在实现层面仍有未解决/论述的问题。
未完待续……
作者简介: 王玮 (wangwei@wecite.com.cn)
“中关村20周年突出贡献奖”获得者,北京微志科技有限公司创始人。主持过世界上最大的基于开放平台和分布式技术的银行账务系统的设计与开发,曾任国家“核高基”国产化中间件应用示范项目副组长等。目前从事区块链技术在金融等领域应用的研究、开发和推广工作。 文章首发于《程序员》杂志,版权归《程序员》杂志所有。
转载/投稿请扫描以下二维码联系