Libra是一个纸老虎吗?Libra技术专业解析 | 技术帖

Libra是一个纸老虎吗?

Libra当然不是一只纸老虎。否则的话,它也不会引起全球金融监管的高度重视,美国国会也不会很快就此召开听证会,调查Libra项目的真实企图和以及它会带来的影响。但是,这个项目本身确实存在着巨大的风险,所以很有可能在其高调推出之后,如果不能对其所一定会面对的各种风险应对合适,就很有可能半路夭折, 其昙花一现的存在因此就更像一只纸老虎。

在Libra消息于6月18日发布之后不久,我在对其分析的一篇研究分析(Libra项目研究分析报告)中就提出,这个项目的一个巨大风险就是项目管理风险。它试图在非常短的时间内完成一个涉及多个方面的范围巨大的项目,因此这个项目一定会遇到非常大的风险,这个项目因此存在着非常大的失败的可能性。本文对Libra的各种风险因素进行进一步的探讨。

一、Facebook并不具备开展此业务的社会支持

Facebook此前因为数据隐私的问题,遭受到社会的一致谴责。它为此不得不支付50亿美元的罚金。Facebook在美国社会中并不具备一个良好的社会形象,并不是被认为一个社交网络的负责任的经营者。实际上在美国社会中,有非常强的反Facebook的势力。

在区块链和加密数字资产的爱好者当中,Facebook绝对也不是以一个正面形象出现的。它在此前的很长的一段时间内,禁止在Facebook的网络中发布关于加密数字货币的广告。这样的行为是同它总体的监管审查的行为是一致的。但这样的行为是同加密数字资产爱好者们的追求是格格不入的。所以加密数字资产爱好者的社群对Facebook是持有非常强烈的批评态度。在这个方面,Jack Dorsey的Twitter与之形成鲜明的对比。实际上Twitter是加密数字资产爱好者们的社交网络。现在Facebook牵头推进这样一个数字稳定币项目,自然不会得到加密数字资产爱好者们的支持。

在传统金融机构方面,Facebook牵头的这个项目更是难以取得共鸣。Libra稳定币及其清算网络同现有的金融机构产生了直接的竞争。更别提传统金融机构还有合规方面的考虑。所以这个项目迄今为止并没有得到任何一家主要金融机构的支持。而主流金融机构的态度会对Libra成功与否起到决定性的影响。

二、监管的巨大阻力

这个项目的稳定币和底层区块链是向现有的金融市场的基本结构做出的直接挑战。现有的各种法币都是各国政府基于自己的主权信用发行。每个法币都有自己的清算网络。由于有各自的清算网络,所以法币之间的流通对全球市场来说并不是高效的。但是对这样的市场现状,各个法币发行政府或机构并没有非常强的动力去改变。但是Libra的底层清算网络却是全球性的。在其之上流通的Libra稳定币也是在全球范围内的。鉴于这样的优势,特别是Libra协会成员的支持,全球市场范围内的货币自然会被吸引到这个网络上来。这就会弱化各个货币发行机构对其所在地和全球经济的影响力。这肯定不是货币发行机构所乐见其成的事情。那么Libra肯定会在这些市场中遇到极强的阻力。

三、无利可图的铸币税

稳定币本质上也是一种产品。如果向市场中推广这种产品,就一定需要有合理的收入。按照这个计划的白皮书,每个节点需要投入1000万美元来参与这个项目。Libra计划设立100个这样的超级节点。因此Libra就会有10亿美元的资金可用。按照这个项目的白皮书,Libra储备会采用现金和短期国债。其运作方式会像一个货币基金。Libra以此方式获得的收益会回馈给这些节点。以此方式产生的收入就类似于参与铸造稳定币这个产品而获得的收入。但是这种模式有两个非常大的缺陷。一个是货币基金产生的收益会非常有限。另外一个更重要的是,这种模式有潜在的风险,有可能导致本金的损失。参与者以此获得的收益有可能是负的。另外,由于经营管理的成本,它比一个单纯的货币基金的成本会更高,所以这10亿美元中能用于购买短期国债的比例就会更小,产生收益的压力就会更大。因此从这个角度分析,如果节点的参与者不能够从其投入的1000万美元能够产生的直接收益之外获得更多的收益(而且还应该是排除风险之外的收益),那么其参与Libra的动力就会大幅减小。

四、难以协调各个法币发行机构的需求

Libra会接受法币抵押,其价格会对标一篮子法币。接受哪些法币做抵押、所对标的一篮子法币种包含哪些法币以及每种法币所占比重多少,都会影响市场中现有法币在市场中的影响力。正是因为这个因素影响重大,所以即使是在白皮书公布时,这些因素也没有最终确定下来,因此也无法公布。这样的不确定性自然引起全球主要货币发行机构的担心和不安。因此,一些金融监管机构的表态并不对这个项目有利。即使是在马库斯在美国国会听证时表明这一篮子法币中将包含50%的美元以及欧元,英镑和日元。但这样的信息肯定不会让全球主要的货币发行机构感到满意。这个项目一定会经历很长的时期同各个主要货币的发行机构进行沟通协调。这些机构是否能对最终的结果感到满意直接决定Libra稳定币是否能在这些经济地区内运行。

