8BTCCI: 11594.73 -0.44% 8BTCVI: 5449.75 +1.31% 24H成交额: ¥3676.68亿 -0.04% 总市值: ¥16308.26亿 -0.11%
Libra区块链论文解析——引言、数据逻辑模型(part 2)

Libra区块链论文解析——引言、数据逻辑模型(part 2)

格密链 发布在 海盗号 34397

整个技术论文分为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发展规划

继续分析第2节:逻辑数据模型。

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

每个资源都属于一种类型,该类型由模块所定义。资源的类型由资源名称、资源所在模块的名字与地址构成。例如在图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
评论
登录 账号发表你的看法,还没有账号?立即免费 注册