github.com/adnan-c/fabric_e2e_couchdb@v0.6.1-preview.0.20170228180935-21ce6b23cf91/docs/Setup/Chaincode-setup.md (about) 1 ## Writing, Building, and Running Chaincode in a Development Environment 2 3 Chaincode developers need a way to test and debug their chaincode without having to set up a complete peer network. By default, when you want to interact with chaincode, you need to first `Deploy` it using the CLI, REST API, gRPC API, or SDK. Upon receiving this request, the peer node would typically spin up a Docker container with the relevant chaincode. This can make things rather complicated for debugging chaincode under development, because of the turnaround time with the `launch chaincode - debug docker container - fix problem - launch chaincode - lather - rinse - repeat` cycle. As such, the fabric peer has a `--peer-chaincodedev` flag that can be passed on start-up to instruct the peer node not to deploy the chaincode as a Docker container. 4 5 The following instructions apply to _developing_ chaincode in Go or Java. They do not apply to running in a production environment. However, if _developing_ chaincode in Java, please see the [Java chaincode setup](https://github.com/hyperledger/fabric/blob/master/docs/Setup/JAVAChaincode.md) instructions first, to be sure your environment is properly configured. 6 7 **Note:** We have added support for [System chaincode](https://github.com/hyperledger/fabric/blob/master/docs/SystemChaincode-noop.md). 8 9 ## Choices 10 11 Once again, you have the choice of using one of the following approaches: 12 13 - [Option 1](#option-1-vagrant-development-environment) using the **Vagrant** [development environment](https://github.com/hyperledger/fabric/blob/master/docs/dev-setup/devenv.md) that is used for developing the fabric itself 14 - [Option 2](#option-2-docker-for-mac-or-windows) using Docker for Mac or Windows 15 - [Option 3](#option-3-docker-toolbox) using Docker toolbox 16 17 By using options *2* or *3*, above, you avoid having to build everything from scratch, and there's no need to keep a clone of the fabric GitHub repos current/up-to-date. Instead, you can simply pull and run the `fabric-peer` and `fabric-membersrvc` images directly from DockerHub. 18 19 You will need multiple terminal windows - essentially one for each component. One runs the validating peer; another runs the chaincode; the third runs the CLI or REST API commands to execute transactions. Finally, when running with security enabled, an additional fourth window is required to run the **Certificate Authority (CA)** server. Detailed instructions are provided in the sections below. 20 21 ## Option 1 Vagrant development environment 22 23 ### Security Setup (optional) 24 25 From the `devenv` subdirectory of your fabric workspace environment, `ssh` into Vagrant: 26 27 ``` 28 cd $GOPATH/src/github.com/hyperledger/fabric/devenv 29 vagrant ssh 30 ``` 31 32 To set up the local development environment with security enabled, you must first build and run the **Certificate Authority (CA)** server: 33 34 ``` 35 cd $GOPATH/src/github.com/hyperledger/fabric 36 make membersrvc && membersrvc 37 ``` 38 39 Running the above commands builds and runs the CA server with the default setup, which is defined in the [membersrvc.yaml](https://github.com/hyperledger/fabric/blob/master/membersrvc/membersrvc.yaml) configuration file. The default configuration includes multiple users who are already registered with the CA; these users are listed in the `eca.users` section of the configuration file. To register additional users with the CA for testing, modify the `eca.users` section of the [membersrvc.yaml](https://github.com/hyperledger/fabric/blob/master/membersrvc/membersrvc.yaml) file to include additional `enrollmentID` and `enrollmentPW` pairs. Note the integer that precedes the `enrollmentPW`. That integer indicates the role of the user, where 1 = client, 2 = non-validating peer, 4 = validating peer, and 8 = auditor. 40 41 ### Running the validating peer 42 43 In a **new** terminal window, from the `devenv` subdirectory of your fabric workspace environment, `ssh` into Vagrant: 44 45 ``` 46 cd $GOPATH/src/github.com/hyperledger/fabric/devenv 47 vagrant ssh 48 ``` 49 50 Build and run the peer process. 51 52 ``` 53 cd $GOPATH/src/github.com/hyperledger/fabric 54 make peer 55 peer node start --peer-chaincodedev 56 ``` 57 58 Alternatively, rather than tweaking the `core.yaml` and rebuilding, you can enable security and privacy on the peer with environment variables: 59 60 ``` 61 CORE_SECURITY_ENABLED=true CORE_SECURITY_PRIVACY=true peer node start --peer-chaincodedev 62 ``` 63 64 Now, you are ready to start [running the chaincode](#running-the-chaincode). 65 66 ## Option 2 Docker for Mac or Windows 67 68 If you would prefer to simply run the fabric components as built and published by the Hyperledger project on your Mac or Windows laptop/server using the Docker for [Mac](https://docs.docker.com/engine/installation/mac/) or [Windows](https://docs.docker.com/engine/installation/windows/) platform, following these steps. If using [Docker Toolbox](https://docs.docker.com/toolbox/overview/), please skip to [Option 3](#option-3-docker-toolbox), below. 69 70 ### Pull images from DockerHub 71 72 First, pull the latest images published by the Hyperledger fabric project from DockerHub. 73 74 ``` 75 docker pull hyperledger/fabric-peer:latest 76 docker pull hyperledger/fabric-membersrvc:latest 77 ``` 78 79 ### Running the Peer and CA 80 81 To run the fabric-peer and fabric-membersrvc images, we'll use [Docker Compose](https://docs.docker.com/compose/). It significantly simplifies things. To do that, we'll create a docker-compose.yml file with a description of the two services we'll be running. Here's the docker-compose.yml to launch the two processes: 82 83 ``` 84 membersrvc: 85 image: hyperledger/fabric-membersrvc 86 ports: 87 - "7054:7054" 88 command: membersrvc 89 vp0: 90 image: hyperledger/fabric-peer 91 ports: 92 - "7050:7050" 93 - "7051:7051" 94 - "7053:7053" 95 environment: 96 - CORE_PEER_ADDRESSAUTODETECT=true 97 - CORE_VM_ENDPOINT=unix:///var/run/docker.sock 98 - CORE_LOGGING_LEVEL=DEBUG 99 - CORE_PEER_ID=vp0 100 - CORE_PEER_PKI_ECA_PADDR=membersrvc:7054 101 - CORE_PEER_PKI_TCA_PADDR=membersrvc:7054 102 - CORE_PEER_PKI_TLSCA_PADDR=membersrvc:7054 103 - CORE_SECURITY_ENABLED=true 104 - CORE_SECURITY_ENROLLID=test_vp0 105 - CORE_SECURITY_ENROLLSECRET=MwYpmSRjupbT 106 links: 107 - membersrvc 108 command: sh -c "sleep 5; peer node start --peer-chaincodedev" 109 ``` 110 111 Save that in a directory with the name `docker-compose.yml`. Then, run `docker-compose up` to start the two processes. 112 113 Now, you are ready to start [running the chaincode](#running-the-chaincode). 114 115 ## Option 3 Docker Toolbox 116 117 If you are using [Docker Toolbox](https://docs.docker.com/toolbox/overview/), please follow these instructions. 118 119 ### Pull images from DockerHub 120 121 First, pull the latest images published by the Hyperledger fabric project from DockerHub. 122 123 ``` 124 docker pull hyperledger/fabric-peer:latest 125 docker pull hyperledger/fabric-membersrvc:latest 126 ``` 127 128 ### Running the Peer and CA 129 130 To run the fabric-peer and fabric-membersrvc images, we'll use [Docker Compose](https://docs.docker.com/compose/). It significantly simplifies things. To do that, we'll create a docker-compose.yml file with a description of the two services we'll be running. Here's the docker-compose.yml to launch the two processes: 131 132 ``` 133 membersrvc: 134 image: hyperledger/fabric-membersrvc 135 command: membersrvc 136 vp0: 137 image: hyperledger/fabric-peer 138 environment: 139 - CORE_PEER_ADDRESSAUTODETECT=true 140 - CORE_VM_ENDPOINT=http://172.17.0.1:2375 141 - CORE_LOGGING_LEVEL=DEBUG 142 - CORE_PEER_ID=vp0 143 - CORE_PEER_PKI_ECA_PADDR=membersrvc:7054 144 - CORE_PEER_PKI_TCA_PADDR=membersrvc:7054 145 - CORE_PEER_PKI_TLSCA_PADDR=membersrvc:7054 146 - CORE_SECURITY_ENABLED=true 147 - CORE_SECURITY_ENROLLID=test_vp0 148 - CORE_SECURITY_ENROLLSECRET=MwYpmSRjupbT 149 links: 150 - membersrvc 151 command: sh -c "sleep 5; peer node start --peer-chaincodedev" 152 ``` 153 Save that in a directory with the name `docker-compose.yml`. Then, run `docker-compose up` to start the two processes. 154 155 ## Running the chaincode 156 157 Start a **new** terminal window. 158 159 ### Vagrant 160 161 If you are using [Option 1](#option-1-vagrant-development-environment), you'll need to `ssh` to Vagrant. Otherwise, [skip](#not-vagrant) this step. 162 163 ``` 164 cd $GOPATH/src/github.com/hyperledger/fabric/devenv 165 vagrant ssh 166 ``` 167 168 Next, we'll build the **chaincode_example02** code, which is provided in the Hyperledger fabric source code repository. If you are using [Option 1](#option-1-vagrant-development-environment), then you can do this from your clone of the fabric repository. 169 170 ``` 171 cd $GOPATH/src/github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 172 go build 173 ``` 174 175 ### Not Vagrant 176 177 If you are using either [Option 2](#option-2-docker-for-mac-or-windows) or [Option 3](#option-3-docker-toolbox), you'll need to download the sample chaincode. The chaincode project must be placed somewhere under the `src` directory in your local `$GOPATH` as shown below. 178 179 ``` 180 mkdir -p $GOPATH/src/github.com/chaincode_example02/ 181 cd $GOPATH/src/github.com/chaincode_example02 182 curl --request GET https://raw.githubusercontent.com/hyperledger/fabric/master/examples/chaincode/go/chaincode_example02/chaincode_example02.go > chaincode_example02.go 183 ``` 184 185 Next, you'll need to clone the Hyperledger fabric to your local $GOPATH, so that you can build your chaincode. **Note:** this is a temporary stop-gap until we can provide an independent package for the chaincode shim. 186 187 ``` 188 mkdir -p $GOPATH/src/github.com/hyperledger 189 cd $GOPATH/src/github.com/hyperledger 190 git clone http://gerrit.hyperledger.org/r/fabric 191 ``` 192 193 Now, you should be able to build your chaincode. 194 195 ``` 196 cd $GOPATH/src/github.com/chaincode_example02 197 go build 198 ``` 199 200 When you are ready to start creating your own Go chaincode, create a new subdirectory under $GOPATH/src. You can copy the **chaincode_example02** file to the new directory and modify it. 201 202 ### Starting and registering the chaincode 203 204 Run the following chaincode command to start and register the chaincode with the validating peer: 205 206 ``` 207 CORE_CHAINCODE_ID_NAME=mycc CORE_PEER_ADDRESS=0.0.0.0:7051 ./chaincode_example02 208 ``` 209 210 The chaincode console will display the message "Received REGISTERED, ready for invocations", which indicates that the chaincode is ready to receive requests. Follow the steps below to send a chaincode deploy, invoke or query transaction. If the "Received REGISTERED" message is not displayed, then an error has occurred during the deployment; revisit the previous steps to resolve the issue. 211 212 ## Running the CLI or REST API 213 214 * [chaincode deploy via CLI and REST](#chaincode-deploy-via-cli-and-rest) 215 * [chaincode invoke via CLI and REST](#chaincode-invoke-via-cli-and-rest) 216 * [chaincode query via CLI and REST](#chaincode-query-via-cli-and-rest) 217 218 If you were running with security enabled, see [Removing temporary files when security is enabled](#removing-temporary-files-when-security-is-enabled) to learn how to clean up the temporary files. 219 220 See the [logging control](https://github.com/hyperledger/fabric/blob/master/docs/Setup/logging-control.md) reference for information on controlling 221 logging output from the `peer` and chaincodes. 222 223 ### Terminal 3 (CLI or REST API) 224 225 #### **Note on REST API port** 226 227 The default REST interface port is `7050`. It can be configured in [core.yaml](https://github.com/hyperledger/fabric/blob/master/peer/core.yaml) using the `rest.address` property. If using Vagrant, the REST port mapping is defined in [Vagrantfile](https://github.com/hyperledger/fabric/blob/master/devenv/Vagrantfile). 228 229 #### **Note on security functionality** 230 231 Current security implementation assumes that end user authentication takes place at the application layer and is not handled by the fabric. Authentication may be performed through any means considered appropriate for the target application. Upon successful user authentication, the application will perform user registration with the CA exactly once. If registration is attempted a second time for the same user, an error will result. During registration, the application sends a request to the certificate authority to verify the user registration and if successful, the CA responds with the user certificates and keys. The enrollment and transaction certificates received from the CA will be stored locally inside `/var/hyperledger/production/crypto/client/` directory. This directory resides on a specific peer node which allows the user to transact only through this specific peer while using the stored crypto material. If the end user needs to perform transactions through more then one peer node, the application is responsible for replicating the crypto material to other peer nodes. This is necessary as registering a given user with the CA a second time will fail. 232 233 With security enabled, the CLI commands and REST payloads must be modified to include the `enrollmentID` of a registered user who is logged in; otherwise an error will result. A registered user can be logged in through the CLI or the REST API by following the instructions below. To log in through the CLI, issue the following commands, where `username` is one of the `enrollmentID` values listed in the `eca.users` section of the [membersrvc.yaml](https://github.com/hyperledger/fabric/blob/master/membersrvc/membersrvc.yaml) file. 234 235 From your command line terminal, move to the `devenv` subdirectory of your workspace environment. Log into a Vagrant terminal by executing the following command: 236 237 ``` 238 vagrant ssh 239 ``` 240 241 Register the user though the CLI, substituting for `<username>` appropriately: 242 243 ``` 244 cd $GOPATH/src/github.com/hyperledger/fabric/peer 245 peer network login <username> 246 ``` 247 248 The command will prompt for a password, which must match the `enrollmentPW` listed for the target user in the `eca.users` section of the [membersrvc.yaml](https://github.com/hyperledger/fabric/blob/master/membersrvc/membersrvc.yaml) file. If the password entered does not match the `enrollmentPW`, an error will result. 249 250 To log in through the REST API, send a POST request to the `/registrar` endpoint, containing the `enrollmentID` and `enrollmentPW` listed in the `eca.users` section of the [membersrvc.yaml](https://github.com/hyperledger/fabric/blob/master/membersrvc/membersrvc.yaml) file. 251 252 **REST Request:** 253 254 ``` 255 POST localhost:7050/registrar 256 257 { 258 "enrollId": "jim", 259 "enrollSecret": "6avZQLwcUe9b" 260 } 261 ``` 262 263 **REST Response:** 264 265 ``` 266 200 OK 267 { 268 "OK": "Login successful for user 'jim'." 269 } 270 ``` 271 272 #### chaincode deploy via CLI and REST 273 274 First, send a chaincode deploy transaction, only once, to the validating peer. The CLI connects to the validating peer using the properties defined in the core.yaml file. **Note:** The deploy transaction typically requires a `path` parameter to locate, build, and deploy the chaincode. However, because these instructions are specific to local development mode and the chaincode is deployed manually, the `name` parameter is used instead. 275 ``` 276 peer chaincode deploy -n mycc -c '{"Args": ["init", "a","100", "b", "200"]}' 277 ``` 278 279 Alternatively, you can run the chaincode deploy transaction through the REST API. 280 281 **REST Request:** 282 283 ``` 284 POST <host:port>/chaincode 285 286 { 287 "jsonrpc": "2.0", 288 "method": "deploy", 289 "params": { 290 "type": 1, 291 "chaincodeID":{ 292 "name": "mycc" 293 }, 294 "input": { 295 "args":["init", "a", "100", "b", "200"] 296 } 297 }, 298 "id": 1 299 } 300 ``` 301 302 **REST Response:** 303 304 ``` 305 { 306 "jsonrpc": "2.0", 307 "result": { 308 "status": "OK", 309 "message": "mycc" 310 }, 311 "id": 1 312 } 313 ``` 314 315 **Note:** When security is enabled, modify the CLI command and the REST API payload to pass the `enrollmentID` of a logged in user. To log in a registered user through the CLI or the REST API, follow the instructions in the [note on security functionality](#note-on-security-functionality). On the CLI, the `enrollmentID` is passed with the `-u` parameter; in the REST API, the `enrollmentID` is passed with the `secureContext` element. If you are enabling security and privacy on the peer process with environment variables, it is important to include these environment variables in the command when executing all subsequent peer operations (e.g. deploy, invoke, or query). 316 317 CORE_SECURITY_ENABLED=true CORE_SECURITY_PRIVACY=true peer chaincode deploy -u jim -n mycc -c '{"Args": ["init", "a","100", "b", "200"]}' 318 319 **REST Request:** 320 321 ``` 322 POST <host:port>/chaincode 323 324 { 325 "jsonrpc": "2.0", 326 "method": "deploy", 327 "params": { 328 "type": 1, 329 "chaincodeID":{ 330 "name": "mycc" 331 }, 332 "input": { 333 "args":["init", "a", "100", "b", "200"] 334 }, 335 "secureContext": "jim" 336 }, 337 "id": 1 338 } 339 ``` 340 341 The deploy transaction initializes the chaincode by executing a target initializing function. Though the example shows "init", the name could be arbitrarily chosen by the chaincode developer. You should see the following output in the chaincode window: 342 ``` 343 <TIMESTAMP_SIGNATURE> Received INIT(uuid:005dea42-d57f-4983-803e-3232e551bf61), initializing chaincode 344 Aval = 100, Bval = 200 345 ``` 346 347 #### Chaincode invoke via CLI and REST 348 349 Run the chaincode invoking transaction on the CLI as many times as desired. The `-n` argument should match the value provided in the chaincode window (started in Vagrant terminal 2): 350 351 ``` 352 peer chaincode invoke -l golang -n mycc -c '{"Args": ["invoke", "a", "b", "10"]}' 353 ``` 354 355 Alternatively, run the chaincode invoking transaction through the REST API. 356 357 **REST Request:** 358 359 ``` 360 POST <host:port>/chaincode 361 362 { 363 "jsonrpc": "2.0", 364 "method": "invoke", 365 "params": { 366 "type": 1, 367 "chaincodeID":{ 368 "name":"mycc" 369 }, 370 "input": { 371 "args":["invoke", "a", "b", "10"] 372 } 373 }, 374 "id": 3 375 } 376 ``` 377 378 **REST Response:** 379 380 ``` 381 { 382 "jsonrpc": "2.0", 383 "result": { 384 "status": "OK", 385 "message": "5a4540e5-902b-422d-a6ab-e70ab36a2e6d" 386 }, 387 "id": 3 388 } 389 ``` 390 391 **Note:** When security is enabled, modify the CLI command and REST API payload to pass the `enrollmentID` of a logged in user. To log in a registered user through the CLI or the REST API, follow the instructions in the [note on security functionality](#note-on-security-functionality). On the CLI, the `enrollmentID` is passed with the `-u` parameter; in the REST API, the `enrollmentID` is passed with the `secureContext` element. If you are enabling security and privacy on the peer process with environment variables, it is important to include these environment variables in the command when executing all subsequent peer operations (e.g. deploy, invoke, or query). 392 393 CORE_SECURITY_ENABLED=true CORE_SECURITY_PRIVACY=true peer chaincode invoke -u jim -l golang -n mycc -c '{"Args": ["invoke", "a", "b", "10"]}' 394 395 **REST Request:** 396 397 ``` 398 POST <host:port>/chaincode 399 400 { 401 "jsonrpc": "2.0", 402 "method": "invoke", 403 "params": { 404 "type": 1, 405 "chaincodeID":{ 406 "name":"mycc" 407 }, 408 "input": { 409 "args":["invoke", "a", "b", "10"] 410 }, 411 "secureContext": "jim" 412 }, 413 "id": 3 414 } 415 ``` 416 417 The invoking transaction runs the specified chaincode function name "invoke" with the arguments. This transaction transfers 10 units from A to B. You should see the following output in the chaincode window: 418 419 ``` 420 <TIMESTAMP_SIGNATURE> Received RESPONSE. Payload 200, Uuid 075d72a4-4d1f-4a1d-a735-4f6f60d597a9 421 Aval = 90, Bval = 210 422 ``` 423 424 #### Chaincode query via CLI and REST 425 426 Run a query on the chaincode to retrieve the desired values. The `-n` argument should match the value provided in the chaincode window (started in Vagrant terminal 2): 427 428 ``` 429 peer chaincode query -l golang -n mycc -c '{"Args": ["query", "b"]}' 430 ``` 431 432 The response should be similar to the following: 433 434 ``` 435 {"Name":"b","Amount":"210"} 436 ``` 437 438 If a name other than "a" or "b" is provided in a query sent to `chaincode_example02`, you should see an error response similar to the following: 439 440 ``` 441 {"Error":"Nil amount for c"} 442 ``` 443 444 Alternatively, run the chaincode query transaction through the REST API. 445 446 **REST Request:** 447 ``` 448 POST <host:port>/chaincode 449 450 { 451 "jsonrpc": "2.0", 452 "method": "query", 453 "params": { 454 "type": 1, 455 "chaincodeID":{ 456 "name":"mycc" 457 }, 458 "input": { 459 "args":["query", "a"] 460 } 461 }, 462 "id": 5 463 } 464 ``` 465 466 **REST Response:** 467 ``` 468 { 469 "jsonrpc": "2.0", 470 "result": { 471 "status": "OK", 472 "message": "90" 473 }, 474 "id": 5 475 } 476 ``` 477 478 **Note:** When security is enabled, modify the CLI command and REST API payload to pass the `enrollmentID` of a logged in user. To log in a registered user through the CLI or the REST API, follow the instructions in the [note on security functionality](#note-on-security-functionality). On the CLI, the `enrollmentID` is passed with the `-u` parameter; in the REST API, the `enrollmentID` is passed with the `secureContext` element. If you are enabling security and privacy on the peer process with environment variables, it is important to include these environment variables in the command when executing all subsequent peer operations (e.g. deploy, invoke, or query). 479 480 ``` 481 CORE_SECURITY_ENABLED=true CORE_SECURITY_PRIVACY=true peer chaincode query -u jim -l golang -n mycc -c '{"Args": ["query", "b"]}' 482 ``` 483 484 **REST Request:** 485 ``` 486 POST <host:port>/chaincode 487 488 { 489 "jsonrpc": "2.0", 490 "method": "query", 491 "params": { 492 "type": 1, 493 "chaincodeID":{ 494 "name":"mycc" 495 }, 496 "input": { 497 "args":["query", "a"] 498 }, 499 "secureContext": "jim" 500 }, 501 "id": 5 502 } 503 ``` 504 505 #### Removing temporary files when security is enabled 506 507 **Note:** this step applies **ONLY** if you were using Option 1 above. For Option 2 or 3, the cleanup is handled by Docker. 508 509 After the completion of a chaincode test with security enabled, remove the temporary files that were created by the CA server process. To remove the client enrollment certificate, enrollment key, transaction certificate chain, etc., run the following commands. Note, that you must run these commands if you want to register a user who has already been registered previously. 510 511 From your command line terminal, `ssh` into Vagrant: 512 513 ``` 514 cd $GOPATH/src/github.com/hyperledger/fabric/devenv 515 vagrant ssh 516 ``` 517 518 And then run: 519 520 ``` 521 rm -rf /var/hyperledger/production 522 ```