五、Facebook巨大的用户数量未能产生预期的作用

Facebook社交网络在全球范围的多个国家内拥有27亿的注册用户。表面上看,这会对Libra稳定币提供海量的潜在用户。但是如果做进一步的分析的话,就会发现这样的用户未必能为稳定币提供大量的潜在用户。

Facebook社交网络用户数量最大的国家是印度。在这个国家中,有2亿4万的Facebook活跃用户。但是,目前印度政府禁止使用加密数字货币。因此这个稳定币就肯定不能在这些用户中使用。而数字稳定币的一个主要应用场景是跨境汇款。而印度又是跨境汇款业务中的最大汇款接收国。这就对Libra稳定币在全球范围内应用于跨境汇款业务产生极大的限制。

在用户的性质方面,Facebook的用户更加是家庭性质的,而不是能够率先尝试新鲜事物的年轻人。在这样的用户群体中推广使用数字稳定币,推进的速度一定会非常慢的。

根据这个项目白皮书,这个稳定币服务的主要对象是全球范围内的目前没有得到金融服务的17亿用户。但是,在这17亿人的用户群体中,能够使用互联网并是Facebook的用户的数量就大打折扣。如果能够满足以上条件的用户所在地区接受稳定币的流通使用,那么稳定币的当地用户就需要有金融机构帮助实现Libra与当地法币的兑换。如果一些用户无法在金融机构开户,这就又会将一些潜在用户排除在外。由于货币的网络效应,一个用户所处的生态,只有当他周围的所有的交易方都使用这个稳定币时,他才能真正的将这个稳定币使用于他的日常经济活动当中。

在主要的经济体当中,即使Libra可以在这些地区运行,它也很难服务这个地区中目前没有获得金融服务的群体。这些用户得不到金融服务的原因是货币和清算网络以外的原因,而Libra稳定币和清算网络对解决这样的问题没有帮助。

六、协会会员的多样性会阻碍Libra的应用推广

首先目前协会的会员的对这个项目的承诺参差不齐。有的成员直接向媒体表明,他们同这个协会签署的协议是意向性的,没有约束力。这就表明这些会员采用的是观望的态度来加入这个协会的。另外有媒体报道,其中的一些成员迄今为止也没有将所承诺的1000万美元投入。所以这个协会在凝聚会员,增强会员承诺方面依然需要有很多工作要做。这将是一个长期的博弈的过程。看看目前欧元组织区的成员的情况以及英国目前的脱欧就会看到这样的组织在此方面的现在和未来的风险会有多大。

这个协会成员的目前的一个巨大的缺陷就是将利益完全对立的各方集中在一个协会当中。而且其中一些成员的目前利益很有可能由于这个项目的发展而受到冲击,因此这些会员的参与一定会妨碍这个项目的推进。在这个方面最典型的代表就是Visa和Mastercard。这两个公司在全球范围内提供信用卡交易的清算网络。提供信用卡支付的各个服务方向收款方收取2%到3%的费用。Visa和Mastercard是这样的业务中的最大的受益者。而Libra却是要在全球范围内提供一个点对点的支持支付的清算和结算网络。这就会直接冲击Visa和Mastercard的现有业务。因此很难相信这两个公司会百分之百地全力支持Libra的推广使用。它们一定会为了维护自己的利益来促使这个协会做出对自己有利的决策。尽管这两个公司是未来的100多名会员中的其中的两名,但它们依然会行使自己的权力影响Libra协会做出对自己有利的决策。其它的大部分会员都是货币和清算网络的使用者,因此它们肯定希望交易的成本越低越好。即使是第三方支付服务商也希望通过降低清算网络成本来增加自己的收益。所以在协会内部的会员之间的争执会是这个协会需要长期面对的问题。

区块链技术支持的共识机制最适合于连接利益共同但又互不信任的机构之间的合作(从维京海盗看DAO的组织原则)。这样的机构通常是同质性的,而且是共同面对强大的共同敌人。这样的共识机制能够保证参与者齐心协力争取共同的利益。但是在这个协会中,协会将利益对立的多方联合在一起,这就肯定会影响协会的推进力量。

总之,Libra项目存在着巨大的风险。这些风险因素至少会导致其不能按照其目前计划的时间表推进,甚至可能导致其失败。Facebook在应对这些风险时,既没有民间社区的支持,又没有强有力的商业伙伴的支持。Facebook是否能成功应对这些风险,这对它来说是一个巨大的挑战。Libra项目是否能成功,我们继续观察。但不管Libra结果如何,它都把区块链技术和加密数字资产的应用推广推上了一个前所未有的高度。至少是基于这点,还是希望它不要成为一个昙花一现的纸老虎。

Libra技术专业解析

