4.5 Hyperledger Fabric - 应用程序开发 - 应用程序

应用程序开发 - 应用程序

应用程序可以通过将交易提交到账本或查询账本内容来与区块链网络进行交互。本主题涵盖了应用程序如何执行此操作的机制。在我们的方案中,组织使用调用商业票据智能合约中定义的发行,购买和赎回交易的应用程序访问 PaperNet。尽管 MagnetoCorp 发行商业票据的申请是基本的,但它涵盖了所有主要的理解要点。

在本主题中,我们将介绍:

  • 调用智能合约的应用程序流程
  • 应用程序如何使用钱包和身份
  • 应用程序如何使用网关进行连接
  • 如何访问特定的网络
  • 如何构造交易请求
  • 如何提交交易
  • 如何处理交易响应

为了帮助你理解,我们将参考 Hyperledger Fabric 随附的商业票据应用程序。你可以 下载它在本地运行它。它是用 JavaScript 和 Java 编写的,但是逻辑是完全独立于语言的,因此你可以轻松地看到发生了什么!(该示例也将适用于 Go。)

1. 基本流程

应用程序使用 Fabric SDK 与区块链网络进行交互。这是应用程序如何调用商业票据智能合约的简化图:

image

PaperNet 应用程序调用商业票据智能合约以提交发行交易请求。

应用程序必须遵循六个基本步骤才能提交交易:

  • 从钱包中选择一个身份
  • 连接到网关
  • 访问所需的网络
  • 构建智能合约的交易请求
  • 将交易提交到网络
  • 处理回应

你将看到典型的应用程序如何使用 Fabric SDK 执行这六个步骤。你可以在 issue.js 文件中找到应用程序代码。在浏览器中 查看它,如果已下载,则在你喜欢的编辑器中将其打开。花一些时间查看应用程序的整体结构;即使有注释和空格,也只有 100 行代码!

2. 钱包

在 issue.js 的顶部,你将看到两个 Fabric 类被引入范围:

const { FileSystemWallet, Gateway } = require('fabric-network');

你可以在 node SDK 文档 中了解 fabric-network,但是现在,让我们看看如何将它们用于将 MagnetoCorp 的应用程序连接到 PaperNet。该应用程序使用 Fabric Wallet 类,如下所示:

const wallet = new FileSystemWallet('../identity/user/isabella/wallet');

查看 wallet 如何在本地文件系统中找到 钱包。从钱包中检索到的身份显然适用于使用发行应用程序的名为 Isabella 的用户。钱包包含一组身份 (X.509 数字证书),可用于访问 PaperNet 或任何其他 Fabric 网络。如果你运行本教程,并查看此目录,则将看到 Isabella 的身份凭证。

想象一下一个 钱包,里面装有政府身份证,驾驶执照或 ATM 卡的数字等效物。其中的 X.509 数字证书将使持有者与组织相关联,从而使他们具有网络通道中的权利。例如,Isabella 可能是 MagnetoCorp 的管理员,这可能赋予她比其他用户 (DigiBank 的 Balaji) 更多的特权。此外,智能合约可以使用 交易上下文 在智能合约处理期间检索此身份。

另请注意,钱包不持有任何形式的现金或代币 - 它们持有身份。

3. 网关

第二个关键类是 Fabric 网关。最重要的是,网关 标识一个或多个提供对网络访问权限的对端节点 - 在我们的示例中为 PaperNet。查看 issue.js 如何连接到其网关:

await gateway.connect(connectionProfile, connectionOptions);

gateway.connect() 有两个重要参数:

  • connectionProfile:连接配置文件 的文件系统位置,该连接配置文件将一组对端节点标识为通往 PaperNet 的网关
  • connectionOptions:一组用于控制 issue.js 与 PaperNet 交互方式的选项

了解客户端应用程序如何使用网关将自身与网络拓扑隔离,这可能会发生变化。网关负责使用 连接配置文件连接选项 将交易提案发送到网络中正确的对端节点。

