github.com/sykesm/fabric@v1.1.0-preview.0.20200129034918-2aa12b1a0181/docs/source/tutorial/commercial_paper.md (about)

     1  # Commercial paper tutorial
     2  
     3  *Note: This tutorial uses the [1.4.x and older lifecycle process](https://hyperledger-fabric.readthedocs.io/en/release-1.4/chaincode4noah.html) in which a chaincode is instantiated on a channel and does not yet work with the Fabric 2.0 release. The commercial paper tutorial will be updated soon to use a multi-organization network and the new chaincode lifecycle.*
     4  
     5  **Audience:** Architects, application and smart contract developers,
     6  administrators
     7  
     8  This tutorial will show you how to install and use a commercial paper sample
     9  application and smart contract. It is a task-oriented topic, so it emphasizes
    10  procedures above concepts. When you’d like to understand the concepts in more
    11  detail, you can read the
    12  [Developing Applications](../developapps/developing_applications.html) topic.
    13  
    14  ![commercialpaper.tutorial](./commercial_paper.diagram.1.png) *In this tutorial
    15  two organizations, MagnetoCorp and DigiBank, trade commercial paper with each
    16  other using PaperNet, a Hyperledger Fabric blockchain network.*
    17  
    18  Once you've set up a basic network, you'll act as Isabella, an employee of
    19  MagnetoCorp, who will issue a commercial paper on its behalf. You'll then switch
    20  hats to take the role of Balaji, an employee of DigiBank, who will buy this
    21  commercial paper, hold it for a period of time, and then redeem it with
    22  MagnetoCorp for a small profit.
    23  
    24  You'll act as an developer, end user, and administrator, each in different
    25  organizations, performing the following steps designed to help you understand
    26  what it's like to collaborate as two different organizations working
    27  independently, but according to mutually agreed rules in a Hyperledger Fabric
    28  network.
    29  
    30  * [Set up machine](#prerequisites) and [download samples](#download-samples)
    31  * [Create a network](#create-network)
    32  *  Understand the structure of a [smart contract](#smart-contract)
    33  * Work as an organization, [MagnetoCorp](#working-as-magnetocorp), to
    34    [install](#install-contract) and [instantiate](#instantiate-contract) smart
    35    contract
    36  * Understand the structure of a MagnetoCorp
    37    [application](#application-structure), including its
    38    [dependencies](#application-dependencies)
    39  * Configure and use a [wallet and identities](#wallet)
    40  * Run a MagnetoCorp application to [issue a commercial
    41    paper](#issue-application)
    42  * Understand how a second organization, [Digibank](#working-as-digibank), uses
    43    the smart contract in their [applications](#digibank-applications)
    44  * As Digibank, [run](#run-as-digibank) applications that
    45    [buy](#buy-application) and [redeem](#redeem-application) commercial paper
    46  
    47  This tutorial has been tested on MacOS and Ubuntu, and should work on other
    48  Linux distributions. A Windows version is under development.
    49  
    50  ## Prerequisites
    51  
    52  Before you start, you must install some prerequisite technology required by the
    53  tutorial. We've kept these to a minimum so that you can get going quickly.
    54  
    55  You **must** have the following technologies installed:
    56  
    57    * [**Node**](https://nodejs.org/en/about/) version 8.9.0, or higher. Node is
    58      a JavaScript runtime that you can use to run applications and smart
    59      contracts. You are recommended to use the LTS (Long Term Support) version
    60      of node. Install node [here](https://nodejs.org/en/).
    61  
    62  
    63    * [**Docker**](https://www.docker.com/get-started) version 18.06, or higher.
    64      Docker help developers and administrators create standard environments for
    65      building and running applications and smart contracts. Hyperledger Fabric is
    66      provided as a set of Docker images, and the PaperNet smart contract will run
    67      in a docker container. Install Docker
    68      [here](https://www.docker.com/get-started).
    69  
    70  You **will** find it helpful to install the following technologies:
    71  
    72    * A source code editor, such as
    73      [**Visual Studio Code**](https://code.visualstudio.com/) version 1.28, or
    74      higher. VS Code will help you develop and test your application and smart
    75      contract. Install VS Code [here](https://code.visualstudio.com/Download).
    76  
    77      Many excellent code editors are available including
    78      [Atom](https://atom.io/), [Sublime Text](http://www.sublimetext.com/) and
    79      [Brackets](http://www.sublimetext.com/).
    80  
    81  You **may** find it helpful to install the following technologies as you become
    82  more experienced with application and smart contract development. There's no
    83  requirement to install these when you first run the tutorial:
    84  
    85    * [**Node Version Manager**](https://github.com/creationix/nvm). NVM helps you
    86      easily switch between different versions of node -- it can be really helpful
    87      if you're working on multiple projects at the same time. Install NVM
    88      [here](https://github.com/creationix/nvm#installation).
    89  
    90  ## Download samples
    91  
    92  The commercial paper tutorial is one of the Hyperledger Fabric
    93  [samples](https://github.com/hyperledger/fabric-samples) held in a public
    94  [GitHub](https://www.github.com) repository called `fabric-samples`. As you're
    95  going to run the tutorial on your machine, your first task is to download the
    96  `fabric-samples` repository.
    97  
    98  ![commercialpaper.download](./commercial_paper.diagram.2.png) *Download the
    99  `fabric-samples` GitHub repository to your local machine.*
   100  
   101  `$GOPATH` is an important environment variable in Hyperledger Fabric; it
   102  identifies the root directory for installation. It is important to get right no
   103  matter which programming language you're using! Open a new terminal window and
   104  check your `$GOPATH` is set using the `env` command:
   105  
   106  ```
   107  $ env
   108  ...
   109  GOPATH=/Users/username/go
   110  NVM_BIN=/Users/username/.nvm/versions/node/v8.11.2/bin
   111  NVM_IOJS_ORG_MIRROR=https://iojs.org/dist
   112  ...
   113  ```
   114  
   115  Use the following
   116  [instructions](https://github.com/golang/go/wiki/SettingGOPATH) if your
   117  `$GOPATH` is not set.
   118  
   119  You can now create a directory relative to `$GOPATH `where `fabric-samples` will
   120  be installed:
   121  
   122  ```
   123  $ mkdir -p $GOPATH/src/github.com/hyperledger/
   124  $ cd $GOPATH/src/github.com/hyperledger/
   125  ```
   126  
   127  Use the [`git clone`](https://git-scm.com/docs/git-clone) command to copy
   128  [`fabric-samples`](https://github.com/hyperledger/fabric-samples) repository to
   129  this location:
   130  
   131  ```
   132  $ git clone https://github.com/hyperledger/fabric-samples.git
   133  ```
   134  
   135  Feel free to examine the directory structure of `fabric-samples`:
   136  
   137  ```
   138  $ cd fabric-samples
   139  $ ls
   140  
   141  CODE_OF_CONDUCT.md    balance-transfer            fabric-ca
   142  CONTRIBUTING.md       basic-network               first-network
   143  Jenkinsfile           chaincode                   high-throughput
   144  LICENSE               chaincode-docker-devmode    scripts
   145  MAINTAINERS.md        commercial-paper            README.md
   146  fabcar
   147  ```
   148  
   149  Notice the `commercial-paper` directory -- that's where our sample is located!
   150  
   151  You've now completed the first stage of the tutorial! As you proceed, you'll
   152  open multiple command windows open for different users and components. For
   153  example:
   154  
   155  * to run applications on behalf of Isabella and Balaji who will trade commercial
   156    paper with each other
   157  * to issue commands to on behalf of administrators from MagnetoCorp and
   158    DigiBank, including installing and instantiating smart contracts
   159  * to show peer, orderer and CA log output
   160  
   161  We'll make it clear when you should run a command from particular command
   162  window; for example:
   163  
   164  ```
   165  (isabella)$ ls
   166  ```
   167  
   168  indicates that you should run the `ls` command from Isabella's window.
   169  
   170  ## Create network
   171  
   172  The tutorial currently uses the basic network; it will be updated soon to a
   173  configuration which better reflects the multi-organization structure of
   174  PaperNet. For now, this network is sufficient to show you how to develop an
   175  application and smart contract.
   176  
   177  ![commercialpaper.network](./commercial_paper.diagram.3.png) *The Hyperledger
   178  Fabric basic network comprises a peer and its ledger database, an orderer and a
   179  certificate authority (CA). Each of these components runs as a docker
   180  container.*
   181  
   182  The peer, its [ledger](../ledger/ledger.html#world-state-database-options), the
   183  orderer and the CA each run in the their own docker container. In production
   184  environments, organizations typically use existing CAs that are shared with
   185  other systems; they're not dedicated to the Fabric network.
   186  
   187  You can manage the basic network using the commands and configuration included
   188  in the `fabric-samples\basic-network` directory. Let's start the network on your
   189  local machine with the `start.sh` shell script:
   190  
   191  ```
   192  $ cd fabric-samples/basic-network
   193  $ ./start.sh
   194  
   195  docker-compose -f docker-compose.yml up -d ca.example.com orderer.example.com peer0.org1.example.com couchdb
   196  Creating network "net_basic" with the default driver
   197  Pulling ca.example.com (hyperledger/fabric-ca:)...
   198  latest: Pulling from hyperledger/fabric-ca
   199  3b37166ec614: Pull complete
   200  504facff238f: Pull complete
   201  (...)
   202  Pulling orderer.example.com (hyperledger/fabric-orderer:)...
   203  latest: Pulling from hyperledger/fabric-orderer
   204  3b37166ec614: Already exists
   205  504facff238f: Already exists
   206  (...)
   207  Pulling couchdb (hyperledger/fabric-couchdb:)...
   208  latest: Pulling from hyperledger/fabric-couchdb
   209  3b37166ec614: Already exists
   210  504facff238f: Already exists
   211  (...)
   212  Pulling peer0.org1.example.com (hyperledger/fabric-peer:)...
   213  latest: Pulling from hyperledger/fabric-peer
   214  3b37166ec614: Already exists
   215  504facff238f: Already exists
   216  (...)
   217  Creating orderer.example.com ... done
   218  Creating couchdb             ... done
   219  Creating ca.example.com         ... done
   220  Creating peer0.org1.example.com ... done
   221  (...)
   222  2018-11-07 13:47:31.634 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
   223  2018-11-07 13:47:31.730 UTC [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel
   224  ```
   225  
   226  Notice how the `docker-compose -f docker-compose.yml up -d ca.example.com...`
   227  command pulls the four Hyperledger Fabric container images from
   228  [DockerHub](https://hub.docker.com/), and then starts them. These containers
   229  have the most up-to-date version of the software for these Hyperledger Fabric
   230  components. Feel free to explore the `basic-network` directory -- we'll use
   231  much of its contents during this tutorial.
   232  
   233  You can list the docker containers that are running the basic-network components
   234  using the `docker ps` command:
   235  
   236  ```
   237  $ docker ps
   238  
   239  CONTAINER ID        IMAGE                        COMMAND                  CREATED              STATUS              PORTS                                            NAMES
   240  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
   241  1fa1fd107bfb        hyperledger/fabric-orderer   "orderer"                About a minute ago   Up About a minute   0.0.0.0:7050->7050/tcp                           orderer.example.com
   242  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
   243  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
   244  ```
   245  
   246  See if you can map these containers to the basic-network (you may need to
   247  horizontally scroll to locate the information):
   248  
   249  * A peer `peer0.org1.example.com` is running in container `ada3d078989b`
   250  * An orderer `orderer.example.com` is running in container `1fa1fd107bfb`
   251  * A CouchDB database `couchdb` is running in container `53fe614274f7`
   252  * A CA `ca.example.com` is running in container `469201085a20`
   253  
   254  These containers all form a [docker network](https://docs.docker.com/network/)
   255  called `net_basic`. You can view the network with the `docker network` command:
   256  
   257  ```
   258  $ docker network inspect net_basic
   259  
   260      {
   261          "Name": "net_basic",
   262          "Id": "62e9d37d00a0eda6c6301a76022c695f8e01258edaba6f65e876166164466ee5",
   263          "Created": "2018-11-07T13:46:30.4992927Z",
   264          "Containers": {
   265              "1fa1fd107bfbe61522e4a26a57c2178d82b2918d5d423e7ee626c79b8a233624": {
   266                  "Name": "orderer.example.com",
   267                  "IPv4Address": "172.20.0.4/16",
   268              },
   269              "469201085a20b6a8f476d1ac993abce3103e59e3a23b9125032b77b02b715f2c": {
   270                  "Name": "ca.example.com",
   271                  "IPv4Address": "172.20.0.2/16",
   272              },
   273              "53fe614274f7a40392210f980b53b421e242484dd3deac52bbfe49cb636ce720": {
   274                  "Name": "couchdb",
   275                  "IPv4Address": "172.20.0.3/16",
   276              },
   277              "ada3d078989b568c6e060fa7bf62301b4bf55bed8ac1c938d514c81c42d8727a": {
   278                  "Name": "peer0.org1.example.com",
   279                  "IPv4Address": "172.20.0.5/16",
   280              }
   281          },
   282          "Labels": {}
   283      }
   284  ```
   285  
   286  See how the four containers use different IP addresses, while being part of a
   287  single docker network. (We've abbreviated the output for clarity.)
   288  
   289  To recap: you've downloaded the Hyperledger Fabric samples repository from
   290  GitHub and you've got the basic network running on your local machine. Let's now
   291  start to play the role of MagnetoCorp, who wish to trade commercial paper.
   292  
   293  ## Working as MagnetoCorp
   294  
   295  To monitor the MagnetoCorp components of PaperNet, an administrator can view the
   296  aggregated output from a set of docker containers using the `logspout`
   297  [tool](https://github.com/gliderlabs/logspout#logspout). It collects the
   298  different output streams into one place, making it easy to see what's happening
   299  from a single window. This can be really helpful for administrators when
   300  installing smart contracts or for developers when invoking smart contracts, for
   301  example.
   302  
   303  Let's now monitor PaperNet as a MagnetoCorp administrator. Open a new window in
   304  the `fabric-samples` directory, and locate and run the `monitordocker.sh`
   305  script to start the `logspout` tool for the PaperNet docker containers
   306  associated with the docker network `net_basic`:
   307  
   308  ```
   309  (magnetocorp admin)$ cd commercial-paper/organization/magnetocorp/configuration/cli/
   310  (magnetocorp admin)$ ./monitordocker.sh net_basic
   311  ...
   312  latest: Pulling from gliderlabs/logspout
   313  4fe2ade4980c: Pull complete
   314  decca452f519: Pull complete
   315  (...)
   316  Starting monitoring on all containers on the network net_basic
   317  b7f3586e5d0233de5a454df369b8eadab0613886fc9877529587345fc01a3582
   318  ```
   319  
   320  Note that you can pass a port number to the above command if the default port in `monitordocker.sh` is already in use.
   321  ```
   322  (magnetocorp admin)$ ./monitordocker.sh net_basic <port_number>
   323  ```
   324  
   325  This window will now show output from the docker containers, so let's start
   326  another terminal window which will allow the MagnetoCorp administrator to
   327  interact with the network.
   328  
   329  ![commercialpaper.workmagneto](./commercial_paper.diagram.4.png) *A MagnetoCorp
   330  administrator interacts with the network via a docker container.*
   331  
   332  To interact with PaperNet, a MagnetoCorp administrator needs to use the
   333  Hyperledger Fabric `peer` commands. Conveniently, these are available pre-built
   334  in the `hyperledger/fabric-tools`
   335  [docker image](https://hub.docker.com/r/hyperledger/fabric-tools/).
   336  
   337  Let's start a MagnetoCorp-specific docker container for the administrator using
   338  the `docker-compose` [command](https://docs.docker.com/compose/overview/):
   339  
   340  ```
   341  (magnetocorp admin)$ cd commercial-paper/organization/magnetocorp/configuration/cli/
   342  (magnetocorp admin)$ docker-compose -f docker-compose.yml up -d cliMagnetoCorp
   343  
   344  Pulling cliMagnetoCorp (hyperledger/fabric-tools:)...
   345  latest: Pulling from hyperledger/fabric-tools
   346  3b37166ec614: Already exists
   347  (...)
   348  Digest: sha256:058cff3b378c1f3ebe35d56deb7bf33171bf19b327d91b452991509b8e9c7870
   349  Status: Downloaded newer image for hyperledger/fabric-tools:latest
   350  Creating cliMagnetoCorp ... done
   351  ```
   352  
   353  Again, see how the `hyperledger/fabric-tools` docker image was retrieved from
   354  Docker Hub and added to the network:
   355  
   356  ```
   357  (magnetocorp admin)$ docker ps
   358  
   359  CONTAINER ID        IMAGE                        COMMAND                  CREATED              STATUS              PORTS                                            NAMES
   360  562a88b25149        hyperledger/fabric-tools     "/bin/bash"              About a minute ago   Up About a minute                                                    cliMagnetoCorp
   361  b7f3586e5d02        gliderlabs/logspout          "/bin/logspout"          7 minutes ago        Up 7 minutes        127.0.0.1:8000->80/tcp                           logspout
   362  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
   363  1fa1fd107bfb        hyperledger/fabric-orderer   "orderer"                29 minutes ago       Up 29 minutes       0.0.0.0:7050->7050/tcp                           orderer.example.com
   364  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
   365  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
   366  ```
   367  
   368  The MagnetoCorp administrator will use the command line in container
   369  `562a88b25149` to interact with PaperNet. Notice also the `logspout` container
   370  `b7f3586e5d02`; this is capturing the output of all other docker containers for
   371  the `monitordocker.sh` command.
   372  
   373  Let's now use this command line to interact with PaperNet as the MagnetoCorp
   374  administrator.
   375  
   376  ## Smart contract
   377  
   378  `issue`, `buy` and `redeem` are the three functions at the heart of the PaperNet
   379  smart contract. It is used by applications to submit transactions which
   380  correspondingly issue, buy and redeem commercial paper on the ledger. Our next
   381  task is to examine this smart contract.
   382  
   383  Open a new terminal window to represent a MagnetoCorp developer and change to
   384  the directory that contains MagnetoCorp's copy of the smart contract to view it
   385  with your chosen editor (VS Code in this tutorial):
   386  
   387  ```
   388  (magnetocorp developer)$ cd commercial-paper/organization/magnetocorp/contract
   389  (magnetocorp developer)$ code .
   390  ```
   391  
   392  In the `lib` directory of the folder, you'll see `papercontract.js` file -- this
   393  contains the commercial paper smart contract!
   394  
   395  ![commercialpaper.vscode1](./commercial_paper.diagram.10.png) *An example code
   396  editor displaying the commercial paper smart contract in `papercontract.js`*
   397  
   398  `papercontract.js` is a JavaScript program designed to run in the node.js
   399  environment. Note the following key program lines:
   400  
   401  * `const { Contract, Context } = require('fabric-contract-api');`
   402  
   403    This statement brings into scope two key Hyperledger Fabric classes that will
   404    be used extensively by the smart contract  -- `Contract` and `Context`. You
   405    can learn more about these classes in the
   406    [`fabric-shim` JSDOCS](https://fabric-shim.github.io/).
   407  
   408  
   409  * `class CommercialPaperContract extends Contract {`
   410  
   411    This defines the smart contract class `CommercialPaperContract` based on the
   412    built-in Fabric `Contract` class.  The methods which implement the key
   413    transactions to `issue`, `buy` and `redeem` commercial paper are defined
   414    within this class.
   415  
   416  
   417  * `async issue(ctx, issuer, paperNumber, issueDateTime, maturityDateTime...) {`
   418  
   419    This method defines the commercial paper `issue` transaction for PaperNet. The
   420    parameters that are passed to this method will be used to create the new
   421    commercial paper.
   422  
   423    Locate and examine the `buy` and `redeem` transactions within the smart
   424    contract.
   425  
   426  
   427  * `let paper = CommercialPaper.createInstance(issuer, paperNumber, issueDateTime...);`
   428  
   429    Within the `issue` transaction, this statement creates a new commercial paper
   430    in memory using the `CommercialPaper` class with the supplied transaction
   431    inputs. Examine the `buy` and `redeem` transactions to see how they similarly
   432    use this class.
   433  
   434  
   435  * `await ctx.paperList.addPaper(paper);`
   436  
   437    This statement adds the new commercial paper to the ledger using
   438    `ctx.paperList`, an instance of a `PaperList` class that was created when the
   439    smart contract context `CommercialPaperContext` was initialized. Again,
   440    examine the `buy` and `redeem` methods to see how they use this class.
   441  
   442  
   443  * `return paper.toBuffer();`
   444  
   445    This statement returns a binary buffer as response from the `issue`
   446    transaction for processing by the caller of the smart contract.
   447  
   448  
   449  Feel free to examine other files in the `contract` directory to understand how
   450  the smart contract works, and read in detail how `papercontract.js` is
   451  designed in the smart contract [topic](../developapps/smartcontract.html).
   452  
   453  ## Install contract
   454  
   455  Before `papercontract` can be invoked by applications, it must be installed onto
   456  the appropriate peer nodes in PaperNet.  MagnetoCorp and DigiBank administrators
   457  are able to install `papercontract` onto peers over which they respectively have
   458  authority.
   459  
   460  ![commercialpaper.install](./commercial_paper.diagram.6.png) *A MagnetoCorp
   461  administrator installs a copy of the `papercontract` onto a MagnetoCorp peer.*
   462  
   463  Smart contracts are the focus of application development, and are contained
   464  within a Hyperledger Fabric artifact called [chaincode](../chaincode.html). One
   465  or more smart contracts can be defined within a single chaincode, and installing
   466  a chaincode will allow them to be consumed by the different organizations in
   467  PaperNet.  It means that only administrators need to worry about chaincode;
   468  everyone else can think in terms of smart contracts.
   469  
   470  The MagnetoCorp administrator uses the `peer chaincode install` command to copy
   471  the `papercontract` smart contract from their local machine's file system to the
   472  file system within the target peer's docker container. Once the smart contract
   473  is installed on the peer and instantiated on a channel,
   474  `papercontract` can be invoked by applications, and interact with the ledger
   475  database via the
   476  [putState()](https://fabric-shim.github.io/release-1.4/fabric-shim.ChaincodeStub.html#putState__anchor)
   477  and
   478  [getState()](https://fabric-shim.github.io/release-1.4/fabric-shim.ChaincodeStub.html#getState__anchor)
   479  Fabric APIs. Examine how these APIs are used by `StateList` class within
   480  `ledger-api\statelist.js`.
   481  
   482  Let's now install `papercontract` as the MagnetoCorp administrator. In the
   483  MagnetoCorp administrator's command window, use the `docker exec` command to run
   484  the `peer chaincode install` command in the `cliMagnetCorp` container:
   485  
   486  ```
   487  (magnetocorp admin)$ docker exec cliMagnetoCorp peer chaincode install -n papercontract -v 0 -p /opt/gopath/src/github.com/contract -l node
   488  
   489  2018-11-07 14:21:48.400 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 001 Using default escc
   490  2018-11-07 14:21:48.400 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 002 Using default vscc
   491  2018-11-07 14:21:48.466 UTC [chaincodeCmd] install -> INFO 003 Installed remotely response:<status:200 payload:"OK" >
   492  ```
   493  
   494  The `cliMagnetCorp` container has set
   495  `CORE_PEER_ADDRESS=peer0.org1.example.com:7051` to target its commands to
   496  `peer0.org1.example.com`, and the `INFO 003 Installed remotely...` indicates
   497  `papercontract` has been successfully installed on this peer. Currently, the
   498  MagnetoCorp administrator only has to install a copy of `papercontract` on a
   499  single MagentoCorp peer.
   500  
   501  Note how `peer chaincode install` command specified the smart contract path,
   502  `-p`, relative to the `cliMagnetoCorp` container's file system:
   503  `/opt/gopath/src/github.com/contract`. This path has been mapped to the local
   504  file system path `.../organization/magnetocorp/contract` via the
   505  `magnetocorp/configuration/cli/docker-compose.yml` file:
   506  
   507  ```yaml
   508  volumes:
   509      - ...
   510      - ./../../../../organization/magnetocorp:/opt/gopath/src/github.com/
   511      - ...
   512  ```
   513  
   514  See how the `volume` directive maps `organization/magnetocorp` to
   515  `/opt/gopath/src/github.com/` providing this container access to your local file
   516  system where MagnetoCorp's copy of the `papercontract` smart contract is held.
   517  
   518  You can read more about `docker compose`
   519  [here](https://docs.docker.com/compose/overview/) and `peer chaincode install`
   520  command [here](../commands/peerchaincode.html).
   521  
   522  ## Instantiate contract
   523  
   524  Now that `papercontract` chaincode containing the `CommercialPaper` smart
   525  contract is installed on the required PaperNet peers, an administrator can make
   526  it available to different network channels, so that it can be invoked by
   527  applications connected to those channels. Because we're using the basic network
   528  configuration for PaperNet, we're only going to make `papercontract` available
   529  in a single network channel, `mychannel`.
   530  
   531  ![commercialpaper.instant](./commercial_paper.diagram.7.png) *A MagnetoCorp
   532  administrator instantiates `papercontract` chaincode containing the smart
   533  contract. A new docker chaincode container will be created to run
   534  `papercontract`.*
   535  
   536  The MagnetoCorp administrator uses the `peer chaincode instantiate` command to
   537  instantiate `papercontract` on `mychannel`:
   538  
   539  ```
   540  (magnetocorp admin)$ docker exec cliMagnetoCorp peer chaincode instantiate -n papercontract -v 0 -l node -c '{"Args":["org.papernet.commercialpaper:instantiate"]}' -C mychannel -P "AND ('Org1MSP.member')"
   541  
   542  2018-11-07 14:22:11.162 UTC [chaincodeCmd] InitCmdFactory -> INFO 001 Retrieved channel (mychannel) orderer endpoint: orderer.example.com:7050
   543  2018-11-07 14:22:11.163 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 002 Using default escc
   544  2018-11-07 14:22:11.163 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 003 Using default vscc
   545  ```
   546  This command may take a few minutes to complete.
   547  
   548  One of the most important parameters on `instantiate` is `-P`. It specifies the
   549  [endorsement policy](../endorsement-policies.html) for `papercontract`,
   550  describing the set of organizations that must endorse (execute and sign) a
   551  transaction before it can be determined as valid. All transactions, whether
   552  valid or invalid, will be recorded on the [ledger blockchain](../ledger/ledger.html#blockchain),
   553  but only valid transactions will update the [world
   554  state](../ledger/ledger.html#world-state).
   555  
   556  In passing, see how `instantiate` passes the orderer address
   557  `orderer.example.com:7050`. This is because it additionally submits an
   558  instantiate transaction to the orderer, which will include the transaction
   559  in the next block and distribute the transaction to all peers that have joined
   560  `mychannel`, enabling any peer to execute the chaincode in their own
   561  isolated chaincode container. Note that `instantiate` only needs to be issued
   562  once for the channel where `papercontract` will run even though typically it is
   563  installed on many peers.
   564  
   565  See how a `papercontract` container has been started with the `docker ps`
   566  command:
   567  
   568  ```
   569  (magnetocorp admin)$ docker ps
   570  
   571  CONTAINER ID        IMAGE                                              COMMAND                  CREATED             STATUS              PORTS          NAMES
   572  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
   573  ```
   574  
   575  Notice that the container is named
   576  `dev-peer0.org1.example.com-papercontract-0-d96...` to indicate which peer
   577  started it, and the fact that it's running `papercontract` version `0`.
   578  
   579  Now that we've got a basic PaperNet up and running, and `papercontract`
   580  installed and instantiated, let's turn our attention to the MagnetoCorp
   581  application which issues a commercial paper.
   582  
   583  ## Application structure
   584  
   585  The smart contract contained in `papercontract` is called by MagnetoCorp's
   586  application `issue.js`. Isabella uses this application to submit a transaction
   587  to the ledger which issues commercial paper `00001`. Let's quickly examine how
   588  the `issue` application works.
   589  
   590  ![commercialpaper.application](./commercial_paper.diagram.8.png) *A gateway
   591  allows an application to focus on transaction generation, submission and
   592  response. It coordinates transaction proposal, ordering and notification
   593  processing between the different network components.*
   594  
   595  Because the `issue` application submits transactions on behalf of Isabella, it
   596  starts by retrieving Isabella's X.509 certificate from her
   597  [wallet](../developapps/wallet.html), which might be stored on the local file
   598  system or a Hardware Security Module
   599  [HSM](https://en.wikipedia.org/wiki/Hardware_security_module). The `issue`
   600  application is then able to utilize the gateway to submit transactions on the
   601  channel. The Hyperledger Fabric SDK provides a
   602  [gateway](../developapps/gateway.html) abstraction so that applications can
   603  focus on application logic while delegating network interaction to the
   604  gateway. Gateways and wallets make it straightforward to write Hyperledger
   605  Fabric applications.
   606  
   607  So let's examine the `issue` application that Isabella is going to use. open a
   608  separate terminal window for her, and in `fabric-samples` locate the MagnetoCorp
   609  `/application` folder:
   610  
   611  ```
   612  (magnetocorp user)$ cd commercial-paper/organization/magnetocorp/application/
   613  (magnetocorp user)$ ls
   614  
   615  addToWallet.js		issue.js		package.json
   616  ```
   617  
   618  `addToWallet.js` is the program that Isabella is going to use to load her
   619  identity into her wallet, and `issue.js` will use this identity to create
   620  commercial paper `00001` on behalf of MagnetoCorp by invoking `papercontract`.
   621  
   622  Change to the directory that contains MagnetoCorp's copy of the application
   623  `issue.js`, and use your code editor to examine it:
   624  
   625  ```
   626  (magnetocorp user)$ cd commercial-paper/organization/magnetocorp/application
   627  (magnetocorp user)$ code issue.js
   628  ```
   629  
   630  Examine this directory; it contains the issue application and all its
   631  dependencies.
   632  
   633  ![commercialpaper.vscode2](./commercial_paper.diagram.11.png) *A code editor
   634  displaying the contents of the commercial paper application directory.*
   635  
   636  Note the following key program lines in `issue.js`:
   637  
   638  * `const { FileSystemWallet, Gateway } = require('fabric-network');`
   639  
   640    This statement brings two key Hyperledger Fabric SDK classes into scope --
   641    `Wallet` and `Gateway`. Because Isabella's X.509 certificate is in the local
   642    file system, the application uses `FileSystemWallet`.
   643  
   644  
   645  * `const wallet = new FileSystemWallet('../identity/user/isabella/wallet');`
   646  
   647    This statement identifies that the application will use `isabella` wallet when
   648    it connects to the blockchain network channel. The application will select a
   649    particular identity within `isabella` wallet. (The wallet must have been
   650    loaded with the Isabella's X.509 certificate -- that's what `addToWallet.js`
   651    does.)
   652  
   653  
   654  * `await gateway.connect(connectionProfile, connectionOptions);`
   655  
   656    This line of code connects to the network using the gateway identified by
   657    `connectionProfile`, using the identity referred to in `ConnectionOptions`.
   658  
   659    See how `../gateway/networkConnection.yaml` and `User1@org1.example.com` are
   660    used for these values respectively.
   661  
   662  
   663  * `const network = await gateway.getNetwork('mychannel');`
   664  
   665    This connects the application to the network channel `mychannel`, where the
   666    `papercontract` was previously instantiated.
   667  
   668  
   669  *  `const contract = await network.getContract('papercontract', 'org.papernet.comm...');`
   670  
   671    This statement gives the application addressability to smart contract defined
   672    by the namespace `org.papernet.commercialpaper` within `papercontract`. Once
   673    an application has issued getContract, it can submit any transaction
   674    implemented within it.
   675  
   676  
   677  * `const issueResponse = await contract.submitTransaction('issue', 'MagnetoCorp', '00001'...);`
   678  
   679    This line of code submits the a transaction to the network using the `issue`
   680    transaction defined within the smart contract. `MagnetoCorp`, `00001`... are
   681    the values to be used by the `issue` transaction to create a new commercial
   682    paper.
   683  
   684  * `let paper = CommercialPaper.fromBuffer(issueResponse);`
   685  
   686    This statement processes the response from the `issue` transaction. The
   687    response needs to deserialized from a buffer into `paper`, a `CommercialPaper`
   688    object which can interpreted correctly by the application.
   689  
   690  
   691  Feel free to examine other files in the `/application` directory to understand
   692  how `issue.js` works, and read in detail how it is implemented in the
   693  application [topic](../developapps/application.html).
   694  
   695  ## Application dependencies
   696  
   697  The `issue.js` application is written in JavaScript and designed to run in the
   698  node.js environment that acts as a client to the PaperNet network.
   699  As is common practice, MagnetoCorp's application is built on many
   700  external node packages -- to improve quality and speed of development. Consider
   701  how `issue.js` includes the `js-yaml`
   702  [package](https://www.npmjs.com/package/js-yaml) to process the YAML gateway
   703  connection profile, or the `fabric-network`
   704  [package](https://www.npmjs.com/package/fabric-network) to access the `Gateway`
   705  and `Wallet` classes:
   706  
   707  ```JavaScript
   708  const yaml = require('js-yaml');
   709  const { FileSystemWallet, Gateway } = require('fabric-network');
   710  ```
   711  
   712  These packages have to be downloaded from [npm](https://www.npmjs.com/) to the
   713  local file system using the `npm install` command. By convention, packages must
   714  be installed into an application-relative `/node_modules` directory for use at
   715  runtime.
   716  
   717  Examine the `package.json` file to see how `issue.js` identifies the packages to
   718  download and their exact versions:
   719  
   720  ```json
   721    "dependencies": {
   722      "fabric-network": "~1.4.0",
   723      "fabric-client": "~1.4.0",
   724      "js-yaml": "^3.12.0"
   725    },
   726  ```
   727  
   728  **npm** versioning is very powerful; you can read more about it
   729  [here](https://docs.npmjs.com/getting-started/semantic-versioning).
   730  
   731  Let's install these packages with the `npm install` command -- this may take up
   732  to a minute to complete:
   733  
   734  ```
   735  (magnetocorp user)$ cd commercial-paper/organization/magnetocorp/application/
   736  (magnetocorp user)$ npm install
   737  
   738  (           ) extract:lodash: sill extract ansi-styles@3.2.1
   739  (...)
   740  added 738 packages in 46.701s
   741  ```
   742  
   743  See how this command has updated the directory:
   744  
   745  ```
   746  (magnetocorp user)$ ls
   747  
   748  addToWallet.js		node_modules	      	package.json
   749  issue.js	      	package-lock.json
   750  ```
   751  
   752  Examine the `node_modules` directory to see the packages that have been
   753  installed. There are lots, because `js-yaml` and `fabric-network` are themselves
   754  built on other npm packages! Helpfully, the `package-lock.json`
   755  [file](https://docs.npmjs.com/files/package-lock.json) identifies the exact
   756  versions installed, which can prove invaluable if you want to exactly reproduce
   757  environments; to test, diagnose problems or deliver proven applications for
   758  example.
   759  
   760  ## Wallet
   761  
   762  Isabella is almost ready to run `issue.js` to issue MagnetoCorp commercial paper
   763  `00001`; there's just one remaining task to perform! As `issue.js` acts on
   764  behalf of Isabella, and therefore MagnetoCorp, it will use identity from her
   765  [wallet](../developapps/wallet.html) that reflects these facts. We now need to
   766  perform this one-time activity of adding appropriate X.509 credentials to her
   767  wallet.
   768  
   769  In Isabella's terminal window, run the `addToWallet.js` program to add identity
   770  information to her wallet:
   771  
   772  ```
   773  (isabella)$ node addToWallet.js
   774  
   775  done
   776  ```
   777  
   778  Isabella can store multiple identities in her wallet, though in our example, she
   779  only uses one -- `User1@org.example.com`. This identity is currently associated
   780  with the basic network, rather than a more realistic PaperNet configuration --
   781  we'll update this tutorial soon.
   782  
   783  `addToWallet.js` is a simple file-copying program which you can examine at your
   784  leisure. It moves an identity from the basic network sample to Isabella's
   785  wallet. Let's focus on the result of this program -- the contents of
   786  the wallet which will be used to submit transactions to `PaperNet`:
   787  
   788  ```
   789  (isabella)$ ls ../identity/user/isabella/wallet/
   790  
   791  User1@org1.example.com
   792  ```
   793  
   794  See how the directory structure maps the `User1@org1.example.com` identity --
   795  other identities used by Isabella would have their own folder. Within this
   796  directory you'll find the identity information that `issue.js` will use on
   797  behalf of `isabella`:
   798  
   799  
   800  ```
   801  (isabella)$ ls ../identity/user/isabella/wallet/User1@org1.example.com
   802  
   803  User1@org1.example.com      c75bd6911a...-priv      c75bd6911a...-pub
   804  ```
   805  
   806  Notice:
   807  
   808  * a private key `c75bd6911a...-priv` used to sign transactions on Isabella's
   809    behalf, but not distributed outside of her immediate control.
   810  
   811  
   812  * a public key `c75bd6911a...-pub` which is cryptographically linked to
   813    Isabella's private key. This is wholly contained within Isabella's X.509
   814    certificate.
   815  
   816  
   817  * a certificate `User1@org.example.com` which contains Isabella's public key
   818    and other X.509 attributes added by the Certificate Authority at certificate
   819    creation. This certificate is distributed to the network so that different
   820    actors at different times can cryptographically verify information created by
   821    Isabella's private key.
   822  
   823    Learn more about certificates
   824    [here](../identity/identity.html#digital-certificates). In practice, the
   825    certificate file also contains some Fabric-specific metadata such as
   826    Isabella's organization and role -- read more in the
   827    [wallet](../developapps/wallet.html) topic.
   828  
   829  ## Issue application
   830  
   831  Isabella can now use `issue.js` to submit a transaction that will issue
   832  MagnetoCorp commercial paper `00001`:
   833  
   834  ```
   835  (isabella)$ node issue.js
   836  
   837  Connect to Fabric gateway.
   838  Use network channel: mychannel.
   839  Use org.papernet.commercialpaper smart contract.
   840  Submit commercial paper issue transaction.
   841  Process issue transaction response.
   842  MagnetoCorp commercial paper : 00001 successfully issued for value 5000000
   843  Transaction complete.
   844  Disconnect from Fabric gateway.
   845  Issue program complete.
   846  ```
   847  
   848  The `node` command initializes a node.js environment, and runs `issue.js`. We
   849  can see from the program output that MagnetoCorp commercial paper 00001 was
   850  issued with a face value of 5M USD.
   851  
   852  As you've seen, to achieve this, the application invokes the `issue` transaction
   853  defined in the `CommercialPaper` smart contract within `papercontract.js`. This
   854  had been installed and instantiated in the network by the MagnetoCorp
   855  administrator. It's the smart contract which interacts with the ledger via the
   856  Fabric APIs, most notably `putState()` and `getState()`, to represent the new
   857  commercial paper as a vector state within the world state. We'll see how this
   858  vector state is subsequently manipulated by the `buy` and `redeem` transactions
   859  also defined within the smart contract.
   860  
   861  All the time, the underlying Fabric SDK handles the transaction endorsement,
   862  ordering and notification process, making the application's logic
   863  straightforward; the SDK uses a [gateway](../developapps/gateway.html) to
   864  abstract away network details and
   865  [connectionOptions](../developapps/connectoptions.html) to declare more advanced
   866  processing strategies such as transaction retry.
   867  
   868  Let's now follow the lifecycle of MagnetoCorp `00001` by switching our emphasis
   869  to DigiBank, who will buy the commercial paper.
   870  
   871  ## Working as DigiBank
   872  
   873  Now that commercial paper `00001`has been issued by MagnetoCorp, let's switch
   874  context to interact with PaperNet as employees of DigiBank. First, we'll act as
   875  administrator who will create a console configured to interact with PaperNet.
   876  Then Balaji, an end user, will use Digibank's `buy` application to buy
   877  commercial paper `00001`, moving it to the next stage in its lifecycle.
   878  
   879  ![commercialpaper.workdigi](./commercial_paper.diagram.5.png) *DigiBank
   880  administrators and applications interact with the PaperNet network.*
   881  
   882  As the tutorial currently uses the basic network for PaperNet, the network
   883  configuration is quite simple. Administrators use a console similar to
   884  MagnetoCorp, but configured for Digibank's file system. Likewise, Digibank end
   885  users will use applications which invoke the same smart contract as MagnetoCorp
   886  applications, though they contain Digibank-specific logic and configuration.
   887  It's the smart contract which captures the shared business process, and the
   888  ledger which holds the shared business data, no matter which applications call
   889  them.
   890  
   891  Let's open up a separate terminal to allow the DigiBank administrator to
   892  interact with PaperNet. In `fabric-samples`:
   893  
   894  ```
   895  (digibank admin)$ cd commercial-paper/organization/digibank/configuration/cli/
   896  (digibank admin)$ docker-compose -f docker-compose.yml up -d cliDigiBank
   897  
   898  (...)
   899  Creating cliDigiBank ... done
   900  ```
   901  
   902  This docker container is now available for Digibank administrators to interact
   903  with the network:
   904  
   905  ```(digibank admin)$ docker ps
   906  CONTAINER ID        IMAGE                            COMMAND                  CREATED             STATUS              PORT         NAMES
   907  858c2d2961d4        hyperledger/fabric-tools         "/bin/bash"              18 seconds ago      Up 18 seconds                    cliDigiBank
   908  ```
   909  
   910  In this tutorial, you'll use the command line container named `cliDigiBank` to
   911  interact with the network on behalf of DigiBank. We've not shown all the docker
   912  containers, and in the real world DigiBank users would only see the network
   913  components (peers, orderers, CAs) to which they have access.
   914  
   915  Digibank's administrator doesn't have much to do in this tutorial right now
   916  because the PaperNet network configuration is so simple. Let's turn our
   917  attention to Balaji.
   918  
   919  ## Digibank applications
   920  
   921  Balaji uses DigiBank's `buy` application to submit a transaction to the ledger
   922  which transfers ownership of commercial paper `00001` from MagnetoCorp to
   923  DigiBank. The `CommercialPaper` smart contract is the same as that used by
   924  MagnetoCorp's application, however the transaction is different this time --
   925  it's `buy` rather than `issue`. Let's examine how DigiBank's application works.
   926  
   927  Open a separate terminal window for Balaji. In `fabric-samples`, change to the
   928  DigiBank application directory that contains the application, `buy.js`, and open
   929  it with your editor:
   930  
   931  ```
   932  (balaji)$ cd commercial-paper/organization/digibank/application/
   933  (balaji)$ code buy.js
   934  ```
   935  
   936  As you can see, this directory contains both the `buy` and `redeem` applications
   937  that will be used by Balaji.
   938  
   939  
   940  
   941  ![commercialpaper.vscode3](./commercial_paper.diagram.12.png) *DigiBank's
   942  commercial paper directory containing the `buy.js` and `redeem.js`
   943  applications.*
   944  
   945  DigiBank's `buy.js` application is very similar in structure to MagnetoCorp's
   946  `issue.js` with two important differences:
   947  
   948  
   949    * **Identity**: the user is a DigiBank user `Balaji` rather than MagnetoCorp's
   950      `Isabella`
   951  
   952      ```JavaScript
   953      const wallet = new FileSystemWallet('../identity/user/balaji/wallet');`
   954      ```
   955  
   956      See how the application uses the `balaji` wallet when it connects to the
   957      PaperNet network channel. `buy.js` selects a particular identity within
   958      `balaji` wallet.
   959  
   960  
   961    * **Transaction**: the invoked transaction is `buy` rather than `issue`
   962  
   963      ```JavaScript
   964      `const buyResponse = await contract.submitTransaction('buy', 'MagnetoCorp', '00001'...);`
   965      ```
   966  
   967      A `buy` transaction is submitted with the values `MagnetoCorp`, `00001`...,
   968      that are used by the `CommercialPaper` smart contract class to transfer
   969      ownership of commercial paper `00001` to DigiBank.
   970  
   971  Feel free to examine other files in the `application` directory to understand
   972  how the application works, and read in detail how `buy.js` is implemented in
   973  the application [topic](../developapps/application.html).
   974  
   975  ## Run as DigiBank
   976  
   977  The DigiBank applications which buy and redeem commercial paper have a very
   978  similar structure to MagnetoCorp's issue application. Therefore, let’s install
   979  their dependencies and set up Balaji's wallet so that he can use these
   980  applications to buy and redeem commercial paper.
   981  
   982  Like MagnetoCorp, Digibank must the install the required application packages
   983  using the `npm install` command, and again, this make take a short time to
   984  complete.
   985  
   986  In the DigiBank administrator window, install the application dependencies:
   987  
   988  ```
   989  (digibank admin)$ cd commercial-paper/organization/digibank/application/
   990  (digibank admin)$ npm install
   991  
   992  (            ) extract:lodash: sill extract ansi-styles@3.2.1
   993  (...)
   994  added 738 packages in 46.701s
   995  ```
   996  
   997  In Balaji's terminal window, run the `addToWallet.js` program to add identity
   998  information to his wallet:
   999  
  1000  ```
  1001  (balaji)$ node addToWallet.js
  1002  
  1003  done
  1004  ```
  1005  
  1006  The `addToWallet.js` program has added identity information for `balaji`, to his
  1007  wallet, which will be used by `buy.js` and `redeem.js` to submit transactions to
  1008  `PaperNet`.
  1009  
  1010  Like Isabella, Balaji can store multiple identities in his wallet, though in our
  1011  example, he only uses one -- `Admin@org.example.com`. His corresponding wallet
  1012  structure `digibank/identity/user/balaji/wallet/Admin@org1.example.com`
  1013  contains is very similar Isabella's -- feel free to examine it.
  1014  
  1015  ## Buy application
  1016  
  1017  Balaji can now use `buy.js` to submit a transaction that will transfer ownership
  1018  of MagnetoCorp commercial paper `00001` to DigiBank.
  1019  
  1020  Run the `buy` application in Balaji's window:
  1021  
  1022  ```
  1023  (balaji)$ node buy.js
  1024  
  1025  Connect to Fabric gateway.
  1026  Use network channel: mychannel.
  1027  Use org.papernet.commercialpaper smart contract.
  1028  Submit commercial paper buy transaction.
  1029  Process buy transaction response.
  1030  MagnetoCorp commercial paper : 00001 successfully purchased by DigiBank
  1031  Transaction complete.
  1032  Disconnect from Fabric gateway.
  1033  Buy program complete.
  1034  ```
  1035  
  1036  You can see the program output that MagnetoCorp commercial paper 00001 was
  1037  successfully purchased by Balaji on behalf of DigiBank. `buy.js` invoked the
  1038  `buy` transaction defined in the `CommercialPaper` smart contract which updated
  1039  commercial paper `00001` within the world state using the `putState()` and
  1040  `getState()` Fabric APIs. As you've seen, the application logic to buy and issue
  1041  commercial paper is very similar, as is the smart contract logic.
  1042  
  1043  ## Redeem application
  1044  
  1045  The final transaction in the lifecycle of commercial paper `00001` is for
  1046  DigiBank to redeem it with MagnetoCorp. Balaji uses `redeem.js` to submit a
  1047  transaction to perform the redeem logic within the smart contract.
  1048  
  1049  Run the `redeem` transaction in Balaji's window:
  1050  
  1051  ```
  1052  (balaji)$ node redeem.js
  1053  
  1054  Connect to Fabric gateway.
  1055  Use network channel: mychannel.
  1056  Use org.papernet.commercialpaper smart contract.
  1057  Submit commercial paper redeem transaction.
  1058  Process redeem transaction response.
  1059  MagnetoCorp commercial paper : 00001 successfully redeemed with MagnetoCorp
  1060  Transaction complete.
  1061  Disconnect from Fabric gateway.
  1062  Redeem program complete.
  1063  ```
  1064  
  1065  Again, see how the commercial paper 00001 was successfully redeemed when
  1066  `redeem.js` invoked the `redeem` transaction defined in `CommercialPaper`.
  1067  Again, it updated commercial paper `00001` within the world state to reflect
  1068  that the ownership returned to MagnetoCorp, the issuer of the paper.
  1069  
  1070  ## Further reading
  1071  
  1072  To understand how applications and smart contracts shown in this tutorial work
  1073  in more detail, you'll find it helpful to read
  1074  [Developing Applications](../developapps/developing_applications.html). This
  1075  topic will give you a fuller explanation of the commercial paper scenario, the
  1076  `PaperNet` business network, its actors, and how the applications and smart
  1077  contracts they use work in detail.
  1078  
  1079  Also feel free to use this sample to start creating your own applications and
  1080  smart contracts!
  1081  
  1082  <!--- Licensed under Creative Commons Attribution 4.0 International License
  1083  https://creativecommons.org/licenses/by/4.0/ -->