第一是背景,为什么要研究Libra?

首先这是与区块链的困境有关的。到目前为止,区块链除了发币和炒币外,还没有成功的商业模式,而且这两个模式在大多数情况下都是不合规合法的。其他商业模式,比如存证溯源积分发票等应用,都不能挣钱,都不是一个成功的商业模式,尽管是可以去做,但这些都是伪需求。

Libra是第1次把区块链和数字货币连在一起,不发空气币,只发与法币价值等价的数字货币,并有等量的法币储备来做价格支撑,而且是合规合法的。当然要合规合法,就不可能是一个公链,因为每个节点都需要是合规合法的,这就是为什么选择了一个联盟链,当然,联盟链的选择也是因为在拜占庭将军协议取得了突破性的进展。是拜占庭将军协议能够高效处理上百个节点。与以前的联盟链相比,比如说fabric hyperledger相比是不一样的,因为以前的联盟链是不发币的,是主要作为一个信息的交流,而不是真正价值的交换,没有币是不可能实现价值交换的。合规合法是联盟链的一个特性,当然以前的联盟链通常是用在产业链,比如说供应链金融里面。其实还没有走过合规合法的流程。Libra是第1个发行一个数字货币走合规合法全流程的联盟链。

尽管Libra是自比特币以来的最大的一个突破,但是,他的愿景和现实的冲突还是巨大的。Libra愿景是为没有银行账户的人群提供银行服务,但是这些没有银行账户的人,他们大多数都生活在当地法币不稳定,或者不能自由兑换的国家和地区,而Libra只能支持稳定的法币,已经发展发达国家,能够自由兑换的法币。所以,Libra他的愿景和现实是有一个根本性上的冲突,这个冲突不是通过技术能够解决的。Libra是一个全球货币,而这些发展中国家,他们的法币不可能是以全球货币的一部分。另外Libra也有它的局限性,至少是现在来看,首先它只支持支付,只支持一个全球数字货币,而且用一个新的MOVE语言。已经有半年了MOVE还没有正式发布,直到现在还是用他的一个中间临时的IR。

Libra的目标及与以前区块链的关系。首先,他的目标是要突破币圈的局限性。币圈只能发币和炒币这两个真正具有商业价值的应用。在币圈里面的所有发行的币,除了比特币包括比特币现金和以太坊外,一般都不能够用来作为支付手段去购买一个真实的东西。那么第一个超越币圈以外的应用,当然就是支付,这就是Libra专注的应用。当然要支付就涉及到必要的安全性,因为这是真金白银。也是当年中本聪发明区块链和比特币的最主要的想法和应用。支付要用到现实社会当中,就需要一定的效率。比如TPS要足够高,这是以太坊和比特币的局限性和EOS的启示,区块链可以做到足够高的效率,TPS可以上千。另外智能合约也是必要的,而且智能合约的安全性是绝对重要的,这是以太坊的启示。因为在以太坊的智能合约里发现了很多漏洞被攻击,所以很难在以太坊上开发一个完全没有漏洞的智能合约,这对于金融应用是非常致命的。Libra核心就是能够有一个MOVE语言,验证器及虚拟机来保证安全,能够逐步做到formal verification完整的验证。可以基本上保证没有代码层的漏洞。

下面就开始讲这个里边儿的核心技术,因为我们这次讲座,主要是讲Libra技术。

首先Libra不是一个区块链,它是一个数据库,是一个能够自我证明的,自然数据的数据库。能自我证明,就是说能够用已有的数据也验证这个数据库的数据是否被修改了,自然数据是说它是随着交易次数不断增加的是不可逆的,不可能回滚的。数据也就是用了这个叫做Sparse Merkle Tree。这也是以太坊用的。


当其中的一些节点数据是不存在的时候,它能够验证说这些节点上的数据是不存在的。也可以验证这个其他有数据的节点上的数据的正确性。它还有一个其他的特性,就是说它能够支持分片sharding。这个对于扩展数据库是非常重要的。还有就是它支持这个并行计算parallel updates。这也是对提高TPS效率非常重要的。另外它也支持并行计算最初的交易的验证和签字的验证,这也是非常重要的。证明:VRF函数Verify(alpha, f, r, pi) 例子alpha = H(h4||H(H(2||r)||h3))

当然Libra也试图考虑用AVL Tree。AVL Tree的核心是一个平衡树。


就是说他试图把这个树的分枝变得更平衡,那么这样储存起来,检索速度最快。下面这张图就是一个AVL Tree表现,你可以看到它是一个非常平衡的树,它没有其中一个枝变得特别长而其他地方没有枝。然后也有人把这个AVL Tree进一步的发展成AVL+ Tree。


左边是AVL+ Tree树装每个节点的数据。右边是这个树的证明。就是对应每个节点的哈希值。这样当这个节点的数据发生变化的时候,那么右边这个证明的树就会改变,这就是用来证明这个数据是否被修改了。其实在Libra里面用到的这个证明函数就很类似于这个VRF的验证函数,里面包括了一个最初值,它的函数,另外就是它们的计算结果和计算结果的证明。 

