本文为Why and How zk-SNARK Works: Definitive Explanation论文学习心得,纯粹个人在阅读过程中的疑问和思考,读后感受到数学之美。详细的理解请阅读附录引用的文章。(PS. 于24年7月重读文章,并且根据最新理解更正了之前的不少理解错误。仍在学习中,错漏之处敬请指教)

零知识证明从原始逻辑,简化到一阶约束电路(rank-1 constraint system, R1CS),再等同转换为多项式(quadratic arithmetic program,QAP)。这个过程的逻辑可以参考V神的文章。零知识证明的最终都落脚到对多项式的证明。

Read more »

Dunbar项目是BIS新加坡创新中心,the Reserve Bank of Australia (RBA), the Bank Negara Malaysia (BNM), the Monetary Authority of Singapore (MAS) and the South African Reserve Bank (SARB) 在2021年合作实验项目,意在研究批发型CBDC在跨境结算中发挥的作用,并在同年11月公开发布研究报告。具体参见BIS的项目介绍Project Dunbar: international settlements using multi-CBDCs

Dunbar项目的探讨了跨境支付,FX等场景,与其他的跨境批发CBDC项目(例如Jura, mBridge等)关注点基本一致。同时,报告中也有其独特的有意思的一些设计。
1.项目的组织。项目拆分为设计和技术开发两个工作组,职责分离;设计工作组着眼于业务需求,包括交易流程设计,合规监管,治理模式等;而作为试验性的项目,技术开发采用了Corda(账本隔离,只能看到己方相关交易信息,不存在全局一本帐)和Quorum(类企业级以太坊,以dApp智能合约的方式按币种逻辑隔离,用Tessera方案解决隐私)两种常用的DLT技术路线并行开发原型,探讨不同的技术路线对于需求的满足度。整个过程采用敏捷开发的方式,拆分迭代,适合这种多团队间的合作。

图1 拓扑

2.角色的划分。虽然项目的目的是为了解决当前跨境支付中依赖中介,导致交易链路长,耗时多,费用高等痛点,但考虑到实际中由于参与银行的规模,从属等,也试图最大程度利用代理银行的优势。项目将参与各方划分成以下多个角色职责,主要关注银行的划分。特许银行(一般是规模大实力强的本地银行)承担最多的职能,包括与传统支付系统互联,执行CBDC交易,登入其他非特许银行/非本地银行,对其进行AML审查等。相比其他项目里只考虑了直参,dunbar在角色设计考虑的更多,并且也赋予此类特许银行更高的权限,参与到整个项目的治理中,而并非仅仅只是规则遵守者。

图2 参与者角色

由于各参与方(主要是商业银行)的职责和参与度不同,跨境支付场景下的流程简化如下。其中,只有收付双方的Sponsor bank都执行完AML等风控措施通过后,批准执行交易,此交易才会在智能合约里执行。

图3 跨境支付流程

对于FX,则对比了多个模型,其中考虑到AMM(Automated market- making)这种在加密资产业界常用的方式。具体的本期没有过多的展开和实现,留到将来的研究。

图4 FX模型

3.未来多平台互联。报告最后预测了将来的multi-CBDC平台会是多个地区性平台互联组成的一个通用平台,而不是全球唯一的。下一步的工作是保证这些平台的互联互通。个人深以为然,在当前BIS的牵头下已经存在了多个类似项目的持续试验和演进中,在技术上是可行的,在治理方面,各平台方有各自协商一致的治理方式,合规等,比起传统swift仅仅只是消息系统,当前的mCBDC平台赋予了更多的能力,及时结算,这个与各辖区的法令和风控制度等也有很大的关联,一个全球参与建设的平台从协商组织上难度也很大,最后很容易沦为寡头政治的金融工具。因此,当前BIS牵头的多个mCBDC平台在齐头并进,并且有更多的项目也在新增研发中。同一个实体同时参加不同的项目,不同的区域性性平台,也是会出现的。

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 DLTgithub源码,虽然时间比较早,但是其算法设计仍可以参考,包括前一期IL2项目,也是明确提到参考了本实验的实现。

