Ubin项目是由新加坡金管局(Monetary Authority of Singapore, MAS)主导的旨在探索利用DLT技术在支付/证券领域的清算结算可行性的研究项目。这个是一个跨度多年多阶段的长期项目,始于2016年,截止当前已完成了5个阶段的实验和研究报告。同时Ubin项目也为另一个跨境CBDC项目Dunbar提供了技术基础。具体可以参见MAS的官网的Ubin项目介绍及BIS的项目介绍。本文只谈早在2017年11月完成的阶段2里的队列管理和gridlock的关键理解,主要基于其研究报告Project Ubin Phase 2: Re-imagining Interbank RTGS using DLT及github源码,虽然时间比较早,但是其算法设计仍可以参考,包括前一期IL2项目,也是明确提到参考了本实验的实现。
这个实验的关键设计主要分Fund chansfer, Queue mechanism, Gridlock resolution三大部分,DLT技术也采用了业界最普遍的Corda,Hyperledger Fabric,企业级以太坊Quorum三大技术路线分别实现。同时,交易的隐私性也是方案设计的重点。以下分析下各自的核心实现。
Hyperledger Fabric
- 利用channel特性的天然的隔离性,在每两个银行之间建立双边交易channel,保护交易隐私。银行对channel维度的账户以及双边队列情况都是可见的。因此,双边的交易就可以很方便的实现净额结算。MAS也是channel的一个参与方。但是,金额被锁定在channel级别上,不同channel间的流动性调拨会较为频繁的发行/注销。
- chaincode记录的交易状态为“排队中”,“已完成”。双方可见,不需要保留两个独立的入向和出向队列。当发生抵押,channel间的资金调拨,收入,撤销排队,调整优先级等,会自动触发应用层调用chaincode进行队列解救或者调整,修改交易状态。解救顺序按优先级高低,入队列从早到晚。
- gridlock的解决方案使用EAF2算法。除了上述的双边交易channel外,还有全局的多边netting channel。每个银行将各自相关的排队交易指令集(包含收入和支出)提交到netting channel上的netting chaincode。chaincode实现了EAF2算法,会决定全局的解决方案。在netting channel上只能看到交易id,以及每个银行每次提交的总净额,不含具体的交易信息,保护隐私。每一轮gridlock仲裁由银行主动触发和主动加入。在仲裁期间发生的新交易,也应加入队列。
- EAF2算法需要银行进行多轮交互。大致思路是,每次银行按照顺序轮流提交交易指令集,保证其提交的指令集如果得以全部执行,结算后其自身的余额(结算钱余额+交易净额)不为负数。如果其间银行发行全部执行后为负,则按金额数从大到小逐笔去掉支出交易直到余额为正,也就是尽可能的满足更多的交易。B银行去掉的这笔支出是A银行的收入,因此A银行也需要按照这个思路重新进行计算,重新提交。进而引起链式反应,直到最后所有的银行结算后余额都不为负数,并且每笔交易在此次仲裁期间都能找到匹配的收付双方。然后各银行再按照得到的全局视图进行最终结算。(如果存在不同优先级的交易,如何处理?是保证优先级高的得以先结算,还是保证最大程度的解救队列?待后续研究。)
Quorum
- 使用双边的private contract来进行两方的交易,使用public contract来记录所有参与方的余额。合约里加盐隐藏余额名额,交易的收付双方基于转账金额和余额使用零知识证明来同时提交证据,保护隐私,同时全网各方验证也保证交易的有效性,没有非法的发行/注销资金。
- 队列管理。全局的gridlock queue也记录全局的排队交易ID用以触发gridlock解锁。每个银行都维护private queue,记录交易的具体内容,只有交易双方可见。头寸不足时,交易会同时提交到这两个queue,当银行的流动性得到补充时,使用新头寸来解救队列,修改queue里记录。
- 同样使用EAF2算法。当gridlock queue里数量达到预设的阈值时,触发进入新一轮的仲裁。
EAF2的算法执行使用合约进行计算,算法是确定的,因此合约计算是可行的。计算出来的结果,需要保证最终解决方案里的交易都同时执行成功或者失败,涉及的银行的余额也是原子性的同步更新成功。同时,分布式的使用EAF2算法时,排队交易需要对接收方是可见的,因为需要将收入纳入计算。从这个实验中可见在这两个前提条件下,去中心化的LSM方案是可以实现的。
Corda
- 局部账本天然的保护隐私;同时每次交易交易双方新生成密钥对,匿名身份,一次一密防止身份追踪。
- 头寸不足时,在账本里记录为负债状态;负载的详细信息记录在发起方队列里。同时,定时调度任务触发结算API,如果头寸充足就解救队列。
Goodbye 2023 👋