还有就是Libra的拜占庭将军协议共识所形成的交易是确定的。比特币共识机制是不一样的,就是所有的POW共识的交易都是不是100%确定的。这也是一个很重要的区别。现在LibraBFT有了一个最新的更新,就是说它这个链可以容许有空块的存在和也有临时的侧链的存在。然后能够达到最后一轮LibraBFT共识的就成为最后的主链。

另外就是哈希函数和签名,也是用了一个比较新的技术。他的这个签名是用的ed25519 Edwards Curve Digital Signature Algorithm (EdDSA: 2017)。就是2017年的版本,这个版本应该是说是可以说是Ed25519曲线上的最新的一个算法。那么这个算法的特征就是没有怀疑的NSA的后门漏洞。以太坊和比特币用的是P-256曲线被怀疑有NSA的后门漏洞,也就是为什么这个函数将会被用到TLS 1.3版,在这是在2018年定下来的,就是为了防止NSA留下后门漏洞。EdDSA也是美国标准局NIST在2017年推荐给所有美国联邦政府机构使用的算法。还有就是每次的交易,都会有一个多于2/3(3f+1)的节点间签名。对每一个交易最后都形成一个Shnorr签字。区块链是通过每个块的哈希值连接在一起。Libra数据库则是每个交易都有多于2/3(3f+1)的节点签名而且每个交易都有一个序列号及整个数据库都有一个从创始交易开始的总交易数量版本号来防止重复和回滚。

Block-tree Libra // 区块树的定义


Block // 区块


round ; // the round that generated this proposal 轮数


payload ; // proposed transaction(s) 交易


parent qc ; // qc for parent block 上轮签字


id ; // unique digest of round, payload and parent qc:id


// 上面三个数(轮数,交易,上轮签字)的哈希值


VoteInfo // 投票信息


id, round ; // id and round of block


parent_id, parent_round; // id and round of parent


exec_state id ; // speculated execution state


// speculated new committed state to vote directly on


LedgerCommitInfo // 预计的写入数据库结果


Commit_state_id ; // nil if no commit happens when this vote is aggregated to QC


Vote_info_hash ; // hash of VoteMsg:vote info


VoteMsg // 投票结果


Vote_info ; // a VoteInfo record


Ledger_commit_info ; // Speculated ledger info


sender <- u, signature <- signu(ledger commit info);


// QC is a VoteMsg with multiple signatures


QC // 法定人数签字证书


Vote_info // 投票信息


Ledger_commit_info // 写入数据库结果


signatures; // quorum of signatures 签字


PendingBlkTree ; // tree of blocks pending commitment 预备块的树


PendingVotes ; // collected votes per block indexed by their LedgerInfo hash 收集的块投票


High_qc ; // highest known QC 最高的法定人数签字


Procedure execute_and_insert(b) // 执行和插入


Execute_state_id <- Ledger:speculate(P:parent_qc:block_id; P:id; P:payload)


PendingBlkTree:add(b)


High_qc <- maxround{b:parent_qc; high_qc}


Procedure process_vote(v) // 投票过程


vote idx <- hash(v:ledger_commit_info)


V[vote_idx] <- V[vote_idx] U v:signature


if |V[vote_idx]| = 2f + 1 then


qc <- QC<


vote_info <- v:vote info,


state_id <- v:state id,


votes <- V[vote idx]


>


Pacemaker.advance_round(qc) high_qc <- maxround{qc; high_qc}


Function generate_proposal(cmds) // 提出出块建议


return <


b:round <- current_round,


b:payload <- cmds,


b:parent_qc <- high_qc,


b:id <- hash(b:round || b:payload || parent_qc:id)


>


Function process_commit(id) // 执行数据库更新


Ledger:commit(id)


PendingBlkTree:prune(id) // id becomes the new root of pending

Libra链也包含了一个日志数据库。这个独立的数据库是非常重要的。就是用来写交易输出结果作为验证交易是否成功。如果交易执行了无论成功与否都会写入日志。比如gas费没有了,时间过期了,等等。日志包括这个账号的路径和这个交易的本身以及这个交易的这个序列数。所以这三个在一起就形成了一个唯一的值。这个就是会被用来验证每个交易的有效性。

Libra也用了哈希3的算法SHA3-256。这个也是以太坊用的但比特币没有用。应该是比sha2-256更好。

Libra的公识机制也是建立在最新的拜占庭将军协议进展上的HotStuff。以前如果拜占庭将军协议的节点大于30以后,它的效率就会急剧下降。那么最新的进展HotStuff或其他的,可以是达到上百,甚至上千还仍然保持高效率。拜占庭将军协议的突破性进展才可能使联盟链有上百上千上万的节点数。这是以前做不到的,也就是在比如说fabric和hyperledger里面,是做不到的。下面这张图就是它的一个最核心特征:链块。它是通过三轮由不同的出块者来提出需要共识的块。每轮都有签字而且后面的轮的签字都是建立在上一轮上面的。