Read more »

本文基于BIS于2021年9月发布的Inthonan-LionRock项目的二阶段报告Inthanon-LionRock to mBridge: building a multi CBDC platform for international payments。本阶段结束后,新增了中国大陆央行和阿联酋央行,项目也被重新命名为mBridge,也就是现在熟知的多边央行数字货币桥项目。

Read more »

Inthonan-LionRock项目是多边央行数字货币桥项目mBridge的前身,由BIS香港创新中心,泰国央行(BOT),香港金管局(HKMA)合作实验项目,意在研究批发型CBDC在跨境结算中发挥的作用。Inthonan-LionRock项目阶段一早在2019年9月启动,2020年1月宣布结束,并且发布了项目的研究报告。本分析完全基于BIS官网公开的项目研究报告Inthanon-LionRock : Leveraging Distributed Ledger Technology to Increase Efficiency in Cross-Border Payments。虽然项目时间较为久远,但仍有参考学习意义。

Read more »

Jura项目是BIS创新中心,Bank of France,Swiss National Bank在2021年合作实验项目,意在研究批发型CBDC在跨境结算中发挥的作用,并在同年12月公开发布研究报告。具体参见BIS的项目介绍Project Jura - Cross-border settlement using wholesale CBDC

图1 拓扑

项目的主要技术服务商是R3,技术架构就采用了Corda。这个是wholesale CBDC的场景,Corda的性能和设计理念也算比较契合。

  1. 资产代币化asset tokenize。商业票据Comercial Paper(CP)由DAR生成数字资产,通过Gateway(也就是图中的NATIXIS)mirror映射到平台上,同时赋予了所有者等属性。对应到Corda里的概念,就是state,可关联到实际环境中的资产和条款等。Corda的这种设计,将wCBDC和CP在技术逻辑上一致,使得这个单一的第三方运营的SDX测试平台可以用相似的逻辑去支持PvP和DvP交易。
  2. 发行/赎回。SDX平台有几类节点,Notary node, Issuer node, Monitor/Observer node监管节点, Bank node。其中,Issuer node跟RTGS完成传统账户体系的兑换。在白皮书里提到 “In Project Jura, EUR and CHF wCBDC and the NEU CP token on the SDX test platform had no legal force, meaning that the wCBDCs did not represent a direct central bank liability.” 这点感觉更多的是强调非直接央行负债,实际上是明确了issuer居中转换的必要地位。
  3. 不同的资产类型通常属于司法管辖区,由不同的notary公证人节点,通常由该资产管理员角色来承担,例如商行,或者授权的管理者。由于Corda的无需全局广播共识的设计,因此单个种类资产的交易情况,只需要该资产的notary进行签署,保证了账本或者资产管辖的独立性隔离性。由于notary节点通常只是技术意义上的,不授权查看具体的交易内容,通常引入监管节点来监控具体的交易(一种办法是只需在交易规则上配置有效的交易需要监管节点签名)。
  4. 子网划分。各个央行可以独立划分和管理子网,允许商行节点接入子网进行业务,实际上就是实现了对其管辖货币的准入机制,只有接入该子网的商行节点才能执行该种资产的业务。在本次实验的拓扑中,银行节点是物理网络联通的,这在实际情况中由于网络策略管控,特别是随着银行借点数量增加,往往是不可全联通的。一种替代方案是参考DAR的类似做法,通过每个央行子网引入Operator Node(可以是逻辑的,与其他角色的node,例如Observer Node共用)作为Gateway,同时不同子网Gatewa互联,本国的商行只与本国的Gateway联通,把全网变成雪花拓扑结构。跨司法领域的,例如外币兑换等,就需要通过Gateway与他国商行交互,这种路由方式可以由全局的网络地图服务提供。这种方式,使得每笔交易都经过了交易双方央行及交易货币对的所属央行,满足监管需要。
  5. DvP,PvP的交易,涉及两种资产在两个子网的处置,需要两种资产的notary的签名赋予有效性。为保证交易的原子性,引入了R3的dual-notary signing机制,即哈希时间锁算法(在前面的bitcoin闪电网络部分有介绍过),常用的跨链方案。具体参看Jura项目白皮书附录部分。
