Fabric(v2.0)官方文档-开发应用程序-场景、分析、流程和数据设计

本主题包括如何开发客户端应用程序和智能契约,以使用超分类结构解决业务问题。在涉及多个组织的真实商业票据场景中,您将了解完成此目标所需的所有概念和任务。

本主题是为多种受众设计的:

  • 解决方案和应用程序架构师
  • 客户端应用程序开发人员
  • 聪明的合同开发人员
  • 商业专业

场景

在本主题中,我们将会描述一个涉及六个组织的业务场景,这些组织使用基于 Hyperledger Fabric 构建的商业票据网络 PaperNet 来发行,购买和兑换商业票据。我们将使用该场景概述参与组织使用的商业票据应用程序和智能合约的开发要求。

PaperNet 网络

PaperNet 是一个商业票据网络,允许适当授权的参与者发行,交易,兑换和估价商业票据。

Fabric(v2.0)官方文档-开发应用程序-场景、分析、流程和数据设计

PaperNet 商业票据网络。六个组织目前使用 PaperNet 网络发行,购买,出售,兑换和估价商业票据。MagentoCorp 发行和兑换商业票据。 DigiBank, BigFund,BrokerHouse 和 HedgeMatic 互相交易商业票据。RateM 为商业票据提供各种风险衡量标准。

让我们来看一下 MagnetoCorp 如何使用 PaperNet 和商业票据来帮助其业务。

介绍演员

MagnetoCorp 是一家备受推崇的公司,生产自动驾驶电动车。在 2020 年 4 月初,MagnetoCorp 公司赢得了大量订单,为 Daintree 公司制造 10,000 辆 D 型车,Daintree 是个人运输市场的新进入者。尽管该订单代表了 MagnetoCorp 公司的重大胜利,但在 MagnetoCorp 和 Daintree 正式达成协议后六个月,Daintree 将于 11 月 1 日开始交付之前不需要支付车辆费用。

为了制造这些车辆,MagnetoCorp 公司将需要雇佣 1000 名工人至少 6 个月。这对它的财务状况造成了短期压力,– 每月需要额外 500 万美元来支付这些新员工。商业票据是为帮助 MagnetoCorp 公司克服短期融资需求而设计的,每月基于 Daintree 公司开始支付 D 型车辆费用时就会有充足现金的预期来满足工资单。

在五月底,MagnetoCorp 公司需要 500 万美元才能满足 5 月 1 日雇佣的额外工人。要做到这个,它会发行一张面值 500 万美元的商业票据,未来6个月到期 – 当预计看到 Daintree 现金流时。DigiBank 认为 MagnetoCorp 公司是值得信赖的,因此,不需要高于*银行 2% 基准利率的溢价,这将会使得今天价值 495 万美元,在6个月时间后价值 500 万美元。所以它以 494 万美元的价格购买了MagnetoCorp 公司 6 个月到期的商业票据 – 与 495 万美元的价值相比略有折扣。DigiBank 完全预计它将能够在 6 个月内从 MagnetoCorp 赎回 500 万美元,因此承担与此商业票据相关的风险增加,使其获利 10K 美元。

在六月底,MagnetoCorp 公司发行一个 500 万美元的商业票据来支付六月份的工资单时,被 BigFund 以 494 万美元购买。这是因为六月的商业条件与五月大致相同,导致 BigFund 以与 DigiBank 五月份相同的价格对 MagnetoCorp 商业票据进行估值。

接下来的每个月,MagnetoCorp 公司可以发行新的商业票据来满足它的工资义务,这些票据可以被 DigiBank 或其他任何在 PaperNet 商业票据网络的参与者购买 – BigFund, HedgeMatic 或 BrokerHouse。这些组织可能会根据两个因素为商业票据支付更多或更少的费用 – 央行基准利率和与 MagnetoCorp 相关的风险。后者取决于各种因素,如 D 型车的生产,以及评级机构 RateM 评估的 MagnetoCorp 公司的信誉度。

