github.com/kaituanwang/hyperledger@v2.0.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/master/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 { FileSystemWallet, 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/master/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 = new FileSystemWallet('../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/master/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  }
   178  ```
   179  
   180  See how it specifies that identity, `userName`, and wallet, `wallet`, should be
   181  used to connect to a gateway. These were assigned values earlier in the code.
   182  
   183  There are other [connection options](./connectionoptions.html) which an
   184  application could use to instruct the SDK to act intelligently on its behalf.
   185  For example:
   186  
   187  ```JavaScript
   188  let connectionOptions = {
   189    identity: userName,
   190    wallet: wallet,
   191    eventHandlerOptions: {
   192      commitTimeout: 100,
   193      strategy: EventStrategies.MSPID_SCOPE_ANYFORTX
   194    },
   195  }
   196  ```
   197  
   198  Here, `commitTimeout` tells the SDK to wait 100 seconds to hear whether a
   199  transaction has been committed. And `strategy:
   200  EventStrategies.MSPID_SCOPE_ANYFORTX` specifies that the SDK can notify an
   201  application after a single MagnetoCorp peer has confirmed the transaction, in
   202  contrast to `strategy: EventStrategies.NETWORK_SCOPE_ALLFORTX` which requires
   203  that all peers from MagnetoCorp and DigiBank to confirm the transaction.
   204  
   205  If you'd like to, [read more](./connectionoptions.html) about how connection
   206  options allow applications to specify goal-oriented behaviour without having to
   207  worry about how it is achieved.
   208  
   209  ## Network channel
   210  
   211  The peers defined in the gateway `connectionProfile.yaml` provide
   212  `issue.js` with access to PaperNet. Because these peers can be joined to
   213  multiple network channels, the gateway actually provides the application with
   214  access to multiple network channels!
   215  
   216  See how the application selects a particular channel:
   217  
   218  ```JavaScript
   219  const network = await gateway.getNetwork('PaperNet');
   220  ```
   221  
   222  From this point onwards, `network` will provide access to PaperNet.  Moreover,
   223  if the application wanted to access another network, `BondNet`, at the same
   224  time, it is easy:
   225  
   226  ```JavaScript
   227  const network2 = await gateway.getNetwork('BondNet');
   228  ```
   229  
   230  Now our application has access to a second network, `BondNet`, simultaneously
   231  with `PaperNet`!
   232  
   233  We can see here a powerful feature of Hyperledger Fabric -- applications can
   234  participate in a **network of networks**, by connecting to multiple gateway
   235  peers, each of which is joined to multiple network channels. Applications will
   236  have different rights in different channels according to their wallet identity
   237  provided in `gateway.connect()`.
   238  
   239  ## Construct request
   240  
   241  The application is now ready to **issue** a commercial paper.  To do this, it's
   242  going to use `CommercialPaperContract` and again, its fairly straightforward to
   243  access this smart contract:
   244  
   245  ```JavaScript
   246  const contract = await network.getContract('papercontract', 'org.papernet.commercialpaper');
   247  ```
   248  
   249  Note how the application provides a name -- `papercontract` -- and an explicit
   250  contract name: `org.papernet.commercialpaper`! We see how a [contract
   251  name](./contractname.html) picks out one contract from the `papercontract.js`
   252  chaincode file that contains many contracts. In PaperNet, `papercontract.js` was
   253  installed and deployed to the channel with the name `papercontract`, and if you're
   254  interested, read [how](../chaincode4noah.html) to deploy a chaincode containing
   255  multiple smart contracts.
   256  
   257  If our application simultaneously required access to another contract in
   258  PaperNet or BondNet this would be easy:
   259  
   260  ```JavaScript
   261  const euroContract = await network.getContract('EuroCommercialPaperContract');
   262  
   263  const bondContract = await network2.getContract('BondContract');
   264  ```
   265  
   266  In these examples, note how we didn't use a qualifying contract name -- we have
   267  only one smart contract per file, and `getContract()` will use the first
   268  contract it finds.
   269  
   270  Recall the transaction MagnetoCorp uses to issue its first commercial paper:
   271  
   272  ```
   273  Txn = issue
   274  Issuer = MagnetoCorp
   275  Paper = 00001
   276  Issue time = 31 May 2020 09:00:00 EST
   277  Maturity date = 30 November 2020
   278  Face value = 5M USD
   279  ```
   280  
   281  Let's now submit this transaction to PaperNet!
   282  
   283  ## Submit transaction
   284  
   285  Submitting a transaction is a single method call to the SDK:
   286  
   287  ```JavaScript
   288  const issueResponse = await contract.submitTransaction('issue', 'MagnetoCorp', '00001', '2020-05-31', '2020-11-30', '5000000');
   289  ```
   290  
   291  See how the `submitTransaction()` parameters match those of the transaction
   292  request.  It's these values that will be passed to the `issue()` method in the
   293  smart contract, and used to create a new commercial paper.  Recall its
   294  signature:
   295  
   296  ```JavaScript
   297  async issue(ctx, issuer, paperNumber, issueDateTime, maturityDateTime, faceValue) {...}
   298  ```
   299  
   300  It might appear that a smart contract receives control shortly after the
   301  application issues `submitTransaction()`, but that's not the case. Under the
   302  covers, the SDK uses the `connectionOptions` and `connectionProfile` details to
   303  send the transaction proposal to the right peers in the network, where it can
   304  get the required endorsements. But the application doesn't need to worry about
   305  any of this -- it just issues `submitTransaction` and the SDK takes care of it
   306  all!
   307  
   308  Note that the `submitTransaction` API includes a process for listening for
   309  transaction commits. Listening for commits is required because without it,
   310  you will not know whether your transaction has successfully been orderered,
   311  validated, and committed to the ledger.
   312  
   313  Let's now turn our attention to how the application handles the response!
   314  
   315  ## Process response
   316  
   317  Recall from `papercontract.js` how the **issue** transaction returns a
   318  commercial paper response:
   319  
   320  ```JavaScript
   321  return paper.toBuffer();
   322  ```
   323  
   324  You'll notice a slight quirk -- the new `paper` needs to be converted to a
   325  buffer before it is returned to the application. Notice how `issue.js` uses the
   326  class method `CommercialPaper.fromBuffer()` to rehydrate the response buffer as
   327  a commercial paper:
   328  
   329  ```JavaScript
   330  let paper = CommercialPaper.fromBuffer(issueResponse);
   331  ```
   332  
   333  This allows `paper` to be used in a natural way in a descriptive completion
   334  message:
   335  
   336  ```JavaScript
   337  console.log(`${paper.issuer} commercial paper : ${paper.paperNumber} successfully issued for value ${paper.faceValue}`);
   338  ```
   339  
   340  See how the same `paper` class has been used in both the application and smart
   341  contract -- if you structure your code like this, it'll really help readability
   342  and reuse.
   343  
   344  As with the transaction proposal, it might appear that the application receives
   345  control soon after the smart contract completes, but that's not the case. Under
   346  the covers, the SDK manages the entire consensus process, and notifies the
   347  application when it is complete according to the `strategy` connectionOption. If
   348  you're interested in what the SDK does under the covers, read the detailed
   349  [transaction flow](../../txflow.html).
   350  
   351  That’s it! In this topic you’ve understood how to call a smart contract from a
   352  sample application by examining how MagnetoCorp's application issues a new
   353  commercial paper in PaperNet. Now examine the key ledger and smart contract data
   354  structures are designed by in the [architecture topic](./architecture.html) behind
   355  them.
   356  
   357  <!--- Licensed under Creative Commons Attribution 4.0 International License
   358  https://creativecommons.org/licenses/by/4.0/ -->