图2 dual-notary signing机制

Corda的设计理念

R3 Corda: A Distributed Ledger Designed for Financial Services : R3 CTO在2016年设计之初分享的设计理念及心路历程

  1. 专门针对金融场景开发,而非通用区块链。受区块链思想的影响,在很多设计理念上考虑了当前金融领域的特点和经典场景。
    • 交易不再全局广播,只在相关方可见;
    • 引入可信公证人机制;
    • 没有经典的区块&全局一条链的设计等等;
  2. 借鉴了区块链经典思想,回归到本质:共识,有效性,唯一性,不可篡改性,可验证性。
    • 使用公证人机制防止双花;
    • UTXO模型,从单纯的资产扩展到状态;
    • 签名放篡改抵赖;

无链之链,非链之链。更恰当应该叫分布式账本DLT。基于金融领域真实存在的一些假设和前提(例如存在可信公证人),更像是借鉴区块链思想去解决金融领域的实际问题,提升效率。

Read more »

场景描述

系统需要每个小时启动多个定时任务,分别与若干个第三方系统进行交互,执行批处理任务。各个批处理定时任务具备强独立性,即第三方系统间相互独立,即A系统的失败不影响B系统的任务;同一系统各个批次的任务相互独立,即A系统0点的任务失败不影响1点的任务。批处理任务的实时性要求低,且存在一定的失败概率(原因可能来自本系统,也可能是第三方系统)。如果是因为系统bug,则此修复时间可能会相对较长。因而,容易积累大量的失败历史任务。失败的任务可以并且需要重试,同时重试不能影响当前时刻正常运行的任务。因为重试过程同样占用系统资源,因此需要限制每个小时重试的任务数。当存在大量的失败任务时,需要相应的调度策略来从中选择重试的任务。

策略一: 平均主义

基本策略

轮询的方式,每个小时重试选择updateTime距今最久远的任务(重试的时候会更新updateTime)。同时设置重试任务的createTime阈值(例如最近一个月),早于此时间创建的任务将不再自动重试,需要人工介入。保证任务调度相对公平,每个任务重试的间隔大致相同,历史任务避免饥饿问题。

遇到问题

  1. 实际运行过程中发现此方案无法很好的应对系统抖动。当本系统恰好在正常任务调度时刻进行系统更新,导致本批次所有定时任务都失败。同时存在A系统因为其系统bug,每个批次都是失败状态。由于积压了大量的A系统的历史失败任务,并且优先重试最早的任务,导致本批次的所有任务被挤压到重试队列的最后。即先把A系统的历史任务都重试,导致A系统外的所有系统被影响,甚至可能需要等上若干天。间接破坏了系统间的独立性。
  2. 极端情况下,当全局只有唯一失败任务,并且该任务理论上无法成功时,该任务仍然会被每小时重试,浪费系统资源。

策略二:指数退避

改进思路

  1. 原则上,最近失败的更新鲜的任务应该是被调度重试的优先级更高,而且被重试的频率概率更高。
  2. 对于历史失败任务,不再每个小时都尝试去重试,以减小系统压力。

具体方式

  1. 采用指数退避方式,退避间隔以2的指数增长,最大间隔32小时。例如,0点的任务,计划重试的时间依次为: 1点,3点,7点,15点,第二天7点(+16),(+32),(+32), …。 在间隔内的其他时刻,例如2点,4点,5点等,不再尝试重试。
  2. 对于每个失败任务,按照以下方式粗略计算优先级,由高到低排序选择。若当前时刻在下一次计划重试前,则计算所得的priority非正数,该任务需要被过滤掉不在当前时刻重试。
1
2
3
4
priority = (backoffToNow + 1) / (createToUpdate + 1)

priority:优先级
backoff:下一个计划重试时刻