在 PaperNet 中的组织具有不同的角色,MagnetoCorp 发行票据,DigiBank、BigFund、HedgeMatic 和 BrokerHouse 交易票据,并且 RateM 评估票据。具有相同角色的组织,比如 DigiBank、Bigfund、HedgeMatic 和 BrokerHouse 是竞争对手。不同角色的组织没有必要是竞争对手,但是可能还是具有不同的商业利益,比如 MagentoCorp 想要给它的票据一个高的评估来卖出高价,然而 DigiBank 会从一个低的评估来获利,因此他们可以以一个地的价钱买入。我们能够看到,像 PaperNet 这样一个非常简单的网络,也可以有非常复杂的关系。一个区块链能够在彼此是竞争对手或者具有相反的商业利益并且可能造成争议的组织间帮助创建信任。其中 Fabric 能够创建更细粒度的信任关系。

让我们暂停 MagnetoCorp 的故事,开发 PaperNet 用于发行,购买,出售和兑换商业票据的客户应用程序和智能合约以获取组织之间的信任关系。稍后我们将回到评级机构 RateM 的角色。

分析

受众: 架构师,应用和合约开发者,业务专家

让我们更详细的分析商业票据。MagnetoCorp 和 DigiBank 等 PaperNet 参与者使用商业票据交易来实现其业务目标 – 让我们检查商业票据的结构以及随着时间推移影响票据结构的交易。我们还将根据网络中组织之间的信任关系,考虑 PaperNet 中的哪些组织需要签署交易。稍后我们将关注买家和卖家之间的资金流动情况; 现在,让我们关注 MagnetoCorp 发行的第一个票据。

商务票据生命周期

票据 00001 是 5 月 31 号由 MagnetoCorp 发行的。花点时间来看看该票据的第一个 状态,它具有不同的属性和值:

 
  1. Issuer = MagnetoCorp

  2. Paper = 00001

  3. Owner = MagnetoCorp

  4. Issue date = 31 May 2020

  5. Maturity = 30 November 2020

  6. Face value = 5M USD

  7. Current state = issued

该票据的状态是 issue 交易的结果,它使得 MagnetoCorp 公司的第一张商业票据面世!注意该票据在今年晚些时候如何兑换面值 500 万美元。当票据 00001 发行后 Issuer 和 Owner 具有相同的值。该票据有唯一标识 MagnetoCorp00001 – 它是 Issuer 属性和 Paper 属性的组合。最后,属性 Current state = issued 快速识别了 MagnetoCorp 票据 00001 在它生命周期中的阶段。

发行后不久,该票据被 DigiBank 购买。花点时间来看看由于 购买 交易,同一个商业票据如何发生变化:

 
  1. Issuer = MagnetoCorp

  2. Paper = 00001

  3. Owner = DigiBank

  4. Issue date = 31 May 2020

  5. Maturity date = 30 November 2020

  6. Face value = 5M USD

  7. Current state = trading

最重要的变化是 Owner 的改变 – 票据初始拥有者是 MagnetoCorp 而现在是 DigiBank。我们可以想象该票据后来如何被出售给 BrokerHouse 或 HedgeMatic,以及相应的变更为相应的 Owner。注意 Current state 允许我们轻松的识别该票据目前状态是 trading

6 个月后,如果 DigiBank 仍然持有商业票据,它就可以从 MagnetoCorp 那里兑换:

 
  1. Issuer = MagnetoCorp

  2. Paper = 00001

  3. Owner = MagnetoCorp

  4. Issue date = 31 May 2020

  5. Maturity date = 30 November 2020

  6. Face value = 5M USD

  7. Current state = redeemed

最终的兑换交易结束了这个商业票据的生命周期 – 它可以被认为票据已经终止。通常必须保留已兑换的商业票据的记录,并且 redeemed 状态允许我们快速识别这些。

通过将 Owner 跟交易创建者的身份进行比较,一个票据的 Owner 值可以被用来在 redeem 交易上进行访问控制。Fabric 通过 getCreator() chaincode API. 来对此提供支持。

