美文网首页区块链Hyperledger Fabric 文档
5.2 Hyperledger Fabric - 教程 - 商业

5.2 Hyperledger Fabric - 教程 - 商业

作者: furnace | 来源:发表于2019-12-05 19:55 被阅读0次

    教程 - 商业票据 (Commercial Paper)

    本教程将向你展示如何安装和使用商业票据 (Commercial Paper) 示例应用程序和智能合约。这是一个面向任务的主题,因此强调了以上概念中的过程。当你想更详细地了解这些概念时,可以阅读 开发应用程序 主题。

    image

    在本教程中,MagnetoCorp 和 DigiBank 这两个组织使用 Hyperledger Fabric 区块链网络 PaperNet 彼此进行商业票据交易。

    建立基本网络后,你将担任 MagnetoCorp 员工 Isabella 的代表,他将代表该公司发行商业票据。然后,你将转而担任 DigiBank 员工 Balaji 的角色,他将购买此商业票据,保留一段时间,然后与 MagnetoCorp 赎回以获取少量利润。

    你将分别在不同的组织中充当开发人员,终端用户和管理员的角色,执行以下步骤旨在帮助你了解作为两个不同的组织独立工作,但要根据 Hyperledger Fabric 网络中共同商定的规则进行协作。

    • 设置网络并下载示例
    • 创建一个网络
    • 了解智能合约的结构
    • 作为组织 MagnetoCorp 来安装和实例化智能合约
    • 了解 MagnetoCorp 应用程序的结构,包括其依赖项
    • 配置和使用钱包和身份
    • 运行 MagnetoCorp 应用程序以发行商业票据
    • 了解第二家组织 Digibank 如何在其应用程序中使用智能合约
    • 作为 Digibank,运行购买和赎回商业票据的应用程序

    本教程已经在 MacOS 和 Ubuntu 上进行了测试,并且可以在其他 Linux 发行版上使用。Windows 版本正在开发中。

    1. 先决条件

    在开始之前,你必须安装本教程所需的一些必备技术。我们将这些限制降至最低,以便你可以快速上手。

    你必须安装以下技术:

    • Node 8.9.0 或更高版本。Node 是一个 JavaScript 运行时,可用于运行应用程序和智能合约。建议你使用 Node 的长期支持 (Long Term Support, LTS) 版本。在 此处 安装 Node。
    • Docker 18.06 或更高版本。Docker 帮助开发人员和管理员创建用于构建和运行应用程序和智能合约的标准环境。Hyperledger Fabric 是作为一组 Docker 镜像提供的,PaperNet 智能合约将在 Docker 容器中运行。在 此处 安装 Docker。

    你会发现安装以下技术会有所帮助:

    • 源代码编辑器,例如 Visual Studio Code 1.28 或更高版本。VS Code 将帮助你开发和测试你的应用程序和智能合约。在 此处 安装 VS Code。

    提供了许多出色的代码编辑器,包括 AtomSublime TextBrackets

    随着对应用程序和智能合约开发的经验越来越丰富,安装以下技术可能会有所帮助。初次运行本教程时,无需安装它们:

    • Node 版本管理器。NVM (Node Version Manager) 可帮助你轻松地在不同版本的 Node 之间切换 - 如果你同时从事多个项目,这将非常有用。在 此处 安装 NVM。

    2. 下载示例

    商业票据教程是 Hyperledger Fabric 示例 之一,该示例存储在公共 GitHub 仓库中,称为 fabric-samples。在你的计算机上运行教程时,你的第一个任务是下载 fabric-samples 仓库。

    image

    将 fabric-samples GitHub 仓库下载到本地计算机。

    GOPATH 是 Hyperledger Fabric 中的重要环境变量;它标识要安装的根目录。无论你使用哪种编程语言,正确安装都非常重要!打开一个新的终端窗口,并使用 env 命令检查GOPATH 是否已设置:

    $ env
    ...
    GOPATH=/Users/username/go
    NVM_BIN=/Users/username/.nvm/versions/node/v8.11.2/bin
    NVM_IOJS_ORG_MIRROR=https://iojs.org/dist
    ...
    

    如果未设置 $GOPATH,请使用以下 指令

    现在,你可以创建一个相对于 $GOPATH 的目录,将在其中安装 fabric-samples:

    $ mkdir -p $GOPATH/src/github.com/hyperledger/
    $ cd $GOPATH/src/github.com/hyperledger/
    

    使用 git clone 命令将 fabric-samples 仓库复制到以下位置:

    $ git clone https://github.com/hyperledger/fabric-samples.git
    

    随时检查 fabric-samples 的目录结构:

    $ cd fabric-samples
    $ ls
    
    CODE_OF_CONDUCT.md    balance-transfer            fabric-ca
    CONTRIBUTING.md       basic-network               first-network
    Jenkinsfile           chaincode                   high-throughput
    LICENSE               chaincode-docker-devmode    scripts
    MAINTAINERS.md        commercial-paper            README.md
    fabcar
    

    请注意 commercial-paper 目录,这是我们的示例所在的目录!

    你现在已经完成了教程的第一阶段!在继续操作时,你将打开多个命令窗口,这些窗口将为不同的用户和组件打开。例如:

    • 代表 Isabella 和 Balaji 运行应用程序,他们将彼此进行商业票据交易
    • 代表 MagnetoCorp 和 DigiBank 的管理员发出命令,包括安装和实例化智能合约
    • 显示对端节点,交易排序器和 CA 日志输出

    我们将在你应该从特定命令窗口运行命令时明确说明,例如:

    (isabella)$ ls
    

    表示你应该在 Isabella 的窗口中运行 ls 命令。

    3. 创建网络

    本教程当前使用基础网络。它将很快更新为更好地反映 PaperNet 的多组织结构的配置。目前,该网络足以向你展示如何开发应用程序和智能合约。

    image

    Hyperledger Fabric 基础网络包括一个对端节点及其账本数据库,一个交易排序器和一个证书颁发机构 (Certificate Authority, CA)。这些组件中的每一个都作为 docker 容器运行。

    对端节点,帐本,交易排序器和 CA 均在各自的 docker 容器中运行。在生产环境中,组织通常使用与其他系统共享的现有 CA。它们不是专用于 Fabric 网络的。

    你可以使用 fabric-samples\basic-network 目录中包含的命令和配置来管理基础网络。让我们使用 start.sh shell 脚本在本地计算机上启动网络:

    $ cd fabric-samples/basic-network
    $ sudo ./start.sh
    
    docker-compose -f docker-compose.yml up -d ca.example.com orderer.example.com peer0.org1.example.com couchdb
    Creating network "net_basic" with the default driver
    Pulling ca.example.com (hyperledger/fabric-ca:)...
    latest: Pulling from hyperledger/fabric-ca
    3b37166ec614: Pull complete
    504facff238f: Pull complete
    (...)
    Pulling orderer.example.com (hyperledger/fabric-orderer:)...
    latest: Pulling from hyperledger/fabric-orderer
    3b37166ec614: Already exists
    504facff238f: Already exists
    (...)
    Pulling couchdb (hyperledger/fabric-couchdb:)...
    latest: Pulling from hyperledger/fabric-couchdb
    3b37166ec614: Already exists
    504facff238f: Already exists
    (...)
    Pulling peer0.org1.example.com (hyperledger/fabric-peer:)...
    latest: Pulling from hyperledger/fabric-peer
    3b37166ec614: Already exists
    504facff238f: Already exists
    (...)
    Creating orderer.example.com ... done
    Creating couchdb             ... done
    Creating ca.example.com         ... done
    Creating peer0.org1.example.com ... done
    (...)
    2018-11-07 13:47:31.634 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
    2018-11-07 13:47:31.730 UTC [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel
    

    请注意 docker-compose -f docker-compose.yml up -d ca.example.com ... 命令如何从 DockerHub 中提取四个 Hyperledger Fabric 容器镜像,然后启动它们。这些容器具有适用于这些 Hyperledger Fabric 组件的软件的最新版本。欢迎浏览 basic-network 目录 - 在本教程中,我们将使用其中的大部分内容。

    你可以使用 docker ps 命令列出运行基础网络组件的 Docker 容器:

    $ sudo docker ps
    
    CONTAINER ID        IMAGE                        COMMAND                  CREATED              STATUS              PORTS                                            NAMES
    ada3d078989b        hyperledger/fabric-peer      "peer node start"        About a minute ago   Up About a minute   0.0.0.0:7051->7051/tcp, 0.0.0.0:7053->7053/tcp   peer0.org1.example.com
    1fa1fd107bfb        hyperledger/fabric-orderer   "orderer"                About a minute ago   Up About a minute   0.0.0.0:7050->7050/tcp                           orderer.example.com
    53fe614274f7        hyperledger/fabric-couchdb   "tini -- /docker-ent…"   About a minute ago   Up About a minute   4369/tcp, 9100/tcp, 0.0.0.0:5984->5984/tcp       couchdb
    469201085a20        hyperledger/fabric-ca        "sh -c 'fabric-ca-se…"   About a minute ago   Up About a minute   0.0.0.0:7054->7054/tcp                           ca.example.com
    

    查看是否可以将这些容器映射到基础网络 (你可能需要水平滚动以查找信息):

    • 对端节点 peer0.org1.example.com 在容器 ada3d078989b 中运行
    • 交易排序器 orderer.example.com 正在容器 1fa1fd107bfb 中运行
    • 在容器 53fe614274f7 中正在运行 CouchDB 数据库 couchdb
    • CA ca.example.com 正在容器 469201085a20 中运行

    这些容器都形成了一个名为 net_basicdocker 网络。你可以使用 docker network 命令查看网络:

    $ sudo docker network inspect net_basic
    
        {
            "Name": "net_basic",
            "Id": "62e9d37d00a0eda6c6301a76022c695f8e01258edaba6f65e876166164466ee5",
            "Created": "2018-11-07T13:46:30.4992927Z",
            "Containers": {
                "1fa1fd107bfbe61522e4a26a57c2178d82b2918d5d423e7ee626c79b8a233624": {
                    "Name": "orderer.example.com",
                    "IPv4Address": "172.20.0.4/16",
                },
                "469201085a20b6a8f476d1ac993abce3103e59e3a23b9125032b77b02b715f2c": {
                    "Name": "ca.example.com",
                    "IPv4Address": "172.20.0.2/16",
                },
                "53fe614274f7a40392210f980b53b421e242484dd3deac52bbfe49cb636ce720": {
                    "Name": "couchdb",
                    "IPv4Address": "172.20.0.3/16",
                },
                "ada3d078989b568c6e060fa7bf62301b4bf55bed8ac1c938d514c81c42d8727a": {
                    "Name": "peer0.org1.example.com",
                    "IPv4Address": "172.20.0.5/16",
                }
            },
            "Labels": {}
        }
    

    查看这四个容器如何成为一个 docker 网络的一部分,如何使用不同的 IP 地址。(为清楚起见,我们将输出缩写。)

    回顾一下:你已经从 GitHub 下载了 Hyperledger Fabric 示例仓库,并且基础网络已在本地计算机上运行。现在,让我们开始扮演 MagnetoCorp 的角色,他希望买卖商业票据。

    4. 担任 MagnetoCorp 角色

    要监视 PaperNet 的 MagnetoCorp 组件,管理员可以使用 logspout 工具 查看一组 Docker 容器的聚合输出。它将不同的输出流收集到一个位置,从而可以轻松地从一个窗口查看正在发生的事情。例如,这对于安装智能合约的管理员或调用智能合约的开发人员确实很有帮助。

    现在,让我们以 MagnetoCorp 管理员的身份监视 PaperNet。在 fabric-samples 目录中打开一个新窗口,找到并运行 monitordocker.sh 脚本以启动与 docker 网络 net_basic 关联的 PaperNet docker 容器的 logspout 工具:

    (magnetocorp admin)$ cd commercial-paper/organization/magnetocorp/configuration/cli/
    (magnetocorp admin)$ sudo ./monitordocker.sh net_basic
    ...
    latest: Pulling from gliderlabs/logspout
    4fe2ade4980c: Pull complete
    decca452f519: Pull complete
    (...)
    Starting monitoring on all containers on the network net_basic
    b7f3586e5d0233de5a454df369b8eadab0613886fc9877529587345fc01a3582
    

    请注意,如果 Monitordocker.sh 中的默认端口已在使用中,则可以将端口号传递给上述命令。

    (magnetocorp admin)$ ./monitordocker.sh net_basic <port_number>
    

    现在,该窗口将显示 docker 容器的输出,因此让我们启动另一个终端窗口,该窗口将允许 MagnetoCorp 管理员与网络进行交互。

    image

    MagnetoCorp 管理员通过 Docker 容器与网络进行交互。

    为了与 PaperNet 进行交互,MagnetoCorp 管理员需要使用 Hyperledger Fabric peer 命令。方便地,这些都可以在 hyperledger/fabric-tools docker 镜像 中预先构建。

    让我们使用 docker-compose 命令 为管理员启动一个特定于 MagnetoCorp 的 Docker 容器:

    (magnetocorp admin)$ cd commercial-paper/organization/magnetocorp/configuration/cli/
    (magnetocorp admin)$ sudo docker-compose -f docker-compose.yml up -d cliMagnetoCorp
    
    Pulling cliMagnetoCorp (hyperledger/fabric-tools:)...
    latest: Pulling from hyperledger/fabric-tools
    3b37166ec614: Already exists
    (...)
    Digest: sha256:058cff3b378c1f3ebe35d56deb7bf33171bf19b327d91b452991509b8e9c7870
    Status: Downloaded newer image for hyperledger/fabric-tools:latest
    Creating cliMagnetoCorp ... done
    

    再次,查看如何从 Docker Hub 检索 hyperledger/fabric-tools docker 镜像并将其添加到网络:

    (magnetocorp admin)$ docker ps
    
    CONTAINER ID        IMAGE                        COMMAND                  CREATED              STATUS              PORTS                                            NAMES
    562a88b25149        hyperledger/fabric-tools     "/bin/bash"              About a minute ago   Up About a minute                                                    cliMagnetoCorp
    b7f3586e5d02        gliderlabs/logspout          "/bin/logspout"          7 minutes ago        Up 7 minutes        127.0.0.1:8000->80/tcp                           logspout
    ada3d078989b        hyperledger/fabric-peer      "peer node start"        29 minutes ago       Up 29 minutes       0.0.0.0:7051->7051/tcp, 0.0.0.0:7053->7053/tcp   peer0.org1.example.com
    1fa1fd107bfb        hyperledger/fabric-orderer   "orderer"                29 minutes ago       Up 29 minutes       0.0.0.0:7050->7050/tcp                           orderer.example.com
    53fe614274f7        hyperledger/fabric-couchdb   "tini -- /docker-ent…"   29 minutes ago       Up 29 minutes       4369/tcp, 9100/tcp, 0.0.0.0:5984->5984/tcp       couchdb
    469201085a20        hyperledger/fabric-ca        "sh -c 'fabric-ca-se…"   29 minutes ago       Up 29 minutes       0.0.0.0:7054->7054/tcp                           ca.example.com
    

    MagnetoCorp 管理员将使用容器 562a88b25149 中的命令行与 PaperNet 进行交互。还要注意日志记录容器 b7f3586e5d02;这是为 monitordocker.sh 命令捕获所有其他 docker 容器的输出。

    现在,让我们使用此命令行以 MagnetoCorp 管理员的身份与 PaperNet 进行交互。

    5. 智能合约

    发行 (issue),购买 (buy) 和赎回 (redeem) 是 PaperNet 智能合约的三个核心功能。应用程序使用它来提交交易,这些交易相应地在账本上发行,购买和赎回商业票据。我们的下一个任务是检查智能合约。

    打开一个新的终端窗口,代表 MagnetoCorp 开发人员,然后转到包含 MagnetoCorp 智能合约副本的目录,以便使用你选择的编辑器进行查 (本教程中的 VS 代码):

    (magnetocorp developer)$ cd commercial-paper/organization/magnetocorp/contract
    (magnetocorp developer)$ ls .
    

    在文件夹的 lib 目录中,你将看到 papercontract.js 文件 - 该文件包含商业票据智能合约!

    image

    一个示例代码编辑器,在 papercontract.js 中显示商业票据智能合约。

    papercontract.js 是一个 JavaScript 程序,旨在在 node.js 环境中运行。请注意以下关键程序行:

    • const { Contract, Context } = require('fabric-contract-api');

      该声明将智能合约广泛使用的两个关键 Hyperledger Fabric 类纳入了范围 - ContractContext。你可以在 fabric-shim JSDOCS 中了解有关这些类的更多信息。

    • class CommercialPaperContract extends Contract {

      这基于内置的 Fabric Contract 类定义了智能合约类 CommercialPaperContract。在此类中定义了实现发行 (issue),购买 (buy) 和赎回 (redeem) 商业票据的关键交易的方法。

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

      此方法为 PaperNet 定义了商业票据发行 (issue) 交易。传递给此方法的参数将用于创建新的商业票据。

      在智能合约中找到并检查购买 (buy) 和赎回 (redeem) 交易。

    • let paper = CommercialPaper.createInstance(issuer, paperNumber, issueDateTime...);

      在发行 (issue) 交易中,此语句使用带有提供的交易输入的 CommercialPaper 类在内存中创建新的商业票据。检查购买 (buy) 和赎回 (redeem) 交易,以了解它们如何类似地使用此类。

    • await ctx.paperList.addPaper(paper);

      该语句使用 ctx.paperList 将新的商业票据添加到帐本中,ctx.paperList 是在智能合约上下文 CommercialPaperContext 初始化时创建的 PaperList 类的实例。再次,检查购买 (buy) 和赎回 (redeem) 方法,以了解它们如何使用此类。

    • return paper.toBuffer();

      该语句返回一个二进制缓冲区作为发行 (issue) 交易的响应,由智能合约的调用者进行处理。

    随时检查 contract 目录中的其他文件,以了解智能合约的工作原理,并详细阅读智能合约 主题papercontract.js 的设计方式。

    6. 安装合约

    在应用程序可以调用 papercontract 之前,必须将它安装到 PaperNet 中的相应对端节点上。MagnetoCorp 和 DigiBank 管理员能够将 papercontract 安装到他们各自具有权限的对端节点上。

    image

    MagnetoCorp 管理员将 papercontract 的副本安装到 MagnetoCorp 对端节点。

    智能合约是应用程序开发的重点,并且包含在称为 链码 的 Hyperledger Fabric 构件中。可以在单个链码中定义一个或多个智能合约,安装链码将允许 PaperNet 中的不同组织使用它们。这意味着只有管理员才需要担心链码。其他人都可以根据智能合约进行思考。

    MagnetoCorp 管理员使用 peer chaincode install 命令将 papercontract 智能合约从其本地计算机的文件系统复制到目标对端节点 Docker 容器内的文件系统。一旦将智能合约安装到对端节点并在通道上实例化,便可以由应用程序调用 papercontract,并通过 putState()getState() Fabric API与账本数据库进行交互。检查 ledger-api\statelist.js 中的 StateList 类如何使用这些 API。

    现在,以 MagnetoCorp 管理员的身份安装 papercontract。在 MagnetoCorp 管理员的命令窗口中,使用 docker exec 命令在 cliMagnetCorp 容器中运行 peer chaincode install 命令:

    (magnetocorp admin)$ sudo docker exec cliMagnetoCorp peer chaincode install -n papercontract -v 0 -p /opt/gopath/src/github.com/contract -l node
    
    2018-11-07 14:21:48.400 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 001 Using default escc
    2018-11-07 14:21:48.400 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 002 Using default vscc
    2018-11-07 14:21:48.466 UTC [chaincodeCmd] install -> INFO 003 Installed remotely response:<status:200 payload:"OK" >
    

    cliMagnetCorp 容器已将 CORE_PEER_ADDRESS=peer0.org1.example.com:7051 设置为将其命令定向到 peer0.org1.example.com,并且 INFO 003 Installed remotely ... 表示该对端节点已成功安装 papercontract。目前,MagnetoCorp 管理员只需在单个 MagentoCorp 对端节点上安装 papercontract 副本。

    请注意,peer chaincode install 命令如何相对于 cliMagnetoCorp 容器的文件系统 /opt/gopath/src/github.com/contract 指定智能合约路径 -p。该路径已通过 magnetocorp/configuration/cli/docker-compose.yml 文件映射到本地文件系统路径 .../organization/magnetocorp/contract

    volumes:
        - ...
        - ./../../../../organization/magnetocorp:/opt/gopath/src/github.com/
        - ...
    

    了解 volume 指令如何将 organization/magnetocorp 映射到 /opt/gopath/src/github.com/,以提供此容器访问你的本地文件系统的位置,该目录中保存了 MagnetoCorp 的 papercontract 智能合约副本。

    你可以在 此处 阅读有关 docker compose 的更多信息,并在 此处 阅读 peer chaincode install 命令。

    7. 实例化合约

    现在,已将包含 CommercialPaper 智能合约的 papercontract 链码安装在所需的 PaperNet 对端节点上,管理员可以将其提供给不同的网络通道使用,从而可以由连接到这些通道的应用程序调用。因为我们使用的是 PaperNet 的基础网络配置,所以我们只会在单个网络通道 mychannel 中提供 papercontract

    image

    MagnetoCorp 管理员实例化包含智能合约的 papercontract 链码。将创建一个新的 docker chaincode 容器以运行 papercontract

    MagnetoCorp 管理员使用 peer chaincode instantiate 命令来实例化 mychannel 上的 papercontract

    (magnetocorp admin)$ sudo docker exec cliMagnetoCorp peer chaincode instantiate -n papercontract -v 0 -l node -c '{"Args":["org.papernet.commercialpaper:instantiate"]}' -C mychannel -P "AND ('Org1MSP.member')"
    
    2018-11-07 14:22:11.162 UTC [chaincodeCmd] InitCmdFactory -> INFO 001 Retrieved channel (mychannel) orderer endpoint: orderer.example.com:7050
    2018-11-07 14:22:11.163 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 002 Using default escc
    2018-11-07 14:22:11.163 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 003 Using default vscc
    

    -Pinstantiate 中最重要的参数之一。它指定了 papercontract背书策略,描述了在确定交易有效之前必须背书 (执行和签名) 交易的一组组织。所有交易 (无论有效还是无效) 都将记录在 账本区块链 上,但是只有有效交易才能更新 世界状态

    通过传递,请参见 instantiate 如何传递交易排序器地址 orderer.example.com:7050。这是因为它另外将实例化交易提交给交易排序器,它会将交易包含在下一个区块中并将其分发给已加入 mychannel 的所有对端节点,从而使任何对端节点都可以在其自己的隔离链码容器中执行链码。请注意,对于 papercontractinstantiate 只需要发布一次,即使它通常安装在许多对端节点上。

    查看如何使用 docker ps 命令启动纸质 papercontract

    (magnetocorp admin)$ sudo docker ps
    
    CONTAINER ID        IMAGE                                              COMMAND                  CREATED             STATUS              PORTS          NAMES
    4fac1b91bfda        dev-peer0.org1.example.com-papercontract-0-d96...  "/bin/sh -c 'cd /usr…"   2 minutes ago       Up 2 minutes                       dev-peer0.org1.example.com-papercontract-0
    

    请注意,该容器的名称为 dev-peer0.org1.example.com-papercontract-0-d96...,以指示哪个对端节点启动了该容器,以及该容器运行的是 papertract 版本 0

    现在,我们已经建立并运行了基本的 PaperNet,并已安装并实例化了 paperContract,现在我们将注意力转向发行商业票据的 MagnetoCorp 应用程序。

    8. 应用程序结构

    papercontract 中包含的智能合约由 MagnetoCorp 的应用程序 issue.js 调用。Isabella (伊莎贝拉) 使用此应用程序将交易提交到帐本,该帐本将发行商业票据 00001。让我们快速检查一下发行 (issue) 程序的工作方式。

    image

    网关 (gateway) 允许应用程序专注于交易的生成,提交和响应。它协调不同网络组件之间的交易提案,交易排序和通知处理。

    由于 issue 应用程序代表 Isabella 提交交易,因此首先要从她的 钱包 中检索 Isabella 的 X.509 证书,该证书可能存储在本地文件系统或硬件安全模块 (Hardware Security Module, HSM) 中。然后,issue 应用程序能够利用网关在通道上提交交易。 Hyperledger Fabric SDK 提供了 网关 抽象,因此应用程序可以在将网络交互委托给网关的同时专注于应用程序逻辑。网关和钱包使编写 Hyperledger Fabric 应用程序变得很简单。

    因此,让我们检查一下Isabella将要使用的问题应用程序。为她打开一个单独的终端窗口,然后在Fabric-samples中找到MagnetoCorp / application文件夹:

    因此,让我们检查一下 Isabella 将要使用的 issue 应用程序。为她打开一个单独的终端窗口,然后在 fabric-samples 中找到 MagnetoCorp /application 文件夹:

    (magnetocorp user)$ cd commercial-paper/organization/magnetocorp/application/
    (magnetocorp user)$ ls
    
    addToWallet.js      issue.js        package.json
    

    Isabella 将使用 addToWallet.js 程序将 Isabella 的身份加载到她的钱包中,issue.js 将通过调用 papercontract 使用此身份代表 MagnetoCorp 创建商业票据 00001

    转到包含 MagnetoCorp 应用程序 issue.js 副本的目录,然后使用代码编辑器进行检查:

    (magnetocorp user)$ cd commercial-paper/organization/magnetocorp/application
    (magnetocorp user)$ code issue.js
    

    检查此目录;它包含 issue 应用程序及其所有依赖项。

    image

    一个代码编辑器,显示商业票据应用程序目录的内容。

    请注意 issue.js 中的以下关键程序行:

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

      该声明将两个关键的 Hyperledger Fabric SDK 类引入了作用域 - WalletGateway。由于 Isabella 的 X.509 证书位于本地文件系统中,因此该应用程序使用 FileSystemWallet

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

      该语句标识该应用程序在连接到区块链网络通道时将使用 isabella 钱包。该应用程序将选择 isabella 钱包中的特定身份。(钱包必须已经装有 Isabella 的 X.509 证书,这就是 addToWallet.js 所做的。)

    • await gateway.connect(connectionProfile, connectionOptions);

      这行代码使用由 connectionProfile 标识的网关 (使用 ConnectionOptions 中引用的身份) 连接到网络。

      请参阅如何分别将 ../gateway/networkConnection.yamlUser1@org1.example.com 用于这些值。

    • const network = await gateway.getNetwork('mychannel');

      这会将应用程序连接到网络通道 mychannel,在该通道 papercontract 先前已实例化。

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

      该语句使应用程序可访问 papercontract 中由命名空间 org.papernet.commercialpaper 定义的智能合约。一旦应用程序发布了 getContract,它就可以提交在其中实现的任何交易。

    • const issueResponse = await contract.submitTransaction('issue', 'MagnetoCorp', '00001'...);

      这行代码使用智能合约中定义的发行 (issue) 交易将交易提交到网络。MagnetoCorp00001 … 是发行交易用于创建新商业票据的值。

    • let paper = CommercialPaper.fromBuffer(issueResponse);

      该语句处理来自发行 (issue) 交易的响应。需要将响应从缓冲区反序列化为 paper (可以由应用程序正确解释的 CommercialPaper 对象)。

    随时检查 /application 目录中的其他文件,以了解 issue.js 的工作方式,并在应用程序 主题 中详细阅读它的实现方式。

    9. 应用程序依赖

    issue.js 应用程序是用 JavaScript 编写的,旨在在作为 PaperNet 网络客户端的 node.js 环境中运行。按照惯例,MagnetoCorp 的应用程序建立在许多外部 node 程序包上 – 以提高开发质量和速度。请考虑 issue.js 如何包括用于处理 YAML 网关连接配置文件的 js-yaml 程序包,或用于访问 Gateway 和 Wallet 类的 fabric-network 程序包

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

    必须使用 npm install 命令将这些软件包从 npm 下载到本地文件系统。按照约定,必须将软件包安装到相对于应用程序的 /node_modules 目录中,以便在运行时使用。

    检查 package.json 文件,查看 issue.js 如何识别要下载的软件包及其确切版本:

      "dependencies": {
        "fabric-network": "^1.4.0-beta",
        "fabric-client": "^1.4.0-beta",
        "js-yaml": "^3.12.0"
      },
    

    npm 版本控制功能非常强大;你可以在 这里 读更多关于它的内容。

    让我们使用 npm install 命令安装这些软件包 - 这可能需要一分钟才能完成:

    (magnetocorp user)$ npm install
    
    (           ) extract:lodash: sill extract ansi-styles@3.2.1
    (...)
    added 738 packages in 46.701s
    

    查看此命令如何更新目录:

    (magnetocorp user)$ ls
    
    addToWallet.js      node_modules            package.json
    issue.js            package-lock.json
    

    检查 node_modules 目录以查看已安装的软件包。有很多,因为 js-yamlfabric-network 本身是建立在其他 npm 软件包上的!有用的是,package-lock.json 文件可以标识安装的确切版本,如果你想精确地复制环境,则可以证明它的价值。以测试,诊断问题或交付经过验证的应用程序。

    10. 钱包

    Isabella 几乎可以运行 issue.js 发行 MagnetoCorp 商业票据 00001;剩下要做的一项任务!由于 issue.js 代表 Isabella 并因此代表 MagnetoCorp,它将使用其钱包中的身份来反映这些事实。现在,我们需要执行这一一次性活动,向她的钱包添加适当的 X.509 凭据。

    在 Isabella 的终端窗口中,运行 addToWallet.js 程序以向她的钱包添加身份信息:

    (isabella)$ node addToWallet.js
    
    done
    

    Isabella 可以在她的钱包中存储多个身份,尽管在我们的示例中,她仅使用一个身份 - User1@org.example.com。该身份当前与基础网络相关联,而不是与更现实的 PaperNet 配置相关联 - 我们将尽快更新本教程。

    addToWallet.js 是一个简单的文件复制程序,你可以随时检查。它将身份从基础网络示例转移到 Isabella 的钱包。让我们关注这个程序的结果 – 钱包中的内容,这些内容将用于向 PaperNet 提交交易:

    (isabella)$ ls ../identity/user/isabella/wallet/
    
    User1@org1.example.com
    

    查看目录结构如何映射 User1@org1.example.com 身份 - Isabella 使用的其他身份将拥有自己的文件夹。在此目录中,你将找到 issue.js 代表 isabella 使用的身份信息:

    (isabella)$ ls ../identity/user/isabella/wallet/User1@org1.example.com
    
    User1@org1.example.com      c75bd6911a...-priv      c75bd6911a...-pub
    

    注意:

    • 私钥 c75bd6911a...-priv 用于代表 Isabella 签署交易,但并未在她的直接控制范围之外分发。
    • 公钥 c75bd6911a...-pub,该密钥以密码方式链接到 Isabella 的私钥。这完全包含在 Isabella 的 X.509 证书中。
    • 证书 User1@org.example.com,其中包含 Isabella 的公钥以及证书颁发机构在创建证书时添加的其他 X.509 属性。该证书已分发到网络,以便不同的参与者在不同的时间可以通过密码验证由 Isabella 的私钥创建的信息。

    此处 了解有关证书的更多信息。实际上,证书文件还包含一些特定于 Fabric 的元数据,例如 Isabella 的组织和角色 - 在 wallet 主题中了解更多。

    11. 发行应用程序

    Isabella 现在可以使用 issue.js 提交将发行 MagnetoCorp 商业票据 00001 的交易:

    (isabella)$ node issue.js
    
    Connect to Fabric gateway.
    Use network channel: mychannel.
    Use org.papernet.commercialpaper smart contract.
    Submit commercial paper issue transaction.
    Process issue transaction response.{"class":"org.papernet.commercialpaper","key":"\"MagnetoCorp\":\"00001\"","currentState":1,"issuer":"MagnetoCorp","paperNumber":"00001","issueDateTime":"2020-05-31","maturityDateTime":"2020-11-30","faceValue":"5000000","owner":"MagnetoCorp"}
    MagnetoCorp commercial paper : 00001 successfully issued for value 5000000
    Transaction complete.
    Disconnect from Fabric gateway.
    Issue program complete.
    

    node 命令初始化一个 node.js 环境,并运行 issue.js。从程序输出中我们可以看到,发行了面值为 500 万美元的 MagnetoCorp 商业票据 00001。

    如你所见,为实现此目的,该应用程序调用 papercontract.jsCommercialPaper 智能合约中定义的 issue 交易。MagnetoCorp 管理员已在网络中安装并实例化了该文件。这是智能合约,它通过 Fabric API 与帐本进行交互,最著名的是 putState()getState(),以将新的商业票据表示为世界状态内的向量状态。我们将看到随后如何通过智能合约中定义的购买 (buy) 和赎回 (redeem) 交易来操纵此向量状态。

    底层的 Fabric SDK 一直都在处理交易背书,交易排序和通知流程,使应用程序的逻辑变得简单明了;SDK使用 gateway 抽象网络详细信息和 connectionOptions 来声明更高级的处理策略,例如交易重试。

    现在,让我们关注 MagnetoCorp 00001 的生命周期,将重点转移到将购买商业票据的 DigiBank。

    12. 担任 DigiBank 角色

    现在,MagnetoCorp 已发行了商业票据 00001,现在让我们切换上下文,以 DigiBank 的雇员的身份与 PaperNet 进行交互。首先,我们将以管理员身份创建一个配置为与 PaperNet 进行交互的控制台。然后,最终用户 Balaji 将使用 Digibank 的购买 (buy) 应用程序购买商业票据 00001,将其转移到生命周期的下一个阶段。

    image

    DigiBank 管理员和应用程序与 PaperNet 网络交互。

    由于本教程当前使用 PaperNet 的基础网络,因此网络配置非常简单。管理员使用类似于 MagnetoCorp 的控制台,但为 Digibank 的文件系统配置了控制台。同样,Digibank 最终用户将使用与 MagnetoCorp 应用程序调用相同智能合约的应用程序,尽管它们包含 Digibank 特定的逻辑和配置。无论是哪个应用程序调用它们,智能合约都可以捕获共享的业务流程,而账本则可以存储共享的业务数据。

    让我们打开一个单独的终端,以使 DigiBank 管理员可以与 PaperNet 进行交互。在 fabric-samples 中:

    (digibank admin)$ cd commercial-paper/organization/digibank/configuration/cli/
    (digibank admin)$ sudo docker-compose -f docker-compose.yml up -d cliDigiBank
    
    (...)
    Creating cliDigiBank ... done
    

    现在,此 Docker 容器可供 Digibank 管理员与网络交互:

    CONTAINER ID        IMAGE                            COMMAND                  CREATED             STATUS              PORT         NAMES
    858c2d2961d4        hyperledger/fabric-tools         "/bin/bash"              18 seconds ago      Up 18 seconds                    cliDigiBank
    

    在本教程中,你将使用名为 cliDigiBank 的命令行容器代表 DigiBank 与网络进行交互。我们并未显示所有的 Docker 容器,在现实世界中,DigiBank 用户只会看到他们有权访问的网络组件 (对端节点,交易排序器,CA)。

    由于 PaperNet 网络配置非常简单,因此 Digibank 的管理员现在在本教程中不需要做什么工作。让我们把注意力转向 Balaji。

    13. DigiBank 应用程序

    Balaji 使用 DigiBank 的购买 (buy) 应用程序将交易提交到帐本,该帐本将商业票据 00001 的所有权从 MagnetoCorp 转移到 DigiBank。CommercialPaper 智能合约与 MagnetoCorp 的应用程序使用的合约相同,但是这次交易有所不同 – 是购买 (buy) 而不是发行 (issue)。让我们研究一下 DigiBank 应用程序的工作方式。

    打开 Balaji 的单独终端窗口。在 fabric-samples 中,切换到包含应用程序 buy.js 的 DigiBank 应用程序目录,然后使用编辑器将其打开:

    (balaji)$ cd commercial-paper/organization/digibank/application/
    (balaji)$ code buy.js
    

    如你所见,此目录包含 Balaji 将使用的购买 (buy) 和赎回 (redeem) 应用程序。

    image

    DigiBank 的商业票据目录,其中包含 buy.jsredeem.js 应用程序。

    DigiBank 的 buy.js 应用程序的结构与 MagnetoCorp 的 issue.js 相似,但有两个重要区别:

    • 身份 (Identity):该用户是 DigiBank 用户 Balaji,而不是 MagnetoCorp 的 Isabella
    const wallet = new FileSystemWallet('../identity/user/balaji/wallet');`
    
    查看应用程序在连接到 PaperNet 网络通道时如何使用 balaji 钱包。`buy.js` 在 balaji 钱包中选择一个特定的身份。
    
    • 交易 (Transaction):被调用的交易是买入 (buy) 而非发行 (issue)
    `const buyResponse = await contract.submitTransaction('buy', 'MagnetoCorp', '00001'...);`
    
    提交了具有 `MagnetoCorp`,`00001` … 值的购买 (`buy`) 交易,由 `CommercialPaper` 智能合约类使用该交易将商业票据 `00001` 的所有权转让给 DigiBank。
    

    随时检查应用程序目录中的其他文件,以了解应用程序的工作方式,并详细阅读应用程序 主题 中的 buy.js 的实现方式。

    14. 以 DigiBank 身份运行

    购买和赎回商业票据的 DigiBank 应用程序的结构与 MagnetoCorp 的发行应用程序非常相似。因此,让我们安装它们的依赖项并设置 Balaji 的钱包,以便他可以使用这些应用程序购买和赎回商业票据。

    与 MagnetoCorp 一样,Digibank 必须使用 npm install 命令安装所需的应用程序包,这又需要很短的时间才能完成。

    在 DigiBank 管理员窗口中,安装应用程序依赖项:

    (digibank admin)$ cd commercial-paper/organization/digibank/application/
    (digibank admin)$ npm install
    
    (            ) extract:lodash: sill extract ansi-styles@3.2.1
    (...)
    added 738 packages in 46.701s
    

    在 Balaji 的终端窗口中,运行 addToWallet.js 程序以向其钱包添加身份信息:

    (balaji)$ node addToWallet.js
    
    done
    

    addToWallet.js 程序已在他的钱包中添加了 balaji 的身份信息,buy.jsredeem.js 将使用该信息来向 PaperNet 提交交易。

    与 Isabella 一样,Balaji 可以在他的钱包中存储多个身份,尽管在我们的示例中,他仅使用一个身份 – Admin@org.example.com。他对应的钱包结构 digibank/identity/user/balaji/wallet/Admin@org1.example.com 所包含的钱包与伊莎贝拉的钱包非常相似 - 请随时进行检查。

    15. 购买应用程序

    Balaji 现在可以使用 buy.js 提交交易,该交易会将 MagnetoCorp 商业票据 00001 的所有权转让给 DigiBank。

    在 Balaji 的窗口中运行购买 (buy) 应用程序:

    (balaji)$ node buy.js
    
    Connect to Fabric gateway.
    Use network channel: mychannel.
    Use org.papernet.commercialpaper smart contract.
    Submit commercial paper buy transaction.
    Process buy transaction response.
    MagnetoCorp commercial paper : 00001 successfully purchased by DigiBank
    Transaction complete.
    Disconnect from Fabric gateway.
    Buy program complete.
    

    你可以看到程序输出,Balaji 代表 DigiBank 成功购买了 MagnetoCorp 商业票据 00001buy.js 调用了 CommercialPaper 智能合约中定义的购买 (buy) 交易,该合约使用 putState()getState() Fabric API 在世界状态更新了商业票据 00001。如你所见,购买和发行商业票据的应用程序逻辑与智能合约逻辑非常相似。

    16. 赎回应用程序

    商业票据 00001 生命周期中的最后一笔交易是 DigiBank 用 MagnetoCorp 赎回它。Balaji 使用 redeem.js 提交交易以执行智能合约中的赎回逻辑。

    在 Balaji 的窗口中运行赎回 (redeem) 交易:

    (balaji)$ node redeem.js
    
    Connect to Fabric gateway.
    Use network channel: mychannel.
    Use org.papernet.commercialpaper smart contract.
    Submit commercial paper redeem transaction.
    Process redeem transaction response.
    MagnetoCorp commercial paper : 00001 successfully redeemed with MagnetoCorp
    Transaction complete.
    Disconnect from Fabric gateway.
    Redeem program complete.
    

    再次,看看当 redeem.js 调用 CommercialPaper 中定义的赎回 (redeem) 交易时,商业票据 00001 是如何成功赎回的。再次,它更新了世界状态的商业票据 00001,以反映所有权归还给票据发行人 MagnetoCorp。

    17. 进一步阅读

    为了更详细地了解本教程中显示的应用程序和智能合约的工作原理,你会发现阅读 开发应用程序 很有帮助。本主题将为你提供有关商业票据方案,PaperNet 商业网络,其参与者以及他们使用的应用程序和智能合约如何工作的更详细说明。

    也可以随时使用此示例开始创建自己的应用程序和智能合约!

    Reference

    项目源代码

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

    Contributor

    1. Windstamp, https://github.com/windstamp

    相关文章

      网友评论

        本文标题:5.2 Hyperledger Fabric - 教程 - 商业

        本文链接:https://www.haomeiwen.com/subject/ocejgctx.html