github.com/true-sqn/fabric@v2.1.1+incompatible/docs/source/developapps/application.md (about)

     1  # Application
     2  
     3  **Audience**: Architects, Application and smart contract developers
     4  
     5  An application can interact with a blockchain network by submitting transactions
     6  to a ledger or querying ledger content. This topic covers the mechanics of how
     7  an application does this; in our scenario, organizations access PaperNet using
     8  applications which invoke **issue**, **buy** and **redeem** transactions
     9  defined in a commercial paper smart contract. Even though MagnetoCorp's
    10  application to issue a commercial paper is basic, it covers all the major points
    11  of understanding.
    12  
    13  In this topic, we're going to cover:
    14  
    15  * [The application flow to invoke a smart contract](#basic-flow)
    16  * [How an application uses a wallet and identity](#wallet)
    17  * [How an application connects using a gateway](#gateway)
    18  * [How to access a particular network](#network-channel)
    19  * [How to construct a transaction request](#construct-request)
    20  * [How to submit a transaction](#submit-transaction)
    21  * [How to process a transaction response](#process-response)
    22  
    23  To help your understanding, we'll make reference to the commercial paper sample
    24  application provided with Hyperledger Fabric. You can [download
    25  it](../install.html) and [run it locally](../tutorial/commercial_paper.html). It
    26  is written in both JavaScript and Java, but the logic is quite language independent, so you'll
    27  easily be able to see what's going on! (The sample will become available for  Go as well.)
    28  
    29  ## Basic Flow
    30  
    31  An application interacts with a blockchain network using the Fabric SDK. Here's
    32  a simplified diagram of how an application invokes a commercial paper smart
    33  contract:
    34  
    35  ![develop.application](./develop.diagram.3.png) *A PaperNet application invokes
    36  the commercial paper smart contract to submit an issue transaction request.*
    37  
    38  An application has to follow six basic steps to submit a transaction:
    39  
    40  * Select an identity from a wallet
    41  * Connect to a gateway
    42  * Access the desired network
    43  * Construct a transaction request for a smart contract
    44  * Submit the transaction to the network
    45  * Process the response
    46  
    47  You're going to see how a typical application performs these six steps using the
    48  Fabric SDK. You'll find the application code in the `issue.js` file. [View
    49  it](https://github.com/hyperledger/fabric-samples/blob/{BRANCH}/commercial-paper/organization/magnetocorp/application/issue.js)
    50  in your browser, or open it in your favourite editor if you've downloaded it.
    51  Spend a few moments looking at the overall structure of the application; even
    52  with comments and spacing, it's only 100 lines of code!
    53  
    54  ## Wallet
    55  
    56  Towards the top of `issue.js`, you'll see two Fabric classes are brought
    57  into scope:
    58  
    59  ```JavaScript
    60  const { Wallets, Gateway } = require('fabric-network');
    61  ```
    62  
    63  You can read about the `fabric-network` classes in the
    64  [node SDK documentation](https://hyperledger.github.io/fabric-sdk-node/{BRANCH}/module-fabric-network.html), but for
    65  now, let's see how they are used to connect MagnetoCorp's application to
    66  PaperNet. The application uses the Fabric **Wallet** class as follows:
    67  
    68  ```JavaScript
    69  const wallet = await Wallets.newFileSystemWallet('../identity/user/isabella/wallet');
    70  ```
    71  
    72  See how `wallet` locates a [wallet](./wallet.html) in the local filesystem. The
    73  identity retrieved from the wallet is clearly for a user called Isabella, who is
    74  using the `issue` application. The wallet holds a set of identities -- X.509
    75  digital certificates -- which can be used to access PaperNet or any other Fabric
    76  network. If you run the tutorial, and look in this directory, you'll see the
    77  identity credentials for Isabella.
    78  
    79  Think of a [wallet](./wallet.html) holding the digital equivalents of your
    80  government ID, driving license or ATM card. The X.509 digital certificates
    81  within it will associate the holder with a organization, thereby entitling them
    82  to rights in a network channel. For example, `Isabella` might be an
    83  administrator in MagnetoCorp, and this could give her more privileges than a
    84  different user -- `Balaji` from DigiBank.  Moreover, a smart contract can
    85  retrieve this identity during smart contract processing using the [transaction
    86  context](./transactioncontext.html).
    87  
    88  Note also that wallets don't hold any form of cash or tokens -- they hold
    89  identities.
    90  
    91  ## Gateway
    92  
    93  The second key class is a Fabric **Gateway**. Most importantly, a
    94  [gateway](./gateway.html) identifies one or more peers that provide access to a
    95  network -- in our case, PaperNet. See how `issue.js` connects to its gateway:
    96  
    97  ```JavaScript
    98  await gateway.connect(connectionProfile, connectionOptions);
    99  ```
   100  
   101  `gateway.connect()` has two important parameters:
   102  
   103    * **connectionProfile**: the file system location of a
   104      [connection profile](./connectionprofile.html) that identifies
   105      a set of peers as a gateway to PaperNet
   106  
   107    * **connectionOptions**: a set of options used to control how `issue.js`
   108      interacts with PaperNet
   109  
   110  
   111  See how the client application uses a gateway to insulate itself from the
   112  network topology, which might change. The gateway takes care of sending the
   113  transaction proposal to the right peer nodes in the network using the
   114  [connection profile](./connectionprofile.html) and [connection
   115  options](./connectionoptions.html).
   116  
   117  Spend a few moments examining the connection
   118  [profile](https://github.com/hyperledger/fabric-samples/blob/{BRANCH}/commercial-paper/organization/magnetocorp/gateway/networkConnection.yaml)
   119  `./gateway/connectionProfile.yaml`. It uses
   120  [YAML](http://yaml.org/spec/1.2/spec.html#Preview), making it easy to read.
   121  
   122  It was loaded and converted into a JSON object:
   123  
   124  ```JavaScript
   125  let connectionProfile = yaml.safeLoad(file.readFileSync('./gateway/connectionProfile.yaml', 'utf8'));
   126  ```
   127  
   128  Right now, we're only interested in the `channels:` and `peers:` sections of the
   129  profile: (We've modified the details slightly to better explain what's
   130  happening.)
   131  
   132  ```YAML
   133  channels:
   134    papernet:
   135      peers:
   136        peer1.magnetocorp.com:
   137          endorsingPeer: true
   138          eventSource: true
   139  
   140        peer2.digibank.com:
   141          endorsingPeer: true
   142          eventSource: true
   143  
   144  peers:
   145    peer1.magnetocorp.com:
   146      url: grpcs://localhost:7051
   147      grpcOptions:
   148        ssl-target-name-override: peer1.magnetocorp.com
   149        request-timeout: 120
   150      tlsCACerts:
   151        path: certificates/magnetocorp/magnetocorp.com-cert.pem
   152  
   153    peer2.digibank.com:
   154      url: grpcs://localhost:8051
   155      grpcOptions:
   156        ssl-target-name-override: peer1.digibank.com
   157      tlsCACerts:
   158        path: certificates/digibank/digibank.com-cert.pem
   159  ```
   160  
   161  See how `channel:` identifies the `PaperNet:` network channel, and two of its
   162  peers. MagnetoCorp has `peer1.magenetocorp.com` and DigiBank has
   163  `peer2.digibank.com`, and both have the role of endorsing peers. Link to these
   164  peers via the `peers:` key, which contains details about how to connect to them,
   165  including their respective network addresses.
   166  
   167  The connection profile contains a lot of information -- not just peers -- but
   168  network channels, network orderers, organizations, and CAs, so don't worry if
   169  you don't understand all of it!
   170  
   171  Let's now turn our attention to the `connectionOptions` object:
   172  
   173  ```JavaScript
   174  let connectionOptions = {
   175      identity: userName,
   176      wallet: wallet,
   177      discovery: { enabled:true, asLocalhost: true }
   178  };
   179  ```
   180  
   181  See how it specifies that identity, `userName`, and wallet, `wallet`, should be
   182  used to connect to a gateway. These were assigned values earlier in the code.
   183  
   184  There are other [connection options](./connectionoptions.html) which an
   185  application could use to instruct the SDK to act intelligently on its behalf.
   186  For example:
   187  
   188  ```JavaScript
   189  let connectionOptions = {
   190    identity: userName,
   191    wallet: wallet,
   192    eventHandlerOptions: {
   193      commitTimeout: 100,
   194      strategy: EventStrategies.MSPID_SCOPE_ANYFORTX
   195    },
   196  }
   197  ```
   198  
   199  Here, `commitTimeout` tells the SDK to wait 100 seconds to hear whether a
   200  transaction has been committed. And `strategy:
   201  EventStrategies.MSPID_SCOPE_ANYFORTX` specifies that the SDK can notify an
   202  application after a single MagnetoCorp peer has confirmed the transaction, in
   203  contrast to `strategy: EventStrategies.NETWORK_SCOPE_ALLFORTX` which requires
   204  that all peers from MagnetoCorp and DigiBank to confirm the transaction.
   205  
   206  If you'd like to, [read more](./connectionoptions.html) about how connection
   207  options allow applications to specify goal-oriented behaviour without having to
   208  worry about how it is achieved.
   209  
   210  ## Network channel
   211  
   212  The peers defined in the gateway `connectionProfile.yaml` provide
   213  `issue.js` with access to PaperNet. Because these peers can be joined to
   214  multiple network channels, the gateway actually provides the application with
   215  access to multiple network channels!
   216  
   217  See how the application selects a particular channel:
   218  
   219  ```JavaScript
   220  const network = await gateway.getNetwork('PaperNet');
   221  ```
   222  
   223  From this point onwards, `network` will provide access to PaperNet.  Moreover,
   224  if the application wanted to access another network, `BondNet`, at the same
   225  time, it is easy:
   226  
   227  ```JavaScript
   228  const network2 = await gateway.getNetwork('BondNet');
   229  ```
   230  
   231  Now our application has access to a second network, `BondNet`, simultaneously
   232  with `PaperNet`!
   233  
   234  We can see here a powerful feature of Hyperledger Fabric -- applications can
   235  participate in a **network of networks**, by connecting to multiple gateway
   236  peers, each of which is joined to multiple network channels. Applications will
   237  have different rights in different channels according to their wallet identity
   238  provided in `gateway.connect()`.
   239  
   240  ## Construct request
   241  
   242  The application is now ready to **issue** a commercial paper.  To do this, it's
   243  going to use `CommercialPaperContract` and again, its fairly straightforward to
   244  access this smart contract:
   245  
   246  ```JavaScript
   247  const contract = await network.getContract('papercontract', 'org.papernet.commercialpaper');
   248  ```
   249  
   250  Note how the application provides a name -- `papercontract` -- and an explicit
   251  contract name: `org.papernet.commercialpaper`! We see how a [contract
   252  name](./contractname.html) picks out one contract from the `papercontract.js`
   253  chaincode file that contains many contracts. In PaperNet, `papercontract.js` was
   254  installed and deployed to the channel with the name `papercontract`, and if you're
   255  interested, read [how](../chaincode_lifecycle.html) to deploy a chaincode containing
   256  multiple smart contracts.
   257  
   258  If our application simultaneously required access to another contract in
   259  PaperNet or BondNet this would be easy:
   260  
   261  ```JavaScript
   262  const euroContract = await network.getContract('EuroCommercialPaperContract');
   263  
   264  const bondContract = await network2.getContract('BondContract');
   265  ```
   266  
   267  In these examples, note how we didn't use a qualifying contract name -- we have
   268  only one smart contract per file, and `getContract()` will use the first
   269  contract it finds.
   270  
   271  Recall the transaction MagnetoCorp uses to issue its first commercial paper:
   272  
   273  ```
   274  Txn = issue
   275  Issuer = MagnetoCorp
   276  Paper = 00001
   277  Issue time = 31 May 2020 09:00:00 EST
   278  Maturity date = 30 November 2020
   279  Face value = 5M USD
   280  ```
   281  
   282  Let's now submit this transaction to PaperNet!
   283  
   284  ## Submit transaction
   285  
   286  Submitting a transaction is a single method call to the SDK:
   287  
   288  ```JavaScript
   289  const issueResponse = await contract.submitTransaction('issue', 'MagnetoCorp', '00001', '2020-05-31', '2020-11-30', '5000000');
   290  ```
   291  
   292  See how the `submitTransaction()` parameters match those of the transaction
   293  request.  It's these values that will be passed to the `issue()` method in the
   294  smart contract, and used to create a new commercial paper.  Recall its
   295  signature:
   296  
   297  ```JavaScript
   298  async issue(ctx, issuer, paperNumber, issueDateTime, maturityDateTime, faceValue) {...}
   299  ```
   300  
   301  It might appear that a smart contract receives control shortly after the
   302  application issues `submitTransaction()`, but that's not the case. Under the
   303  covers, the SDK uses the `connectionOptions` and `connectionProfile` details to
   304  send the transaction proposal to the right peers in the network, where it can
   305  get the required endorsements. But the application doesn't need to worry about
   306  any of this -- it just issues `submitTransaction` and the SDK takes care of it
   307  all!
   308  
   309  Note that the `submitTransaction` API includes a process for listening for
   310  transaction commits. Listening for commits is required because without it,
   311  you will not know whether your transaction has successfully been orderered,
   312  validated, and committed to the ledger.
   313  
   314  Let's now turn our attention to how the application handles the response!
   315  
   316  ## Process response
   317  
   318  Recall from `papercontract.js` how the **issue** transaction returns a
   319  commercial paper response:
   320  
   321  ```JavaScript
   322  return paper.toBuffer();
   323  ```
   324  
   325  You'll notice a slight quirk -- the new `paper` needs to be converted to a
   326  buffer before it is returned to the application. Notice how `issue.js` uses the
   327  class method `CommercialPaper.fromBuffer()` to rehydrate the response buffer as
   328  a commercial paper:
   329  
   330  ```JavaScript
   331  let paper = CommercialPaper.fromBuffer(issueResponse);
   332  ```
   333  
   334  This allows `paper` to be used in a natural way in a descriptive completion
   335  message:
   336  
   337  ```JavaScript
   338  console.log(`${paper.issuer} commercial paper : ${paper.paperNumber} successfully issued for value ${paper.faceValue}`);
   339  ```
   340  
   341  See how the same `paper` class has been used in both the application and smart
   342  contract -- if you structure your code like this, it'll really help readability
   343  and reuse.
   344  
   345  As with the transaction proposal, it might appear that the application receives
   346  control soon after the smart contract completes, but that's not the case. Under
   347  the covers, the SDK manages the entire consensus process, and notifies the
   348  application when it is complete according to the `strategy` connectionOption. If
   349  you're interested in what the SDK does under the covers, read the detailed
   350  [transaction flow](../../txflow.html).
   351  
   352  That’s it! In this topic you’ve understood how to call a smart contract from a
   353  sample application by examining how MagnetoCorp's application issues a new
   354  commercial paper in PaperNet. Now examine the key ledger and smart contract data
   355  structures are designed by in the [architecture topic](./architecture.html) behind
   356  them.
   357  
   358  <!--- Licensed under Creative Commons Attribution 4.0 International License
   359  https://creativecommons.org/licenses/by/4.0/ -->