如果 golang 作为一个链码的语言,client identity chaincode library 可以被用来取回交易创建者的额外的属性。

交易

我们已经看到票据 00001 的生命周期相对简单 – 由于 issuebuy, 和 redeem 交易,它在 issuedtrading 和 redeemed 状态之间转移。

这三笔交易由 MagnetoCorp 和 DigiBank(两次)发起,并推动了 00001 票据的状态变化。让我们更详细地看一下影响票据的交易:

发行

检查 MagnetoCorp 发起的第一笔交易:

 
  1. Txn = issue

  2. Issuer = MagnetoCorp

  3. Paper = 00001

  4. Issue time = 31 May 2020 09:00:00 EST

  5. Maturity date = 30 November 2020

  6. Face value = 5M USD

观察 发行 交易是如何具有属性和值的结构的。这个交易的结构跟票据 00001 的结构是不同的但是非常匹配的。那是因为他们是不同的事情 – 票据 00001 反应了 PaperNet state,是作为 issue 交易的结果。这是在 发行 交易背后的逻辑(我们是看不到的),它带着这些属性并且创建了票据。因为交易 创建 了票据,着意味着在这些结构之间具有着飞铲更密切的关系。

在这个 发行 的交易中唯一被引入的组织是 MagnetoCorp。很自然的,MagnetoCorp 需要对交易进行签名。通常,一个票据的发行者会被要求在发行一个新的票据的交易上提供批准。

购买

接下来,检查 buy 交易,将票据 00001 的所有权从 MagnetoCorp 转移到 DigiBank:

 
  1. Issuer = MagnetoCorp

  2. Paper = 00001

  3. Current owner = MagnetoCorp

  4. New owner = DigiBank

  5. Purchase time = 31 May 2020 10:00:00 EST

  6. Price = 4.94M USD

了解 buy 交易如何减少票据中最终的属性。因为交易只能修改该票据。只有 New owner = DigiBank 改变了;其他所有的都是相同的。这没关系 – 关于 buy 交易最重要的是所有权的变更,事实上,在这次交易中,有一份对该票据当前所有者 MagnetoCorp 的认可。

你可能会奇怪为什么 Purchase time 和 Price 属性没有在票据 00001 中体现? 这要回到交易和票据之间的差异。494 万美元的价格标签实际上是交易的属性,而不是票据的属性。花点时间来思考一下这两者的不同;它并不像它看上去的那么明显。稍后我们会看到账本会记录这些信息片段 – 影响票据的所有交易历史,和它最新的状态。清楚这些信息分离非常重要。

同样值得注意的是票据 00001 可能会被买卖多次。尽管在我们的场景中略微跳过了一点,我们来检查一下如果票据 00001 变更了所有者我们可能会看到什么。

如果 BigFund 购买:

 
  1. Txn = buy

  2. Issuer = MagnetoCorp

  3. Paper = 00001

  4. Current owner = DigiBank

  5. New owner = BigFund

  6. Purchase time = 2 June 2020 12:20:00 EST

  7. Price = 4.93M USD

看看票据所有者如何变化,以及在我们的例子中,价格如何变化。你能想到 MagnetoCorp 商业票据价格会降低的原因吗?很直观地,一个 购买 交易要求售卖组织和购买组织都要对该交易进行批准,一次作为该笔交易的两方参与者之间的一个共同的协议的证据。

赎回

票据 00001 赎回 交易代表了它生命周期的结束。在我们相对简单的例子中,HedgeMatic 启动将商业票据转回 MagnetoCorp 的交易:

 
  1. Txn = redeem

  2. Issuer = MagnetoCorp

  3. Paper = 00001

  4. Current owner = HedgeMatic

  5. Redeem time = 30 Nov 2020 12:00:00 EST

再次注意 赎回 交易有更少的属性;票据 00001 所有更改都可以通过兑换交易逻辑计算数据:Issuer 将成为新的所有者,Current state 将变成 redeemed。在我们的例子中指定了 Current owner 属性,以便可以针对当前的票据持有者进行检查。

