github.com/yacovm/fabric@v2.0.0-alpha.0.20191128145320-c5d4087dc723+incompatible/docs/source/tutorial/commercial_paper.md (about)

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