每一轮的拜占庭将军协议都是建立在上一轮上的。最后第三轮一起commit写进数据库。图上这个QC就是2/3以上节点的签字证书(法定人数签字证书)。


每轮都包含了这个QC法定人数签字证书。这是每轮里包含的几个数据。就是它的ID,第几个轮,这个交易本身和这个交易时间及签字。

这个图就是说如果是其中有一轮没有达成共识,就是说会是因为gas费用完了或者时间过期了,那么他仍然能够通过第二轮第三轮这个回合来形成达成共识。下面图里的K就是Timeout Certificate (TC)就是未完成轮的法定人数签字证书。


现在的HotStuff拜占庭将军协议的算法上,大概能支撑上百个节点,但是如果要支撑上万个节点的话,那还需要不同的,具有更强扩展性的拜占庭将军协议。BFTree的算法和其中一个。这是一个拜占庭将军协议里的节点树。从这个图当中就会看到,如果是这个有节点没能够达到共识的,那么它会将把这些节点从这个树里面移出去。那么只有形成共识的节点才会留在这个树里面。

 其他还有一种叫做MOCA的共识机制。就像这张图显示的一样,就在这个图当中你会看到一个星号在最右边。就说它的这个节点数可以达到100万,同时它的这个TPS还可以达到上万。,这就是这个共识机制特别的地方。


 还有就是Libra在HotStuff当中没有具体描述和实现的。就是每一步是怎么计算的?每个回合是如何计算的?Libra有一套新的实现,它不是用绝对时间而是用步骤来作为计算,这样就避免了在不同的节点在不同的时间区,会形成不同的时间造成的时间差的问题。

还有就是MOVE语言。MOVE语言的最大的特性就是实现了资金和逻辑的分离。比如说Libra代币就定义为合约的资源或资产部分。合约的逻辑就是模块部分。在Libra里面资产只能产生,销毁和转移但不能复制。就像一个硬件东西只有一个原件没有复制品。下面是MOVE语言的组成部分

a) MOVE语言

├── README.md      # This README 简介


├── benchmarks      # Benchmarks for the Move language VM and surrounding code


├── bytecode-verifier  # The bytecode verifier 验证器


├── e2e-tests         # Infrastructure and tests for the end-to-end flow 端到端测试


├── functional_tests    # Testing framework for the Move language 功能测试


├── compiler          # The IR to Move bytecode compiler 编译器


├── stdlib             # Core Move modules and transaction scripts 标准库


├── test.sh            # Script for running all the language tests 测试脚本


└── vm


    ├── cost-synthesis  # Cost synthesis for bytecode instructions gas费分析


    ├── src     # Bytecode language definitions, serializer, and deserializer代码


    ├── tests          # VM tests 虚拟机测试


    ├── vm-genesis # The genesis state creation, and blockchain genesis writeset创世块


└── vm-runtime   # The bytecode interpreter 执行码

 

b) MOVE编译器把模块和脚本编译成字节码(开发很费时=低效)(Module & Script)

USAGE:


    compiler [FLAGS] [OPTIONS] 编译选项


FLAGS:


    -h, --help        Prints help information 帮助


    -l, --list_dependencies    Instead of compiling the source, emit a dependency list of the compiled source 依赖库


-m, --module Treat input file as a module (default is to treat file as a program) 模块 


--no-stdlib    Do not automatically compile stdlib dependencies 不编译标准库里的依赖库


--no-verify    Do not automatically run the bytecode verifier 不跑验证器


    -V, --version     Prints version information 打印版本号


OPTIONS:


    -a, --address Account address used for publishing 发布的账户地址


    --deps       Path to the list of modules that we want to link with 连接列表


    -o, --output     Serialize and write the compiled output to this file输出文件


ARGS:


Path to the Move IR source to compile 输出文件夹

 

c) MOVE编译器的组成

compiler               # Main compiler crate. This depends on stdlib.


├── ir-to-bytecode   # Core backend compiler logic, independent of stdlib.


│   ├── src


│   │   ├── compiler.rs # Main compiler logic - converts an AST generated by `syntax.rs` to a `CompiledModule` or `CompiledScript`.


│   │   └── parser.rs    # Wrapper around Move IR syntax crate.


│   └── syntax           # Crate containing Move IR syntax.


│       └── src


│           ├── ast.rs   # Contains all the data structures used to build the AST representing the parsed Move IR input.


│           ├── syntax.lalrpop  # Description of the Move IR language, used by lalrpop to generate a parser.


              └── syntax.rs        # Parser generated by lalrpop using the description in `syntax.lalrpop` - a clean checkout won't contain this file.


└── src


    ├── main.rs          # Compiler driver - parses command line options and calls the parser, compiler, and bytecode verifier.


    └── util.rs            # Misc compiler utilities.