从信任的角度来说,跟 购买 交易具有相同的原因,也可以应用到 赎回 的说明:在交易中引入的双方组织都需要对它提供批准。

账本

在本主题中,我们已经看到交易和产生的票据状态是 PaperNet 中两个重要的概念。的确,我们将会在任何一个 Hyperledger Fabric 分布式账本中看到这些基本元素 – 包含了当前所有对象最新状态的世界状态和记录了所有交易历史并能归集出最新世界状态的区块链。

在交易上必须的批准通过规则被强制执行,这个在一个交易被附加到账本之前被评估。只有当需要的签名被展示的时候,Fabric 才会接受一个交易作为有效的交易。

你现在处在一个很棒的地方,将这些想法转化为智能合约。如果您的编程有点生疏,请不要担心,我们将提供了解程序代码的提示和指示。掌握商业票据智能合约是设计自己的应用程序的第一个重要步骤。或者,你是一个有一点编程经验的业务分析师,不要害怕继续深入挖掘!

流程和数据设计

生命周期

正如我们所见,在处理商业票据时有两个重要的概念:状态和 交易。实际上,所有区块链用例都是如此;状态建模是重要的概念对象,其生命周期转换由交易描述。对状态和交易的有效分析是成功实施的重要起点。

我们可以用状态转移表来表示商业票据的生命周期:

Fabric(v2.0)官方文档-开发应用程序-场景、分析、流程和数据设计

商业票据的状态转移表。商业票据通过 issuebuy 和 redeem 交易在 issuedtrading 和 redeemed 之间进行状态转移。

了解状态图如何描述商业票据随着时间如何变化,以及特定交易如何控制生命周期转换。在 Hypledger Fabric 中,智能合约实现了在不同状态之间转换商业票据的交易逻辑。商业票据状态实际上是保存在帐本的世界状态中; 让我们来深入了解一下。

账本状态

回想一下商业票据的结构:

Fabric(v2.0)官方文档-开发应用程序-场景、分析、流程和数据设计

商业票据可以被表示为属性集,每个属性都对应一个值。通常,这些属性的组合会为每个票据提供一个唯一键

商业票据的 Paper 属性的值是 00001Face value 属性的值是 5M USD。更重要的是, Current state 属性表示了商业票据是 issued 状态,trading 状态还是 redeemed 状态。 结合来看,属性的完整集合构成了商业票据的状态。此外,这些商业票据的全部集合构成了账本的 世界状态

所有的账本状态都是这种形式;每个状态都是一个属性集,每个都有不同的值。状态的多属性是一个强大的特性 – 允许我们把 Fabric 的状态看做是一个向量而不是一个简单的标量。然后,我们把整个实际的对象当做独立的状态,随后由交易逻辑控制状态转换。Fabric 的状态是由键值对实现的,其中值以捕获对象的多个属性的格式编码对象属性,通常是 JSON 格式。根据这些属性,账本数据库 可以支持高级的查询操作,这对于复杂的对象检索非常有帮助。

查看 MagnetoCorp 的票据 00001 如何表示为一个状态向量,根据不同的交易刺激进行转换:

Fabric(v2.0)官方文档-开发应用程序-场景、分析、流程和数据设计

商业票据状态是由于不同的交易而产生和过渡的。Hyperledger Fabric 状态拥有多个属性,使他们成为向量而不是标量。

注意每个独立的票据都起于空状态,技术上被称作 nil,来表示票据不存在!通过 issue 交易,票据 00001 问世,然后由于 buy 和 redeem 交易而更新状态。

注意每个状态是如何自描述的;每个属性都有一个名字和值。尽管目前所有的商业票据都有相同的属性,这种情况不一定总是如此,而 Hyperledger Fabric 支持不同的状态有不同的属性。这允许相同的帐本世界状态包含相同资产的不同形式以及不同类型的资产。同样使得更新状态结构成为可能;试想有一个新的规则需要一个额外的数据字段。灵活的状态属性集支持数据演化的基本需求。