花一些时间检查连接配置 文件 ./gateway/connectionProfile.yaml。它使用 YAML,使其易于阅读。

它已加载并转换为 JSON 对象:

let connectionProfile = yaml.safeLoad(file.readFileSync('./gateway/connectionProfile.yaml', 'utf8'));

目前,我们只对 profile 部分的 channels:peers: 感兴趣:(我们对详细信息进行了一些修改,以更好地说明正在发生的事情。)

channels:
  papernet:
    peers:
      peer1.magnetocorp.com:
        endorsingPeer: true
        eventSource: true

      peer2.digibank.com:
        endorsingPeer: true
        eventSource: true

peers:
  peer1.magnetocorp.com:
    url: grpcs://localhost:7051
    grpcOptions:
      ssl-target-name-override: peer1.magnetocorp.com
      request-timeout: 120
    tlsCACerts:
      path: certificates/magnetocorp/magnetocorp.com-cert.pem

  peer2.digibank.com:
    url: grpcs://localhost:8051
    grpcOptions:
      ssl-target-name-override: peer1.digibank.com
    tlsCACerts:
      path: certificates/digibank/digibank.com-cert.pem

查看 channel: 如何识别 PaperNet: 网络通道及其两个对端节点。 MagnetoCorp 拥有 peer1.magenetocorp.com,而 DigiBank 拥有 peer2.digibank.com,并且两者都具有背书对端节点的作用。通过 peers: 键链接到这些对端节点,其中包含有关如何连接到它们的详细信息,包括它们各自的网络地址。

连接配置文件包含很多信息 - 不仅包括对端节点信息 - 而且还包含网络通道,网络交易排序器,组织和 CA,因此,如果你不了解所有信息,请不要担心!

现在,我们将注意力转向 connectionOptions 对象:

let connectionOptions = {
  identity: userName,
  wallet: wallet
}

了解如何指定身份 (userName) 以及钱包 (wallet) 用于连接到网关。这些是在代码的前面分配的值。

应用程序还可以使用其他 连接选项 来指示 SDK 代表其智能操作。例如:

let connectionOptions = {
  identity: userName,
  wallet: wallet,
  eventHandlerOptions: {
    commitTimeout: 100,
    strategy: EventStrategies.MSPID_SCOPE_ANYFORTX
  },
}

在这里,commitTimeout 告诉 SDK 等待 100 秒,以了解交易是否已提交。strategy:EventStrategies.MSPID_SCOPE_ANYFORTX 指定 SDK 可以在单个 MagnetoCorp 对端节点确认交易后通知应用程序,而strategy:EventStrategies.NETWORK_SCOPE_ALLFORTX 则要求 MagnetoCorp 和 DigiBank 的所有对端节点确认交易。

如果你愿意,请 阅读更多 有关连接选项如何允许应用程序指定面向目标的行为的信息,而不必担心如何实现。

4. 网络通道

网关 connectionProfile.yaml 中定义的对端节点使 issue.js 可以访问 PaperNet。因为这些对端节点可以加入多个网络通道,所以网关实际上为应用程序提供了对多个网络通道的访问权限!

查看应用程序如何选择特定通道:

const network = await gateway.getNetwork('PaperNet');

从此时起,network 将提供对 PaperNet 的访问。此外,如果应用程序同时希望访问另一个网络,BondNet,则很容易:

const network2 = await gateway.getNetwork('BondNet');

现在,我们的应用程序可以与 PaperNet 同时访问第二个网络 BondNet

我们在这里可以看到 Hyperledger Fabric 的强大功能 - 应用程序可以通过连接到多个网关对端节点来参与网络中的网络,每个网关对端节点都连接到多个网络通道。根据 gateway.connect() 中提供的钱包身份,应用程序将在不同的通道中具有不同的权限。

5. 构造请求

该应用程序现在准备发行商业票据。为此,它将使用 CommercialPaperContract,并且再次使用它非常简单地访问此智能合约:

const contract = await network.getContract('papercontract', 'org.papernet.commercialpaper');

请注意,该应用程序如何提供名称 – papercontract – 和明确的合约名称:org.papernet.commercialpaper!我们将看到 合约名称 如何从包含许多合约的 papercontract.js 链码文件中挑选出一个合约。在 PaperNet 中,papercontract.js 的安装和实例化名为 papercontract,如果你感兴趣的话,请阅读如何安装和实例化包含多个智能合约的链码。

如果我们的应用程序同时需要访问 PaperNet 或 BondNet 中的另一个合约,这将很容易:

const euroContract = await network.getContract('EuroCommercialPaperContract');

const bondContract = await network2.getContract('BondContract');

在这些示例中,请注意我们如何不使用带限定符的合约名称 - 每个文件只有一个智能合约,而 getContract() 将使用找到的第一个合约。

回顾一下 MagnetoCorp 发行第一张商业票据所使用的交易:

Txn = issue
Issuer = MagnetoCorp
Paper = 00001
Issue time = 31 May 2020 09:00:00 EST
Maturity date = 30 November 2020
Face value = 5M USD

现在,我们将此交易提交给 PaperNet!

6. 提交交易

提交交易是对 SDK 的单一方法调用:

const issueResponse = await contract.submitTransaction('issue', 'MagnetoCorp', '00001', '2020-05-31', '2020-11-30', '5000000');

查看 submitTransaction() 参数如何与交易请求的参数匹配。这些值将传递给智能合约中的 issue() 方法,并用于创建新的商业票据。回顾其签名:

async issue(ctx, issuer, paperNumber, issueDateTime, maturityDateTime, faceValue) {...}

在应用程序发出 submitTransaction() 之后,智能合约可能会立即获得控制权,但事实并非如此。在幕后,SDK使用 connectionOptionsconnectionProfile 详细信息将交易提案发送到网络中的正确对端节点,在该对端节点可以获取所需的背书。但是应用程序无需担心任何这些 – 只需发出 SubmitTransaction,SDK 就可以解决一切!

请注意,submitTransaction API 包括用于侦听交易提交的过程。需要侦听提交,因为没有提交,你将不知道你的交易是否已成功排序,验证并提交到账本。

现在,我们将注意力转移到应用程序如何处理响应上!

7. 处理响应

回想一下 papercontract.js,发行交易如何返回商业票据响应:`

return paper.toBuffer();

你会注意到一个小怪癖 - 新票据需要先转换为缓冲区,然后才能返回到应用程序中。请注意 issue.js 如何使用类方法 CommercialPaper.fromBuffer() 来将响应缓冲区重新反序列化为商业票据:

let paper = CommercialPaper.fromBuffer(issueResponse);

这允许在描述性完成消息中以自然方式使用票据:

console.log(`${paper.issuer} commercial paper : ${paper.paperNumber} successfully issued for value ${paper.faceValue}`);

了解在应用程序和智能合约中如何使用相同的 paper 类 - 如果你这样构造代码,它将真正有助于提高可读性和重用性。

与交易提案一样,智能合约完成后,应用程序似乎很快就会收到控制权,但事实并非如此。在后台,SDK 管理整个共识过程,并根据策略 connectionOption 通知应用程序完成。如果你对 SDK 的基本功能感兴趣,请阅读详细的 交易流程

就是这样!在本主题中,你已通过研究 MagnetoCorp 的应用程序如何在 PaperNet 中发布新的商业票据来理解如何从示例应用程序中调用智能合约。现在,检查关键账本和智能合约数据结构是根据其背后的 体系结构主题 设计的。

Reference

项目源代码

项目源代码会逐步上传到 Github,地址为 https://github.com/windstamp

Contributor

  1. Windstamp, https://github.com/windstamp
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,658评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,482评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,213评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,395评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,487评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,523评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,525评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,300评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,753评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,048评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,223评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,905评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,541评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,168评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,417评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,094评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,088评论 2 352

推荐阅读更多精彩内容