这是一个MOVE交易例子。核心是资产Libra coin(import 0x0.LibraCoin;)只能被转账

// A small variant of the peer-peer payment example that creates a fresh


// account if one does not already exist.


import 0x0.LibraAccount;


import 0x0.LibraCoin;


main(payee: address, amount: u64) {


  let coin: LibraCoin.T;


  let account_exists: bool;


  // Acquire a LibraCoin.T resource with value `amount` from the sender's


  // account.  This will fail if the sender's balance is less than `amount`.


  // 提款


  coin = LibraAccount.withdraw_from_sender(move(amount));


  account_exists = LibraAccount.exists(copy(payee));


  if (!move(account_exists)) {


    // Creates a fresh account at the address `payee` by publishing a


    // LibraAccount.T resource under this address. If theres is already a


    // LibraAccount.T resource under the address, this will fail.


    create_account(copy(payee));


  }


  // 存款


  LibraAccount.deposit(move(payee), move(coin));


  return;


}

只有module LibraCoin模块本身才能生成,销毁,合成Libra coin。下面就是对上面Libra账户LibraAccount两个资产转移函数提款和存款的定义(只是用来说明不是真正Libra代码里的)

// 数字货币


module Currency {


// 定义数字货币


resource Coin { value: u64 }


// 存款


public deposit(payee: address, to_deposit: Coin) {


let to_deposit_value: u64 = Unpack<Coin>(move(to_deposit));


let coin_ref: &mut Coin = BorrowGlobal<Coin>(move(payee));


let coin_value_ref: &mut u64 = &mut move(coin_ref).value;


let coin_value: u64 = *move(coin_value_ref);


*move(coin_value_ref) = move(coin_value) + move(to_deposit_value);


}


// 提款


public withdraw_from_sender(amount: u64): Coin {


let transaction_sender_address: address = GetTxnSenderAddress();


let coin_ref: &mut Coin = BorrowGlobal<Coin>(move(transaction_sender_address));


let coin_value_ref: &mut u64 = &mut move(coin_ref).value;


let coin_value: u64 = *move(coin_value_ref);


RejectUnless(copy(coin_value) >= copy(amount));


*move(coin_value_ref) = move(coin_value) - copy(amount);


let new_coin: Coin = Pack<Coin>(move(amount));


return move(new_coin);


}


}

真正的Libra币LibraCoin在Libra代码里的定义如下:

https://github.com/libra/libra/blob/master/language/move-lang/stdlib/modules/libra_coin.move

// Libra币的代码定义


address 0x0:


module LibraCoin {


// 交易


    use 0x0::Transaction;


 // A resource representing the Libra coin


 // The value of the coin. May be zero


 // 币本身


    resource struct T { value: u64 }


 // A singleton resource that grants access to `LibraCoin::mint`. Only the Association has one.


    resource struct MintCapability {}发币权限


 // The sum of the values of all LibraCoin::T resources in the system


// 发币数量


    resource struct MarketCap { total_value: u64 } 


 // Return a reference to the MintCapability published under the sender's account. Fails if the


 // sender does not have a MintCapability.


 // Since only the Association account has a mint capability, this will only succeed if it is


 // invoked by a transaction sent by that account.


// 发默认币数量


    public mint_with_default_capability(amount: u64): T acquires MintCapability, MarketCap{


        mint(amount, borrow_global<MintCapability>(Transaction::sender()))


    }


 // Mint a new LibraCoin::T worth `value`. The caller must have a reference to a MintCapability.


 // Only the Association account can acquire such a reference, and it can do so only via


// `borrow_sender_mint_capability`


// 发新币数量


    public mint(value: u64, capability: &MintCapability): T acquires MarketCap {


    // TODO: temporary measure for testnet only: limit minting to 1B Libra at a time.


    // this is to prevent the market cap's total value from hitting u64_max due to excessive


    // minting. This will not be a problem in the production Libra system because coins will


    // be backed with real-world assets, and thus minting will be correspondingly rarer.


    // * 1000000 because the unit is microlibra


        Transaction::assert(value <= 1000000000 * 1000000, 11);


    // update market cap resource to reflect minting


        let market_cap = borrow_global_mut<MarketCap>(0xA550C18);


        market_cap.total_value = market_cap.total_value + value;


        T { value }


    }


    // This can only be invoked by the Association address, and only a single time.


// Currently, it is invoked in the genesis transaction


// 初始化


    public initialize() {


    // Only callable by the Association address


        Transaction::assert(Transaction::sender() == 0xA550C18, 1);


        move_to_sender(MintCapability{});


        move_to_sender(MarketCap { total_value: 0 });


    }


// Return the total value of all Libra in the system


// 查询系统里币数量


    public market_cap(): u64 acquires MarketCap {


        borrow_global<MarketCap>(0xA550C18).total_value


    }


// Create a new LibraCoin::T with a value of 0


// 发布一个数量为零的币


    public zero(): T {


        T { value: 0 }


    }


// Public accessor for the value of a coin


// 查询币数量