状态键值

大多数的实际应用中,状态会有一个属性组合在给定的上下文中唯一识别它 – 它就是主键。PaperNet 商业票据的主键是通过 Issuer 属性和 paper 属性拼接得到的;所以 MagnetoCorp 的第一个票据的主键就是 MagnetoCorp00001

状态的主键允许我们唯一识别一个票据;它是通过 issue 交易创建的,然后由 buy 和 redeem 更新。Hyperledger Fabric 需要账本中的每个状态都有唯一的主键。

当唯一主键在可用的属性集中不能获得,应用决定的唯一键会被指定为交易的输入来创建状态。这个唯一键的形式一般是 UUID,尽管可读性不好,但是是一个很好的实践。最重要的是账本中每个独立的状态对象都必须有一个唯一键。

Note: 在主键中你应该避免使用 U+0000 (nil byte)。

多个状态

正如我们所见,PaperNet 中的商业票据作为状态向量被存储在账本中。能够从账本中查询不同的商业票据是合理的需求;比如,查询所有由 MagnetoCorp 发行的的票据,或者查询所有由 MagnetoCorp 发行且处在 redeemed 状态的票据。

为了满足不同类型的查询任务,把所有相关的商业票据按逻辑顺序排列在一起是很有帮助的。PaperNet 的设计包含了商业票据列表的思想 – 一个逻辑容器,每当商业票据发行或发生其他更改时,该容器都会更新。

逻辑代表

把所有的 PaperNet 商业票据放在一个商业票据列表中是有帮助的:

Fabric(v2.0)官方文档-开发应用程序-场景、分析、流程和数据设计

 

MagnetoCorp 新增加的票据 00004 被加入到已有的商业票据列表中。

新票据由于发行交易被加入到列表中,然后列表中已存在的票据因为购买交易和兑换交易可以被更新状态。列表有一个描述性的名称:org.papernet.papers;使用这种 DNS name真的是一个好主意,因为适当的名称会让你的区块链设计对其他人来说是直观的。这种想法同样也适用于智能合约的names

物理的代表

我们可以正确地想到 PaperNet 中的单个票据列表 – org.papernet.papers – 列表最好作为一组单独的 Fabric 状态来实现,其复合键将状态与其列表关联起来。这样,每个状态的复合键都是惟一的,并支持有效的列表查询。

 

将 PaperNet 商业票据列表表示为一组不同的 Hyperledger Fabric 状态

Fabric(v2.0)官方文档-开发应用程序-场景、分析、流程和数据设计

注意列表中的每个票据都是如何用向量状态表示的,其中唯一的组合键是由 org.papernet.paper 的属性 Issuer 和 Paper 连接而成的。这种结构有两个好处:

  • 允许我们检查账本中的任意状态向量在哪个列表中,不用引用到不同的列表。这类似于观察一群体育迷,通过他们穿的衬衫的颜色来判断他们支持哪支球队。体育迷们自我宣布他们的忠诚;我们不需要粉丝名单。
  • Hyperlegder Fabric 内部使用了一个并发控制机制来更新账本,所以把票据保存在不同的状态向量中大大减少了共享状态碰撞的机会。这种碰撞需要交易重新提交,复杂化了应用设计,而且降低了性能。

第二点是 Hyperledger Fabric 的关键;状态向量的物理设计对于优化性能和行为非常重要。保持状态的独立!

信任关系

我们已经讨论了网络中的不同角色,如发行者,交易员或评级机构,以及不同的商业利益如何决定谁需要签署交易。在 Fabric 中,这些规则由所谓的背书策略捕获。这些规则可以在链码粒度上设置,也可以为单个状态键设置。

这意味着在 PaperNet 中,我们可以为整个命名空间设置一个规则,以确定哪些组织可以发行新票据。然后,可以为单个票据设置和更新规则,以捕获购买和兑换交易的信任关系。

在下一个主题中,我们将向您展示如何结合这些设计概念来实现 PaperNet 商业票据智能合约,然后是应用程序来使用它!