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