github.com/true-sqn/fabric@v2.1.1+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 the test 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 roles 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 the network](#create-the-network) 30 * [Examine the commercial paper smart contract](#examine-the-commercial-paper-smart-contract) 31 * [Deploy the smart contract to the channel](#deploy-the-smart-contract-to-the-channel) 32 by approving the chaincode definition as MagnetoCorp and Digibank. 33 * Understand the structure of a MagnetoCorp [application](#application-structure), 34 including its [dependencies](#application-dependencies) 35 * Configure and use a [wallet and identities](#wallet) 36 * Run a MagnetoCorp application to [issue a commercial paper](#issue-application) 37 * Understand how DigiBank uses the smart contract in their [applications](#digibank-applications) 38 * As Digibank, run applications that 39 [buy](#buy-application) and [redeem](#redeem-application) commercial paper 40 41 This tutorial has been tested on MacOS and Ubuntu, and should work on other 42 Linux distributions. A Windows version is under development. 43 44 ## Prerequisites 45 46 Before you start, you must install some prerequisite technology required by the 47 tutorial. We've kept these to a minimum so that you can get going quickly. 48 49 You **must** have the following technologies installed: 50 51 * [**Node**](https://github.com/hyperledger/fabric-sdk-node#build-and-test) 52 The Node.js SDK README contains the up to date list of prerequisites. 53 54 You **will** find it helpful to install the following technologies: 55 56 * A source code editor, such as 57 [**Visual Studio Code**](https://code.visualstudio.com/) version 1.28, or 58 higher. VS Code will help you develop and test your application and smart 59 contract. Install VS Code [here](https://code.visualstudio.com/Download). 60 61 Many excellent code editors are available including 62 [Atom](https://atom.io/), [Sublime Text](http://www.sublimetext.com/) and 63 [Brackets](http://www.sublimetext.com/). 64 65 You **may** find it helpful to install the following technologies as you become 66 more experienced with application and smart contract development. There's no 67 requirement to install these when you first run the tutorial: 68 69 * [**Node Version Manager**](https://github.com/creationix/nvm). NVM helps you 70 easily switch between different versions of node -- it can be really helpful 71 if you're working on multiple projects at the same time. Install NVM 72 [here](https://github.com/creationix/nvm#installation). 73 74 ## Download samples 75 76 The commercial paper tutorial is one of the samples in the `fabric-samples` 77 directory. Before you begin this tutorial, ensure that you have followed the 78 instructions to install the Fabric [Prerequisites](../prereqs.html) and 79 [Download the Samples, Binaries and Docker Images](../install.html). 80 When you are finished, you will have cloned the `fabric-samples` repository that 81 contains the tutorial scripts, smart contract, and application files. 82 83 ![commercialpaper.download](./commercial_paper.diagram.2.png) *Download the 84 `fabric-samples` GitHub repository to your local machine.* 85 86 After downloading, feel free to examine the directory structure of `fabric-samples`: 87 88 ``` 89 $ cd fabric-samples 90 $ ls 91 92 CODEOWNERS basic-network first-network 93 CODE_OF_CONDUCT.md chaincode high-throughput 94 CONTRIBUTING.md chaincode-docker-devmode interest_rate_swaps 95 Jenkinsfile ci off_chain_data 96 LICENSE ci.properties scripts 97 MAINTAINERS.md commercial-paper test-network 98 README.md docs 99 SECURITY.md fabcar 100 ``` 101 102 Notice the `commercial-paper` directory -- that's where our sample is located! 103 104 You've now completed the first stage of the tutorial! As you proceed, you'll 105 open multiple command windows for different users and components. For example: 106 107 * To show peer, orderer and CA log output from your network. 108 * To approve the chaincode as an administrator from MagnetoCorp and as an 109 administrator from DigiBank. 110 * To run applications on behalf of Isabella and Balaji, who will use the smart 111 contract to trade commercial paper with each other. 112 113 We'll make it clear when you should run a command from particular command 114 window; for example: 115 116 ``` 117 (isabella)$ ls 118 ``` 119 120 indicates that you should run the `ls` command from Isabella's window. 121 122 ## Create the network 123 124 This tutorial will deploy a smart contract using the Fabric test network. 125 The test network consists of two peer organizations and an ordering organization. 126 The two peer organizations operate one peer each, while the ordering organization 127 operates a single node raft ordering service. We will also use the test network 128 to create a single channel named `mychannel` that both peer organizations will 129 be members of. 130 131 ![commercialpaper.network](./commercial_paper.diagram.testnet.png) 132 *The Fabric test network is comprised of two peer organizations, Org1 and Org2, 133 each with one peer and its ledger database, an ordering node. Each of these 134 components runs as a Docker container.* 135 136 The two peers, the peer [ledgers](../ledger/ledger.html#world-state-database-options), the 137 orderer and the CA each run in the their own Docker container. In production 138 environments, organizations typically use existing CAs that are shared with 139 other systems; they're not dedicated to the Fabric network. 140 141 The two organizations of the test network allow us to interact with a blockchain 142 ledger as two organizations that operate separate peers. In this tutorial, 143 we will operate Org1 of the test network as DigiBank and Org2 as MagnetoCorp. 144 145 You can start the test network and create the channel with a script provided in 146 the commercial paper directory. Change to the `commercial-paper` directory in 147 the `fabric-samples`: 148 ``` 149 cd fabric-samples/commercial-paper 150 ``` 151 Then use the script to start the test network: 152 ``` 153 ./network-starter.sh 154 ``` 155 If the command is successful, you will see the test network being created in your 156 logs. You can use the `docker ps` command to see the Fabric nodes running on your 157 local machine: 158 ``` 159 $ docker ps 160 161 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 162 321cc489b10f hyperledger/fabric-peer:latest "peer node start" 2 minutes ago Up 2 minutes 0.0.0.0:7051->7051/tcp peer0.org1.example.com 163 ad668671f95f hyperledger/fabric-peer:latest "peer node start" 2 minutes ago Up 2 minutes 7051/tcp, 0.0.0.0:9051->9051/tcp peer0.org2.example.com 164 caadbe4d8592 hyperledger/fabric-couchdb "tini -- /docker-ent…" 2 minutes ago Up 2 minutes 4369/tcp, 9100/tcp, 0.0.0.0:7984->5984/tcp couchdb1 165 ebabe52903b8 hyperledger/fabric-couchdb "tini -- /docker-ent…" 2 minutes ago Up 2 minutes 4369/tcp, 9100/tcp, 0.0.0.0:5984->5984/tcp couchdb0 166 7c72711c6e18 hyperledger/fabric-orderer:latest "orderer" 2 minutes ago Up 2 minutes 0.0.0.0:7050->7050/tcp orderer.example.com 167 ``` 168 169 See if you can map these containers to the nodes of the test network (you may 170 need to horizontally scroll to locate the information): 171 172 * The Org1 peer, `peer0.org1.example.com`, is running in container `321cc489b10f` 173 * The Org2 peer, `peer0.org2.example.com`, is running in container `ad668671f95f` 174 * The CouchDB database for the Org1 peer, `couchdb0`, is running in container `ebabe52903b8` 175 * The CouchDB database for the Org2 peer, `couchdb1`, is running in container `caadbe4d8592` 176 * The ordering node `orderer.example.com` is running in container `7c72711c6e18` 177 178 These containers all form a [Docker network](https://docs.docker.com/network/) 179 called `net_test`. You can view the network with the `docker network` command: 180 181 ``` 182 $ docker network inspect net_test 183 184 { 185 "Name": "net_test", 186 "Id": "b77b99d29e37677fac48b7ecd78383bdebf09ebdd6b00e87e3d9444252b1ce31", 187 "Created": "2020-01-30T23:04:39.6157465Z", 188 "Containers": { 189 "321cc489b10ff46554d0b215da307d38daf35b68bbea635ae0ae3176c3ae0945": { 190 "Name": "peer0.org1.example.com", 191 "IPv4Address": "192.168.224.5/20", 192 }, 193 "7c72711c6e18caf7bff4cf78c27efc9ef3b2359a749c926c8aba1beacfdb0211": { 194 "Name": "orderer.example.com", 195 "IPv4Address": "192.168.224.4/20", 196 }, 197 "ad668671f95f351f0119320198e1d1e19ebbb0d75766c6c8b9bb7bd36ba506af": { 198 "Name": "peer0.org2.example.com", 199 "IPv4Address": "192.168.224.6/20", 200 }, 201 "caadbe4d8592aa558fe14d07a424a9e04365620ede1143b6ce5902ce038c0851": { 202 "Name": "couchdb1", 203 "IPv4Address": "192.168.224.2/20", 204 }, 205 "ebabe52903b8597d016dbc0d0ca4373ef75162d3400efbe6416975abafd08a8f": { 206 "Name": "couchdb0", 207 "IPv4Address": "192.168.224.3/20", 208 } 209 }, 210 "Labels": {} 211 } 212 ] 213 214 ``` 215 See how the five containers use different IP addresses, while being part of a 216 single Docker network. (We've abbreviated the output for clarity.) 217 218 Because we are operating the test network as DigiBank and MagnetoCorp, 219 `peer0.org1.example.com` will belong to the DigiBank organization while 220 `peer0.org2.example.com` will be operated by MagnetoCorp. Now that the test 221 network is up and running, we can refer our network as PaperNet from this point 222 forward. 223 224 To recap: you've downloaded the Hyperledger Fabric samples repository from 225 GitHub and you've got the test network running on your local machine. Let's now 226 start to play the role of MagnetoCorp, who wish to trade commercial paper. 227 228 ## Monitor the network as MagnetoCorp 229 230 The commercial paper tutorial allows you to act as two organizations by 231 providing two separate folders for DigiBank and MagnetoCorp. The two folders 232 contain the smart contracts and application files for each organization. Because 233 the two organizations have different roles in the trading of the commercial paper, 234 the application files are different for each organization. Open a new window in 235 the `fabric-samples` repository and use the following command to change into 236 the MagnetoCorp directory: 237 ``` 238 cd commercial-paper/organization/magnetocorp 239 ``` 240 The first thing we are going to do as MagnetoCorp is monitor the components 241 of PaperNet. An administrator can view the aggregated output from a set 242 of Docker containers using the `logspout` [tool](https://github.com/gliderlabs/logspout#logspout). 243 The tool collects the different output streams into one place, making it easy 244 to see what's happening from a single window. This can be really helpful for 245 administrators when installing smart contracts or for developers when invoking 246 smart contracts, for example. 247 248 In the MagnetoCorp directory, run the following command to run the 249 `monitordocker.sh` script and start the `logspout` tool for the containers 250 associated with PaperNet running on `net_test`: 251 ``` 252 (magnetocorp admin)$ ./configuration/cli/monitordocker.sh net_test 253 ... 254 latest: Pulling from gliderlabs/logspout 255 4fe2ade4980c: Pull complete 256 decca452f519: Pull complete 257 (...) 258 Starting monitoring on all containers on the network net_test 259 b7f3586e5d0233de5a454df369b8eadab0613886fc9877529587345fc01a3582 260 ``` 261 262 Note that you can pass a port number to the above command if the default port in `monitordocker.sh` is already in use. 263 ``` 264 (magnetocorp admin)$ ./monitordocker.sh net_test <port_number> 265 ``` 266 267 This window will now show output from the Docker containers for the remainder of the 268 tutorial, so go ahead and open another command window. The next thing we will do is 269 examine the smart contract that MagnetoCorp will use to issue to the commercial 270 paper. 271 272 ## Examine the commercial paper smart contract 273 274 `issue`, `buy` and `redeem` are the three functions at the heart of the commercial 275 paper smart contract. It is used by applications to submit transactions which 276 correspondingly issue, buy and redeem commercial paper on the ledger. Our next 277 task is to examine this smart contract. 278 279 Open a new terminal in the `fabric-samples` directory and change into the 280 MagnetoCorp folder to act as the MagnetoCorp developer. 281 ``` 282 cd commercial-paper/organization/magnetocorp 283 ``` 284 You can then view the smart contract in the `contract` directory using your chosen 285 editor (VS Code in this tutorial): 286 ``` 287 (magnetocorp developer)$ code contract 288 ``` 289 290 In the `lib` directory of the folder, you'll see `papercontract.js` file -- this 291 contains the commercial paper smart contract! 292 293 ![commercialpaper.vscode1](./commercial_paper.vscode.papercontract.png) *An 294 example code editor displaying the commercial paper smart contract in `papercontract.js`* 295 296 `papercontract.js` is a JavaScript program designed to run in the Node.js 297 environment. Note the following key program lines: 298 299 * `const { Contract, Context } = require('fabric-contract-api');` 300 301 This statement brings into scope two key Hyperledger Fabric classes that will 302 be used extensively by the smart contract -- `Contract` and `Context`. You 303 can learn more about these classes in the 304 [`fabric-shim` JSDOCS](https://hyperledger.github.io/fabric-chaincode-node/). 305 306 307 * `class CommercialPaperContract extends Contract {` 308 309 This defines the smart contract class `CommercialPaperContract` based on the 310 built-in Fabric `Contract` class. The methods which implement the key 311 transactions to `issue`, `buy` and `redeem` commercial paper are defined 312 within this class. 313 314 315 * `async issue(ctx, issuer, paperNumber, issueDateTime, maturityDateTime...) {` 316 317 This method defines the commercial paper `issue` transaction for PaperNet. The 318 parameters that are passed to this method will be used to create the new 319 commercial paper. 320 321 Locate and examine the `buy` and `redeem` transactions within the smart 322 contract. 323 324 325 * `let paper = CommercialPaper.createInstance(issuer, paperNumber, issueDateTime...);` 326 327 Within the `issue` transaction, this statement creates a new commercial paper 328 in memory using the `CommercialPaper` class with the supplied transaction 329 inputs. Examine the `buy` and `redeem` transactions to see how they similarly 330 use this class. 331 332 333 * `await ctx.paperList.addPaper(paper);` 334 335 This statement adds the new commercial paper to the ledger using 336 `ctx.paperList`, an instance of a `PaperList` class that was created when the 337 smart contract context `CommercialPaperContext` was initialized. Again, 338 examine the `buy` and `redeem` methods to see how they use this class. 339 340 341 * `return paper;` 342 343 This statement returns a binary buffer as response from the `issue` 344 transaction for processing by the caller of the smart contract. 345 346 347 Feel free to examine other files in the `contract` directory to understand how 348 the smart contract works, and read in detail how `papercontract.js` is 349 designed in the smart contract [topic](../developapps/smartcontract.html). 350 351 ## Deploy the smart contract to the channel 352 353 Before `papercontract` can be invoked by applications, it must be installed onto 354 the appropriate peer nodes of the test network and then defined on the channel 355 using the [Fabric chaincode lifecycle](../chaincode_lifecycle.html#chaincode-lifecycle). The Fabric chaincode 356 lifecycle allows multiple organizations to agree to the parameters of a chaincode 357 before the chainocde is deployed to a channel. As a result, we need to install 358 and approve the chaincode as administrators of both MagnetoCorp and DigiBank. 359 360 ![commercialpaper.install](./commercial_paper.diagram.install.png) *A MagnetoCorp 361 administrator installs a copy of the `papercontract` onto a MagnetoCorp peer.* 362 363 Smart contracts are the focus of application development, and are contained 364 within a Hyperledger Fabric artifact called [chaincode](../chaincode.html). One 365 or more smart contracts can be defined within a single chaincode, and installing 366 a chaincode will allow them to be consumed by the different organizations in 367 PaperNet. It means that only administrators need to worry about chaincode; 368 everyone else can think in terms of smart contracts. 369 370 ### Install and approve the smart contract as MagnetoCorp 371 372 We will first install and approve the smart contract as the MagnetoCorp admin. Make 373 sure that you are operating from the `magnetocorp` folder, or navigate back to that 374 folder using the following command: 375 ``` 376 cd commercial-paper/organization/magnetocorp 377 ``` 378 379 A MagnetoCorp administrator can interact with PaperNet using the `peer` CLI. However, 380 the administrator needs to set certain environment variables in their command 381 window to use the correct set of `peer` binaries, send commands to the address 382 of the MagnetoCorp peer, and sign requests with the correct crypto material. 383 384 You can use a script provided by the sample to set the environment variables in 385 your command window. Run the following command in the `magnetocorp` directory: 386 ``` 387 source magnetocorp.sh 388 ``` 389 390 You will see the full list of environment variables printed in your window. We 391 can now use this command window to interact with PaperNet as the MagnetoCorp 392 administrator. 393 394 The first step is to install the `papercontract` smart contract. The smart 395 contract can be packaged into a chaincode using the 396 `peer lifecycle chaincode package` command. In the MagnetoCorp administrator's 397 command window, run the following command to create the chaincode package: 398 ``` 399 (magnetocorp admin)$ peer lifecycle chaincode package cp.tar.gz --lang node --path ./contract --label cp_0 400 ``` 401 The MagnetoCorp admin can now install the chaincode on the MagnetoCorp peer using 402 the `peer lifecycle chaincode install` command: 403 ``` 404 (magnetocorp admin)$ peer lifecycle chaincode install cp.tar.gz 405 ``` 406 If the command is successful, you will see messages similar to the following 407 printed in your terminal: 408 ``` 409 2020-01-30 18:32:33.762 EST [cli.lifecycle.chaincode] submitInstallProposal -> INFO 001 Installed remotely: response:<status:200 payload:"\nEcp_0:ffda93e26b183e231b7e9d5051e1ee7ca47fbf24f00a8376ec54120b1a2a335c\022\004cp_0" > 410 2020-01-30 18:32:33.762 EST [cli.lifecycle.chaincode] submitInstallProposal -> INFO 002 Chaincode code package identifier: cp_0:ffda93e26b183e231b7e9d5051e1ee7ca47fbf24f00a8376ec54120b1a2a335c 411 ``` 412 Because the MagnetoCorp admin has set `CORE_PEER_ADDRESS=localhost:9051` to 413 target its commands to `peer0.org2.example.com`, the `INFO 001 Installed remotely...` 414 indicates that `papercontract` has been successfully installed on this peer. 415 416 After we install the smart contract, we need to approve the chaincode definition 417 for `papercontract` as MagnetoCorp. The first step is to find the packageID of 418 the chaincode we installed on our peer. We can query the packageID using the 419 `peer lifecycle chaincode queryinstalled` command: 420 ``` 421 peer lifecycle chaincode queryinstalled 422 ``` 423 424 The command will return the same package identifier as the install command. You 425 should see output similar to the following: 426 ``` 427 Installed chaincodes on peer: 428 Package ID: cp_0:ffda93e26b183e231b7e9d5051e1ee7ca47fbf24f00a8376ec54120b1a2a335c, Label: cp_0 429 ``` 430 431 We will need the package ID in the next step, so we will save it as an environment 432 variable. The package ID may not be the same for all users, so you need to 433 complete this step using the package ID returned from your command window. 434 ``` 435 export PACKAGE_ID=cp_0:ffda93e26b183e231b7e9d5051e1ee7ca47fbf24f00a8376ec54120b1a2a335c 436 ``` 437 438 The admin can now approve the chaincode definition for MagnetoCorp using the 439 `peer lifecycle chaincode approveformyorg` command: 440 ``` 441 (magnetocorp admin)$ peer lifecycle chaincode approveformyorg --orderer localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name papercontract -v 0 --package-id $PACKAGE_ID --sequence 1 --tls --cafile $ORDERER_CA 442 ``` 443 444 One of the most important chaincode parameters that channel members need to 445 agree to using the chaincode definition is the chaincode [endorsement policy](../endorsement-policies.html). 446 The endorsement policy describes the set of organizations that must endorse 447 (execute and sign) a transaction before it can be determined to be valid. By 448 approving the `papercontract` chaincode without the ``--policy`` flag, the 449 MagnetoCorp admin agrees to using the default endorsement policy, which requires a 450 majority of organizations on the channel to endorse a transaction. All transactions, 451 whether valid or invalid, will be recorded on the [ledger blockchain](../ledger/ledger.html#blockchain), 452 but only valid transactions will update the [world state](../ledger/ledger.html#world-state). 453 454 ### Install and approve the smart contract as DigiBank 455 456 By default, the Fabric Chaincode lifecycle requires a majority of organizations 457 on the channel to successfully commit the chaincode definition to the channel. 458 This implies that we need to approve the `papernet` chaincode as both MagnetoCorp 459 and DigiBank to get the required majority of 2 out of 2. Open a new terminal 460 window in the `fabric-samples` and navigate to the older that contains the 461 DigiBank smart contract and application files: 462 ``` 463 (digibank admin)$ cd commercial-paper/organization/digibank/ 464 ``` 465 Use the script in the DigiBank folder to set the environment variables that will 466 allow you to act as the DigiBank admin: 467 ``` 468 source digibank.sh 469 ``` 470 471 We can now install and approve `papercontract` as the DigiBank. Run the following 472 command to package the chaincode: 473 ``` 474 (digibank admin)$ peer lifecycle chaincode package cp.tar.gz --lang node --path ./contract --label cp_0 475 ``` 476 The admin can now install the chaincode on the DigiBank peer: 477 ``` 478 (digibank admin)$ peer lifecycle chaincode install cp.tar.gz 479 ``` 480 We then need to query and save the packageID of the chaincode that was just 481 installed: 482 ``` 483 (digibank admin)$ peer lifecycle chaincode queryinstalled 484 ``` 485 Save the package ID as an environment variable. Complete this step using the 486 package ID returned from your console. 487 ``` 488 export PACKAGE_ID=cp_0:ffda93e26b183e231b7e9d5051e1ee7ca47fbf24f00a8376ec54120b1a2a335c 489 ``` 490 491 The Digibank admin can now approve the chaincode definition of `papercontract`: 492 ``` 493 (digibank admin)$ peer lifecycle chaincode approveformyorg --orderer localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name papercontract -v 0 --package-id $PACKAGE_ID --sequence 1 --tls --cafile $ORDERER_CA 494 ``` 495 496 ### Commit the chaincode definition to the channel 497 498 Now that DigiBank and MagnetoCorp have both approved the `papernet` chaincode, we 499 have the majority we need (2 out of 2) to commit the chaincode definition to the 500 channel. Once the chaincode is successfully defined on the channel, the 501 `CommercialPaper` smart contract inside the `papercontract` chaincode can be 502 invoked by client applications on the channel. Since either organization can 503 commit the chaincode to the channel, we will continue operating as the 504 DigiBank admin: 505 506 ![commercialpaper.commit](./commercial_paper.diagram.commit.png) *After the DigiBank administrator commits the definition of the `papercontract` chaincode to the channel, a new Docker chaincode container will be created to run `papercontract` on both PaperNet peers* 507 508 The DigiBank administrator uses the `peer lifecycle chaincode commit` command 509 to commit the chaincode definition of `papercontract` to `mychannel`: 510 ``` 511 (digibank admin)$ peer lifecycle chaincode commit -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --peerAddresses localhost:7051 --tlsRootCertFiles ${PEER0_ORG1_CA} --peerAddresses localhost:9051 --tlsRootCertFiles ${PEER0_ORG2_CA} --channelID mychannel --name papercontract -v 0 --sequence 1 --tls --cafile $ORDERER_CA --waitForEvent 512 ``` 513 The chaincode container will start after the chaincode definition has been 514 committed to the channel. You can use the `docker ps` command to see 515 `papercontract` container starting on both peers. 516 517 ``` 518 (digibank admin)$ docker ps 519 520 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 521 d4ba9dc9c55f dev-peer0.org1.example.com-cp_0-ebef35e7f1f25eea1dcc6fcad5019477cd7f434c6a5dcaf4e81744e282903535-05cf67c20543ee1c24cf7dfe74abce99785374db15b3bc1de2da372700c25608 "docker-entrypoint.s…" 30 seconds ago Up 28 seconds dev-peer0.org1.example.com-cp_0-ebef35e7f1f25eea1dcc6fcad5019477cd7f434c6a5dcaf4e81744e282903535 522 a944c0f8b6d6 dev-peer0.org2.example.com-cp_0-1487670371e56d107b5e980ce7f66172c89251ab21d484c7f988c02912ddeaec-1a147b6fd2a8bd2ae12db824fad8d08a811c30cc70bc5b6bc49a2cbebc2e71ee "docker-entrypoint.s…" 31 seconds ago Up 28 seconds dev-peer0.org2.example.com-cp_0-1487670371e56d107b5e980ce7f66172c89251ab21d484c7f988c02912ddeaec 523 ``` 524 525 Notice that the containers are named to indicate the peer that started it, and 526 the fact that it's running `papercontract` version `0`. 527 528 Now that we have deployed the `papercontract` chaincode to the channel, we can 529 use the MagnetoCorp application to issue the commercial paper. Let's take a 530 moment to examine the application structure. 531 532 ## Application structure 533 534 The smart contract contained in `papercontract` is called by MagnetoCorp's 535 application `issue.js`. Isabella uses this application to submit a transaction 536 to the ledger which issues commercial paper `00001`. Let's quickly examine how 537 the `issue` application works. 538 539 ![commercialpaper.application](./commercial_paper.diagram.8.png) *A gateway 540 allows an application to focus on transaction generation, submission and 541 response. It coordinates transaction proposal, ordering and notification 542 processing between the different network components.* 543 544 Because the `issue` application submits transactions on behalf of Isabella, it 545 starts by retrieving Isabella's X.509 certificate from her 546 [wallet](../developapps/wallet.html), which might be stored on the local file 547 system or a Hardware Security Module 548 [HSM](https://en.wikipedia.org/wiki/Hardware_security_module). The `issue` 549 application is then able to utilize the gateway to submit transactions on the 550 channel. The Hyperledger Fabric SDK provides a 551 [gateway](../developapps/gateway.html) abstraction so that applications can 552 focus on application logic while delegating network interaction to the 553 gateway. Gateways and wallets make it straightforward to write Hyperledger 554 Fabric applications. 555 556 So let's examine the `issue` application that Isabella is going to use. Open a 557 separate terminal window for her, and in `fabric-samples` locate the MagnetoCorp 558 `/application` folder: 559 560 ``` 561 (isabella)$ cd commercial-paper/organization/magnetocorp/application/ 562 (isabella)$ ls 563 564 addToWallet.js issue.js package.json 565 ``` 566 567 `addToWallet.js` is the program that Isabella is going to use to load her 568 identity into her wallet, and `issue.js` will use this identity to create 569 commercial paper `00001` on behalf of MagnetoCorp by invoking `papercontract`. 570 571 Change to the directory that contains MagnetoCorp's copy of the application 572 `issue.js`, and use your code editor to examine it: 573 574 ``` 575 (isabella)$ cd commercial-paper/organization/magnetocorp/application 576 (isabella)$ code issue.js 577 ``` 578 579 Examine this directory; it contains the issue application and all its 580 dependencies. 581 582 ![commercialpaper.vscode2](./commercial_paper.vscode.issue.png) *A code editor 583 displaying the contents of the commercial paper application directory.* 584 585 Note the following key program lines in `issue.js`: 586 587 * `const { Wallets, Gateway } = require('fabric-network');` 588 589 This statement brings two key Hyperledger Fabric SDK classes into scope -- 590 `Wallet` and `Gateway`. 591 592 593 * `const wallet = await Wallets.newFileSystemWallet('../identity/user/isabella/wallet');` 594 595 This statement identifies that the application will use `isabella` wallet when 596 it connects to the blockchain network channel. Because Isabella's X.509 certificate 597 is in the local file system, the application creates a new `FileSystemWallet`. The 598 application will select a particular identity within `isabella` wallet. 599 600 601 * `await gateway.connect(connectionProfile, connectionOptions);` 602 603 This line of code connects to the network using the gateway identified by 604 `connectionProfile`, using the identity referred to in `ConnectionOptions`. 605 606 See how `../gateway/networkConnection.yaml` and `User1@org1.example.com` are 607 used for these values respectively. 608 609 610 * `const network = await gateway.getNetwork('mychannel');` 611 612 This connects the application to the network channel `mychannel`, where the 613 `papercontract` was previously instantiated. 614 615 616 * `const contract = await network.getContract('papercontract');` 617 618 This statement gives the application access to the `papercontract` chaincode. 619 Once an application has issued getContract, it can submit to any smart contract 620 transaction implemented within the chaincode. 621 622 * `const issueResponse = await contract.submitTransaction('issue', 'MagnetoCorp', '00001', ...);` 623 624 This line of code submits the a transaction to the network using the `issue` 625 transaction defined within the smart contract. `MagnetoCorp`, `00001`... are 626 the values to be used by the `issue` transaction to create a new commercial 627 paper. 628 629 * `let paper = CommercialPaper.fromBuffer(issueResponse);` 630 631 This statement processes the response from the `issue` transaction. The 632 response needs to deserialized from a buffer into `paper`, a `CommercialPaper` 633 object which can interpreted correctly by the application. 634 635 636 Feel free to examine other files in the `/application` directory to understand 637 how `issue.js` works, and read in detail how it is implemented in the 638 application [topic](../developapps/application.html). 639 640 ## Application dependencies 641 642 The `issue.js` application is written in JavaScript and designed to run in the 643 Node.js environment that acts as a client to the PaperNet network. 644 As is common practice, MagnetoCorp's application is built on many 645 external node packages --- to improve quality and speed of development. Consider 646 how `issue.js` includes the `js-yaml` 647 [package](https://www.npmjs.com/package/js-yaml) to process the YAML gateway 648 connection profile, or the `fabric-network` 649 [package](https://www.npmjs.com/package/fabric-network) to access the `Gateway` 650 and `Wallet` classes: 651 652 ```JavaScript 653 const yaml = require('js-yaml'); 654 const { Wallets, Gateway } = require('fabric-network'); 655 ``` 656 657 These packages have to be downloaded from [npm](https://www.npmjs.com/) to the 658 local file system using the `npm install` command. By convention, packages must 659 be installed into an application-relative `/node_modules` directory for use at 660 runtime. 661 662 Examine the `package.json` file to see how `issue.js` identifies the packages to 663 download and their exact versions: 664 665 ```json 666 "dependencies": { 667 "fabric-network": "~1.4.0", 668 "fabric-client": "~1.4.0", 669 "js-yaml": "^3.12.0" 670 }, 671 ``` 672 673 **npm** versioning is very powerful; you can read more about it 674 [here](https://docs.npmjs.com/getting-started/semantic-versioning). 675 676 Let's install these packages with the `npm install` command -- this may take up 677 to a minute to complete: 678 679 ``` 680 (isabella)$ cd commercial-paper/organization/magnetocorp/application/ 681 (isabella)$ npm install 682 683 ( ) extract:lodash: sill extract ansi-styles@3.2.1 684 (...) 685 added 738 packages in 46.701s 686 ``` 687 688 See how this command has updated the directory: 689 690 ``` 691 (isabella)$ ls 692 693 addToWallet.js node_modules package.json 694 issue.js package-lock.json 695 ``` 696 697 Examine the `node_modules` directory to see the packages that have been 698 installed. There are lots, because `js-yaml` and `fabric-network` are themselves 699 built on other npm packages! Helpfully, the `package-lock.json` 700 [file](https://docs.npmjs.com/files/package-lock.json) identifies the exact 701 versions installed, which can prove invaluable if you want to exactly reproduce 702 environments; to test, diagnose problems or deliver proven applications for 703 example. 704 705 ## Wallet 706 707 Isabella is almost ready to run `issue.js` to issue MagnetoCorp commercial paper 708 `00001`; there's just one remaining task to perform! As `issue.js` acts on 709 behalf of Isabella, and therefore MagnetoCorp, it will use identity from her 710 [wallet](../developapps/wallet.html) that reflects these facts. We now need to 711 perform this one-time activity of adding appropriate X.509 credentials to her 712 wallet. 713 714 In Isabella's terminal window, run the `addToWallet.js` program to add identity 715 information to her wallet: 716 717 ``` 718 (isabella)$ node addToWallet.js 719 720 done 721 ``` 722 723 `addToWallet.js` is a simple file-copying program which you can examine at your 724 leisure. It moves an identity from the test network sample to Isabella's 725 wallet. Let's focus on the result of this program --- the contents of 726 the wallet which will be used to submit transactions to PaperNet: 727 728 ``` 729 (isabella)$ ls ../identity/user/isabella/wallet/ 730 731 isabella.id 732 ``` 733 734 Isabella can store multiple identities in her wallet, though in our example, she 735 only uses one. The `wallet` folder contains an `isabella.id` file that provides 736 the information that Isabella needs to connect to the network. Other identities 737 used by Isabella would have their own file. You can open this file to see the 738 identity information that `issue.js` will use on behalf of Isabella inside a JSON 739 file. The output has been formatted for clarity. 740 ``` 741 (isabella)$ cat ../identity/user/isabella/wallet/* 742 743 { 744 "credentials": { 745 "certificate": "-----BEGIN CERTIFICATE-----\nMIICKTCCAdCgAwIBAgIQWKwvLG+sqeO3LwwQK6avZDAKBggqhkjOPQQDAjBzMQsw\nCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy\nYW5jaXNjbzEZMBcGA1UEChMQb3JnMi5leGFtcGxlLmNvbTEcMBoGA1UEAxMTY2Eu\nb3JnMi5leGFtcGxlLmNvbTAeFw0yMDAyMDQxOTA5MDBaFw0zMDAyMDExOTA5MDBa\nMGwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1T\nYW4gRnJhbmNpc2NvMQ8wDQYDVQQLEwZjbGllbnQxHzAdBgNVBAMMFlVzZXIxQG9y\nZzIuZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAT4TnTblx0k\ngfqX+NN7F76Me33VTq3K2NUWZRreoJzq6bAuvdDR+iFvVPKXbdORnVvRSATcXsYl\nt20yU7n/53dbo00wSzAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADArBgNV\nHSMEJDAigCDOCdm4irsZFU3D6Hak4+84QRg1N43iwg8w1V6DRhgLyDAKBggqhkjO\nPQQDAgNHADBEAiBhzKix1KJcbUy9ey5ulWHRUMbqdVCNHe/mRtUdaJagIgIgYpbZ\nXf0CSiTXIWOJIsswN4Jp+ZxkJfFVmXndqKqz+VM=\n-----END CERTIFICATE-----\n", 746 "privateKey": "-----BEGIN PRIVATE KEY-----\nMIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQggs55vQg2oXi8gNi8\nNidE8Fy5zenohArDq3FGJD8cKU2hRANCAAT4TnTblx0kgfqX+NN7F76Me33VTq3K\n2NUWZRreoJzq6bAuvdDR+iFvVPKXbdORnVvRSATcXsYlt20yU7n/53db\n-----END PRIVATE KEY-----\n" 747 }, 748 "mspId": "Org2MSP", 749 "type": "X.509", 750 "version": 1 751 } 752 ``` 753 754 In the file you can notice the following: 755 756 * a `"privateKey":` used to sign transactions on Isabella's behalf, but not 757 distributed outside of her immediate control. 758 759 * a `"certificate":` which contains Isabella's public key and other X.509 760 attributes added by the Certificate Authority at certificate creation. This 761 certificate is distributed to the network so that different actors at different 762 times can cryptographically verify information created by Isabella's private key. 763 764 You can Learn more about certificates [here](../identity/identity.html#digital-certificates). In practice, the 765 certificate file also contains some Fabric-specific metadata such as 766 Isabella's organization and role -- read more in the [wallet](../developapps/wallet.html) topic. 767 768 ## Issue application 769 770 Isabella can now use `issue.js` to submit a transaction that will issue 771 MagnetoCorp commercial paper `00001`: 772 773 ``` 774 (isabella)$ node issue.js 775 776 Connect to Fabric gateway. 777 Use network channel: mychannel. 778 Use org.papernet.commercialpaper smart contract. 779 Submit commercial paper issue transaction. 780 Process issue transaction response.{"class":"org.papernet.commercialpaper","key":"\"MagnetoCorp\":\"00001\"","currentState":1,"issuer":"MagnetoCorp","paperNumber":"00001","issueDateTime":"2020-05-31","maturityDateTime":"2020-11-30","faceValue":"5000000","owner":"MagnetoCorp"} 781 MagnetoCorp commercial paper : 00001 successfully issued for value 5000000 782 Transaction complete. 783 Disconnect from Fabric gateway. 784 Issue program complete. 785 ``` 786 787 The `node` command initializes a Node.js environment, and runs `issue.js`. We 788 can see from the program output that MagnetoCorp commercial paper 00001 was 789 issued with a face value of 5M USD. 790 791 As you've seen, to achieve this, the application invokes the `issue` transaction 792 defined in the `CommercialPaper` smart contract within `papercontract.js`. This 793 had been installed and instantiated in the network by the MagnetoCorp 794 administrator. It's the smart contract which interacts with the ledger via the 795 Fabric APIs, most notably `putState()` and `getState()`, to represent the new 796 commercial paper as a vector state within the world state. We'll see how this 797 vector state is subsequently manipulated by the `buy` and `redeem` transactions 798 also defined within the smart contract. 799 800 All the time, the underlying Fabric SDK handles the transaction endorsement, 801 ordering and notification process, making the application's logic 802 straightforward; the SDK uses a [gateway](../developapps/gateway.html) to 803 abstract away network details and 804 [connectionOptions](../developapps/connectoptions.html) to declare more advanced 805 processing strategies such as transaction retry. 806 807 Let's now follow the lifecycle of MagnetoCorp 00001 by switching our emphasis 808 to an employee of DigiBank, Balaji, who will buy the commercial paper using a 809 DigiBank application. 810 811 ## Digibank applications 812 813 Balaji uses DigiBank's `buy` application to submit a transaction to the ledger 814 which transfers ownership of commercial paper `00001` from MagnetoCorp to 815 DigiBank. The `CommercialPaper` smart contract is the same as that used by 816 MagnetoCorp's application, however the transaction is different this time -- 817 it's `buy` rather than `issue`. Let's examine how DigiBank's application works. 818 819 Open a separate terminal window for Balaji. In `fabric-samples`, change to the 820 DigiBank application directory that contains the application, `buy.js`, and open 821 it with your editor: 822 823 ``` 824 (balaji)$ cd commercial-paper/organization/digibank/application/ 825 (balaji)$ code buy.js 826 ``` 827 828 As you can see, this directory contains both the `buy` and `redeem` applications 829 that will be used by Balaji. 830 831 832 ![commercialpaper.vscode3](./commercial_paper.diagram.12.png) *DigiBank's 833 commercial paper directory containing the `buy.js` and `redeem.js` 834 applications.* 835 836 DigiBank's `buy.js` application is very similar in structure to MagnetoCorp's 837 `issue.js` with two important differences: 838 839 840 * **Identity**: the user is a DigiBank user `Balaji` rather than MagnetoCorp's 841 `Isabella` 842 843 ```JavaScript 844 const wallet = await Wallets.newFileSystemWallet('../identity/user/balaji/wallet'); 845 ``` 846 847 See how the application uses the `balaji` wallet when it connects to the 848 PaperNet network channel. `buy.js` selects a particular identity within 849 `balaji` wallet. 850 851 852 * **Transaction**: the invoked transaction is `buy` rather than `issue` 853 854 ```JavaScript 855 const buyResponse = await contract.submitTransaction('buy', 'MagnetoCorp', '00001', ...); 856 ``` 857 858 A `buy` transaction is submitted with the values `MagnetoCorp`, `00001`, ..., 859 that are used by the `CommercialPaper` smart contract class to transfer 860 ownership of commercial paper `00001` to DigiBank. 861 862 Feel free to examine other files in the `application` directory to understand 863 how the application works, and read in detail how `buy.js` is implemented in 864 the application [topic](../developapps/application.html). 865 866 ## Run as DigiBank 867 868 The DigiBank applications which buy and redeem commercial paper have a very 869 similar structure to MagnetoCorp's issue application. Therefore, let’s install 870 their dependencies and set up Balaji's wallet so that he can use these 871 applications to buy and redeem commercial paper. 872 873 Like MagnetoCorp, Digibank must the install the required application packages 874 using the ``npm install`` command, and again, this make take a short time to 875 complete. 876 877 In the DigiBank administrator window, install the application dependencies: 878 879 ``` 880 (digibank admin)$ cd commercial-paper/organization/digibank/application/ 881 (digibank admin)$ npm install 882 883 ( ) extract:lodash: sill extract ansi-styles@3.2.1 884 (...) 885 added 738 packages in 46.701s 886 ``` 887 888 In Balaji's command window, run the `addToWallet.js` program to add the identity 889 to his wallet: 890 891 ``` 892 (balaji)$ node addToWallet.js 893 894 done 895 ``` 896 897 The `addToWallet.js` program has added identity information for `balaji`, to his 898 wallet, which will be used by `buy.js` and `redeem.js` to submit transactions to 899 `PaperNet`. 900 901 Like Isabella, Balaji can store multiple identities in his wallet, though in our 902 example, he only uses one. His corresponding id file at 903 `digibank/identity/user/balaji/wallet/balaji.id` is very similar Isabella's --- 904 feel free to examine it. 905 906 ## Buy application 907 908 Balaji can now use `buy.js` to submit a transaction that will transfer ownership 909 of MagnetoCorp commercial paper 00001 to DigiBank. 910 911 Run the `buy` application in Balaji's window: 912 913 ``` 914 (balaji)$ node buy.js 915 916 Connect to Fabric gateway. 917 Use network channel: mychannel. 918 Use org.papernet.commercialpaper smart contract. 919 Submit commercial paper buy transaction. 920 Process buy transaction response. 921 MagnetoCorp commercial paper : 00001 successfully purchased by DigiBank 922 Transaction complete. 923 Disconnect from Fabric gateway. 924 Buy program complete. 925 ``` 926 927 You can see the program output that MagnetoCorp commercial paper 00001 was 928 successfully purchased by Balaji on behalf of DigiBank. `buy.js` invoked the 929 `buy` transaction defined in the `CommercialPaper` smart contract which updated 930 commercial paper `00001` within the world state using the `putState()` and 931 `getState()` Fabric APIs. As you've seen, the application logic to buy and issue 932 commercial paper is very similar, as is the smart contract logic. 933 934 ## Redeem application 935 936 The final transaction in the lifecycle of commercial paper 00001 is for 937 DigiBank to redeem it with MagnetoCorp. Balaji uses `redeem.js` to submit a 938 transaction to perform the redeem logic within the smart contract. 939 940 Run the `redeem` transaction in Balaji's window: 941 942 ``` 943 (balaji)$ node redeem.js 944 945 Connect to Fabric gateway. 946 Use network channel: mychannel. 947 Use org.papernet.commercialpaper smart contract. 948 Submit commercial paper redeem transaction. 949 Process redeem transaction response. 950 MagnetoCorp commercial paper : 00001 successfully redeemed with MagnetoCorp 951 Transaction complete. 952 Disconnect from Fabric gateway. 953 Redeem program complete. 954 ``` 955 956 Again, see how the commercial paper 00001 was successfully redeemed when 957 `redeem.js` invoked the `redeem` transaction defined in `CommercialPaper`. 958 Again, it updated commercial paper `00001` within the world state to reflect 959 that the ownership returned to MagnetoCorp, the issuer of the paper. 960 961 ## Clean up 962 963 When you are finished using the Commercial Paper tutorial, you can use a script 964 to clean up your environment. Use a command window to navigate back to the root 965 directory of the commercial paper sample: 966 ``` 967 cd fabric-samples/commercial-paper 968 ``` 969 You can then bring down the network with the following command: 970 ``` 971 ./network-clean.sh 972 ``` 973 This command will bring down the peers, CouchDB containers, and ordering node of the network, in addition to the logspout tool. It will also remove the identities that we created for Isabella and Balaji. Note that all of the data on the ledger will be lost. If you want to go through the tutorial again, you will start from a clean initial state. 974 975 ## Further reading 976 977 To understand how applications and smart contracts shown in this tutorial work 978 in more detail, you'll find it helpful to read 979 [Developing Applications](../developapps/developing_applications.html). This 980 topic will give you a fuller explanation of the commercial paper scenario, the 981 PaperNet business network, its actors, and how the applications and smart 982 contracts they use work in detail. 983 984 Also feel free to use this sample to start creating your own applications and 985 smart contracts! 986 987 <!--- Licensed under Creative Commons Attribution 4.0 International License 988 https://creativecommons.org/licenses/by/4.0/ -->