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/ -->