    public value(coin: &T): u64 {


        coin.value


    }


    // Splits the given coin into two and returns them both


// It leverages `Self::withdraw` for any verifications of the values


// 分币:把一个币分成两个


    public split(coin: T, amount: u64): (T, T) {


        let other = withdraw(&mut coin, amount);


        (coin, other)


    }


    // "Divides" the given coin into two, where original coin is modified in place


    // The original coin will have value = original value - `amount`


    // The new coin will have a value = `amount`


// Fails if the coins value is less than `amount`


// 提款


    public withdraw(coin: &mut T, amount: u64): T {


        // Check that `amount` is less than the coin's value


        Transaction::assert(coin.value >= amount, 10);


        // Split the coin


        coin.value = coin.value - amount;


        T { value: amount }


    }


// Merges two coins and returns a new coin whose value is equal to the sum of the two inputs


// 合并两个币为一


    public join(coin1: T, coin2: T): T  {


        deposit(&mut coin1, coin2);


        coin1


    }


    // "Merges" the two coins


    // The coin passed in by reference will have a value equal to the sum of the two coins


// The `check` coin is consumed in the process


// 充值


    public deposit(coin: &mut T, check: T) {


        let T { value } = check;


        coin.value = coin.value + value


    }


    // Destroy a coin


    // Fails if the value is non-zero


    // The amount of LibraCoin::T in the system is a tightly controlled property,


// so you cannot "burn" any non-zero amount of LibraCoin::T


// 销毁币


    public destroy_zero(coin: Self::T) {


        let T { value } = coin;


        Transaction::assert(value == 0, 11)


    }


}

 因为Libra是一个专注支付的系统,所以它并到目前为止并不支持具有双向原子交易的功能,或者就是说,两个币之间进行原子交换的功能。

下面这图是Libra交易流程图。

 Libra的交易流程是交易方首先把请求发到验证节点(第一步)。然后验证节点把请求送到虚拟机去检验请求是否有效的。比如是否有足够的钱、是否签了字、签字是否有效、格式是否正确、等等。如果请求是查询已有的交易,就送到数据库里查询交易然后返回交易信息给请求方(第二步)。如果不是查询而是新的交易,就送到内存池(第三步)。内存池进一步验证交易。比如交易序列号是否是最新的(第四步)。如果是合格的交易就把交易发送给其他验证节点的内存池(第五步)。如果这个验证节点是出块节点,共识层就从内存池里取出所有有效交易作为这个块包含的交易(第六步)。然后发给所有验证节点(第七步)。同时每个验证节点把包含在块里的交易送去执行模块(第八步)。执行模块在达成共识之前将交易送去虚拟机执行(第九步)。执行模块把执行结果加到内存池Merkle Tree里(第十步)。出块节点按照LibraBFT共识机制试图获取3f+1的验证节点签字(第十一步)。如果出块节点获取了足够的验证节点签字3f+1,执行模块就将内存池里的交易结果和Merkle Tree写进数据库(第十二步)。

 Libra链本身有一个叫做命令行的界面。也就是CLI就可以从命令行执行各种命令。然后可以建立一个本地的测试链,就说在一个计算机上可以建一个多节点的测试链。而在多个服务器上建立的测试链,则是比较麻烦。可以从Libra的代码挖掘到所需的信息。这个我们也是最开始是不知道的。那么Libra的主链现在就是pre-mainnet,它实际上是不公开的。包括里面的一些具体的部署是不公开的。这就是联盟链的特征。有些东西是不公开的。

 MOVE语言至今还就是一个IR语言,也就是一个中间过度的语言,还不是MOVE的正式语言,只是一个脚本语言。但是可以用这个脚本语言来写MOVE合约,比如合约里资产的定义和逻辑部分。

数字货币与DeFi

a) 支付与双向交易

i. 支付是一方用货币交易而另一方用提供实物或服务作为交易

ii. 双向交易是双方都用货币交易但是两个不同的货币

b) DEX交易所

i. 挂单

ii. 撮合

iii. 执行交易

c) 借贷

i. 抵押

ii. 利息

iii. 期限

 DeFi是包括支付和双向交易或者说叫做交换。支付是一方用货币进行交易,而另一方用实物,或者服务作为交易。这就是支付是一种单方的交易而交换是一种双方的交易。比如说我用港币换美元,这就是一个交换是两个不同币的交换。这个Libra里的MOVE合约现在是不支持的。但是这个原子交换是今后的DeFi当中的一个最最基本的需求。这个原子交换在区块链当中,现在最受关注的就是分布式或者去中心化交易所。因为中心化交易所的所有问题。当中涉及挂单撮合执行交易,这些都是需要解决这个双向交易或者说原子交换。在这个基础上才可以建立包括借贷抵押利息期限。这些都是智能合约需要完成的,而在以太坊里面已经很成熟了,但是在Libra里面,还没有出现,也就是今后需要把这个已经在以太坊上成熟的这些地方的协议迁移到Libra上面来,把以太坊合约改成MOVE合约。