若干简单案例

  1. 0点的任务,更新时间是1点(上次重试),当前时间是2点,下一个计划重试时间3点,计算出来 p = (2-3+1) / (1-0+1) = 0, 非正数,意味下一个计划调度时间在未来,当前时刻不尝试。
  2. 当前时间2点,两个任务,第一个是0点的任务,计划1点重试,由于1点时候存在大量重试任务(例如0点批次所有系统都失败),重试名额有限没有被选择;第二个任务是1点的,计划2点重试,计算出来 p1 = (2-1+1) / (1-0+1) = 1p2 = (2-2+1) / (2-1+1) = 0.5,任务1的优先级更高。虽然两个任务都是第一次调度,但任务1的计划时间更早,也就是滞后其计划重试时间更长。
  3. 当前时间7点,两个任务,第一个是0点的任务,更新时间是3点(第二次重试),计划7点重试;第二个任务是4点的,更新时间是5点(第一次重试),也是计划7点重试,计算出来 p1 = (7-7+1) / (3-0+1) = 0.25p2 = (7-7+1) / (5-4+1) = 0.5,任务2的优先级更高。虽然两个任务都是当前时刻计划重试,但任务2更新鲜,重试次数更少。
  • 以上仅仅是以简单的方式来选择任务,并非精确计算,有可能在更复杂的组合情况下优先级排序存在问题。**但基本上能保证在新鲜的任务在较短的时间内得到充分的尝试,历史任务得到的机会将会快速衰减。**由于所有任务采用相同的退避策略,仅仅是因为新鲜度导致退避间隔差异,可以认为仍然保留公平性。此方案更多强调应对系统的抖动,同时隐式的认为历史任务的价值随着时间的推移逐步的降低。

未来工作

考虑到存在个别系统的bug导致存在大量的失败任务,可引入公平队列,防止单个系统占据了绝大部分的系统资源。

合约里经常会包含有事件(event关键字),应用通过监听链上指定合约的指定事件,从而得到相应的数据触发相应的处理,也就是不同的系统不再需要链下的交互(api调用等),在这里链扮演了类似持久化的消息队列的角色。在多数场景下,对于链上事件,应用有着可以重复读,可以从指定块开始读,不能丢失事件等等的需求。应用监听智能合约事件,常见有主动轮询链节点和向链节点订阅推送的方式。当单个应用存在多个实例时,需要在各个实例间协调,避免对同一合约事件的重复处理。同时,当前监听实例一旦下线,对于该合约事件的处理需要由其他实例从当前位置接着消费(应用需要额外设计实现协调机制保证不丢事件不重复消费)。本方案将事件监听和消费协同的功能交给中间件及消息队列等组件。应用无需再额外实现实例间的协调机制,只需要负责从消息队列里消费就可以,保证消息at-least-once消费。一次注册,就可满足单应用多实例甚至多应用的共享。

Read more »

合约运行的可回溯重复执行及执行确定性要求,合约执行过程使用的数据必须被记录,可以采取记录在链上预言机合约内(公链),或者是合约的含预言机返回值的执行凭证(联盟链,用于事后审计)。对于前者,使用链上预言机主要分成三种方式:

  1. “立即读取” : 用户合约直接访问预言机合约读取所需数据。(预言机数据可能被更新,导致多次读取不一致。需要结合数据版本等机制保证,较为复杂)
  2. “订阅发布” : 关注预言机数据的变化。可以预言机合约在数据变动时,同时发出合约事件。链下应用监听特定的合约事件,然后相应的调用用户合约。本质上还是链下发起的上链交易,区别只是触发时机。
  3. “请求响应” : 由用户合约执行时组装请求(常见的HTTP请求)向预言机合约请求数据,并且附带回调API。链下的预言机应用监听预言机合约,向外部系统请求数据,然后回写到预言机合约(上链或分布式账本)。然后预言机合约将改响应数据回调前述的用户合约声明的回调API。可以是用以GET获取数据合约内计算,也可以是POST链下应用系统进行复杂计算,获取计算结果。此过程的关键在于保证传输过程的完整性真实性,即防止预言机合约的传递篡改以及数据源作恶。
Read more »