对Libra和MOVE的预测和期望

 首先是希望这个move的正式版能够发行。这是最重要的。还有就是我们希望Libra能够支持更多隐私交易。一个具体的形式就是链上的交易需要符合监管需求,但是链下的交易可以是全隐私的交易,就像闪电网络里面的支付通道一样,在这个通道里是可以实现全隐私的。但链上的这个交易可以符合监管的要求。这我们想到的一个最佳的组合就是半隐私链上交易,全隐私链下交易。

支持原子交换这是目前区块链最热门的一个话题。下面这个图就是这个原子交换的示意图。


 如果你想要用一个BT C交换等价的ETH。那么你首先是要挂单,然后有人愿意要和你交换。然后你把这个BTC放在一个盒子里面锁上。然后把其中的一把钥匙给另一个人把这个盒子打开但把只能把ETH放进去。这样这个盒子里就有两个币了。两个互相交换后,大家再各自拿出自己需要的。这就是原子交换的一个基本原理,那么怎么去具体实现,这是有不同的做法。

因为现在所有的DeFi协议基本上都是在支持ERC20标准上实现。所以也是希望今后在Libra上发行的数字货币也能支持ERC20类似的标准。这里把ERC20这个标准列出来了。


他有这个几个主要的功能。第1个就是币的总数是多少。就是这个币的发行总数是多少。第二个就是他现在的存量是多少?第三是容许的是多少。转账是多少。授权转账交易。还有就是转账是从哪里到哪里。也有日志这是转账和授权结果。

下面是这个0x协议API。

contract IAuthorizable { // 授权接口


    /// @dev Gets all authorized addresses.


    /// @return Array of authorized addresses.


    function getAuthorizedAddresses()  // 获取已经授权的地址列表


        external


        view


        returns (address[]);


    /// @dev Authorizes an address.


    /// @param target Address to authorize.


    function addAuthorizedAddress(address target) // 添加授权地址


        external;


    /// @dev Removes authorizion of an address.


    /// @param target Address to remove authorization from.


    function removeAuthorizedAddress(address target) // 除去授权地址


        external;


    /// @dev Removes authorizion of an address.


    /// @param target Address to remove authorization from.


    /// @param index Index of target in authorities array.


    function removeAuthorizedAddressAtIndex( // 从授权列表里除去第x名地址


        address target,


        uint256 index


    )


        external;


}






contract IAssetProxy is IAuthorizable // 已经授权的接口


{


    /// @dev Transfers assets. Either succeeds or throws.


    /// @param assetData Byte array encoded for the respective asset proxy.


    /// @param from Address to transfer asset from.


    /// @param to Address to transfer asset to.


    /// @param amount Amount of asset to transfer.


    function transferFrom( // 从地址xxx向地址yyy转账


        bytes assetData,


        address from,


        address to,


        uint256 amount


    )


     external;


    /// @dev Gets the proxy id associated with the proxy address.


    /// @return Proxy id.


    function getProxyId() // 获取代理ID


        external


        view


        returns (uint8);


}

 你可以看到0x协议API。首先是已经取得授权地址列表。然后就是给一个地址授权。就是把某个地址加到这个授权里面。还有就是取消某个地址授权的授权或从授权的地址列表里去掉。如果已经代理授权了,就可以从哪里到哪里转账了。最后就是获取这个代理ID。


这个图是一个很简单的分布式交易所或去中心化交易所。有一个买家taker和卖家maker。卖家首先是把这个交易挂单order到订单表orderbook。买家看到了后就通过0x协议API吃单execute order。0x智能合约就把挂单和吃单分别发送到买家和卖家。这个中继层Relayer是最重要的。这些都是在MOVE合约里可能实现的。

Libra 链开发进展

Master 代码每天 几十个 commit 更新几百个文件

测试链每两周更新一次(开始时从每天到每周) 最近一次是一个月之后

预计 2020 年 3 月底出 beta 版

预计 2020 年 6 月底出第一版

预计 MOVE 语言正式版应该在 beta 版里发布

监管方面

2020 年也是美国大选年。在 2020 年底前上线应该是在美国大选后上线当然取决于大选局势。

Facebook Pay法币支付:进展不顺也是必要的实习过程和双管齐下的做法。

Libra是否最终支持多种数字货币:Facebook Pay应该支持多种法币。

MOVE合约中资产和程序的分离是移植以太坊上虚拟币DeFi协议的核心挑战。

需要重新思考建立在资产和程序分离上的真金白银数字货币DeFi协议而不是虚拟币DeFi 协议。在Libra上开发数字货币DeFi要在2020年后了,真金白银的数字货币DeFi将会建立在Libra上。

MOVE VM将会归顺于WAVM。

参考资料:

[1] 零壹财经谷燕西专栏:libra是一个纸老虎吗?

[2] 魔笛手开发社区libra分享讨论内容

本文图片源于网络,如有侵权,请联系删除。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值