본문 바로가기

IT/블록체인

Hyperledger Fabric Tutorial(2) - Writing Your First Application

Writing Your First Application

http://hyperledger-fabric.readthedocs.io/en/latest/writefirstapp.html

Setting up your Dev Environment

cd ~/workspace/fabric-samples
cd fabcar
ls
docker rm -f $(docker ps -aq)
docker network prune

Install the clients & launch the network

unset HTTP_PROXY HTTPS_PROXY
npm install
./startFabric.sh
docker ps

Start by installing required packages run 'npm install'                                             Then run 'node enrollAdmin.js', then 'node registerUser'                                                                                                                                                The 'node invoke.js' will fail until it has been updated with valid arguments                       The 'node query.js' may be run at anytime once the user has been registered                                                                                                                             hyperledger@vm001:~/workspace/fabric-samples/fabcar$ docker ps                                      CONTAINER ID        IMAGE                                                                                                    COMMAND                  CREATED              STATUS              PORTS                                            NAMES                                                       a89ea642889f        dev-peer0.org1.example.com-fabcar-1.0-5c906e402ed29f20260ae42283216aa75549c571e2e380f3615826365d8269ba   "chaincode -peer.add…"   20 seconds ago       Up 19 seconds                                                        dev-peer0.org1.example.com-fabcar-1.0                       6ddf1d64c477        hyperledger/fabric-tools                                                                                 "/bin/bash"              56 seconds ago       Up 54 seconds                                                        cli                                                         4ebe2c26862a        hyperledger/fabric-peer                                                                                  "peer node start"        About a minute ago   Up About a minute   0.0.0.0:7051->7051/tcp, 0.0.0.0:7053->7053/tcp   peer0.org1.example.com                                      692dc32a8769        hyperledger/fabric-orderer                                                                               "orderer"                About a minute ago   Up About a minute   0.0.0.0:7050->7050/tcp                           orderer.example.com                                         ad0bde91d759        hyperledger/fabric-couchdb                                                                               "tini -- /docker-ent…"   About a minute ago   Up About a minute   4369/tcp, 9100/tcp, 0.0.0.0:5984->5984/tcp       couchdb                                                     0f2d8df11c4c        hyperledger/fabric-ca                                                                                    "sh -c 'fabric-ca-se…"   About a minute ago   Up About a minute   0.0.0.0:7054->7054/tcp                           ca.example.com                                              hyperledger@vm001:~/workspace/fabric-samples/fabcar$ exit                                                                                                                                               
03:08

Enrolling the Admin User

node enrollAdmin.js

Register and Enroll user1

node registerUser.js

Querying the Ledger

node query.js

  • query.js 수정
const request = {
  //targets : --- letting this default to the peers assigned to the channel
  chaincodeId: 'fabcar',
  fcn: 'queryCar',
  args: ['CAR4']
};

node query.js

User1 was successfully registered and enrolled and is ready to intreact with the fabric network     hyperledger@vm001:~/workspace/fabric-samples/fabcar$ ls hfc-key-store/                              58255b2483c88e04b5c22e5a24f25480f9cf6f3525da2079864d8e22b9907cd4-priv                               58255b2483c88e04b5c22e5a24f25480f9cf6f3525da2079864d8e22b9907cd4-pub                                admin                                                                                               c6d9ece148fad5268b598c998efab6d5acf00a1022db9dcfd4717575de74cd51-priv                               c6d9ece148fad5268b598c998efab6d5acf00a1022db9dcfd4717575de74cd51-pub                                user1                                                                                               hyperledger@vm001:~/workspace/fabric-samples/fabcar$ node query.js                                  Store path:/home/hyperledger/workspace/fabric-samples/fabcar/hfc-key-store                          Successfully loaded user1 from persistence                                                          Query has completed, checking results                                                               Response is  [{"Key":"CAR0", "Record":{"colour":"blue","make":"Toyota","model":"Prius","owner":"Tomoko"}},{"Key":"CAR1", "Record":{"colour":"red","make":"Ford","model":"Mustang","owner":"Brad"}},{"Key":"CAR2", "Record":{"colour":"green","make":"Hyundai","model":"Tucson","owner":"Jin Soo"}},{"Key":"CAR3", "Record":{"colour":"yellow","make":"Volkswagen","model":"Passat","owner":"Max"}},{"Key":"CAR4", "Record":{"colour":"black","make":"Tesla","model":"S","owner":"Adriana"}},{"Key":"CAR5", "Record":{"colour":"purple","make":"Peugeot","model":"205","owner":"Michel"}},{"Key":"CAR6", "Record":{"colour":"white","make":"Chery","model":"S22L","owner":"Aarav"}},{"Key":"CAR7", "Record":{"colour":"violet","make":"Fiat","model":"Punto","owner":"Pari"}},{"Key":"CAR8", "Record":{"colour":"indigo","make":"Tata","model":"Nano","owner":"Valeria"}},{"Key":"CAR9", "Record":{"colour":"brown","make":"Holden","model":"Barina","owner":"Shotaro"}}]                                                                hyperledger@vm001:~/workspace/fabric-samples/fabcar$ vi query.js                                    hyperledger@vm001:~/workspace/fabric-samples/fabcar$ node query.js                                  Store path:/home/hyperledger/workspace/fabric-samples/fabcar/hfc-key-store                          Successfully loaded user1 from persistence                                                          Query has completed, checking results                                                               Response is  {"colour":"black","make":"Tesla","model":"S","owner":"Adriana"}                        hyperledger@vm001:~/workspace/fabric-samples/fabcar$ exit                                                                                                                                               
01:20

Updating the Ledger

  • invoke.js 수정
var request = {
  //targets: let default to the peer assigned to the client
  chaincodeId: 'fabcar',
  fcn: 'createCar',
  args: ['CAR10', 'Chevy', 'Volt', 'Red', 'Nick'],
  chainId: 'mychannel',
  txId: tx_id
};

node invoke.js

  • query.js 수정
const request = {
  //targets : --- letting this default to the peers assigned to the channel
  chaincodeId: 'fabcar',
  fcn: 'queryCar',
  args: ['CAR10']
};

node query.js

  • invoke.js 수정
var request = {
  //targets: let default to the peer assigned to the client
  chaincodeId: 'fabcar',
  fcn: 'changeCarOwner',
  args: ['CAR10', 'Dave'],
  chainId: 'mychannel',
  txId: tx_id
};

node invoke.js

The transaction has been committed on peer localhost:7053                                           Send transaction promise and event listener promise have completed                                  Successfully sent transaction to the orderer.                                                       Successfully committed the change to the ledger by the peer                                         hyperledger@vm001:~/workspace/fabric-samples/fabcar$ vi query.js                                    hyperledger@vm001:~/workspace/fabric-samples/fabcar$ node query.js                                  Store path:/home/hyperledger/workspace/fabric-samples/fabcar/hfc-key-store                          Successfully loaded user1 from persistence                                                          Query has completed, checking results                                                               Response is  {"colour":"Red","make":"Chevy","model":"Volt","owner":"Nick"}                          hyperledger@vm001:~/workspace/fabric-samples/fabcar$                                                hyperledger@vm001:~/workspace/fabric-samples/fabcar$                                                hyperledger@vm001:~/workspace/fabric-samples/fabcar$ vi invoke.js                                   hyperledger@vm001:~/workspace/fabric-samples/fabcar$ node invoke.js                                 Store path:/home/hyperledger/workspace/fabric-samples/fabcar/hfc-key-store                          Successfully loaded user1 from persistence                                                          Assigning transaction_id:  83df8d6053ebe338006aeefd0c748f51c39f1836758b50e205733ced4e04f859         Transaction proposal was good                                                                       Successfully sent Proposal and received ProposalResponse: Status - 200, message - "OK"              The transaction has been committed on peer localhost:7053                                           Send transaction promise and event listener promise have completed                                  Successfully sent transaction to the orderer.                                                       Successfully committed the change to the ledger by the peer                                         hyperledger@vm001:~/workspace/fabric-samples/fabcar$ node query.js                                  Store path:/home/hyperledger/workspace/fabric-samples/fabcar/hfc-key-store                          Successfully loaded user1 from persistence                                                          Query has completed, checking results                                                               Response is  {"colour":"Red","make":"Chevy","model":"Volt","owner":"Dave"}                          hyperledger@vm001:~/workspace/fabric-samples/fabcar$ exit                                                                                                                                               
01:40

네트워크 삭제


Chaincode for Developers

http://hyperledger-fabric.readthedocs.io/en/latest/chaincode4ade.html

Clear previous network

docker rm -f $(docker ps -aq)
docker network prune

Simple Asset Chaincode

Choosing a Location for the Code

mkdir -p $GOPATH/src/sacc
cd $GOPATH/src/sacc
touch sacc.go

Pulling it All Together

package main

import (
    "fmt"

    "github.com/hyperledger/fabric/core/chaincode/shim"
    "github.com/hyperledger/fabric/protos/peer"
)

// SimpleAsset implements a simple chaincode to manage an asset
type SimpleAsset struct {
}

// Init is called during chaincode instantiation to initialize any
// data. Note that chaincode upgrade also calls this function to reset
// or to migrate data.
func (t *SimpleAsset) Init(stub shim.ChaincodeStubInterface) peer.Response {
    // Get the args from the transaction proposal
    args := stub.GetStringArgs()
    if len(args) != 2 {
            return shim.Error("Incorrect arguments. Expecting a key and a value")
    }

    // Set up any variables or assets here by calling stub.PutState()

    // We store the key and the value on the ledger
    err := stub.PutState(args[0], []byte(args[1]))
    if err != nil {
            return shim.Error(fmt.Sprintf("Failed to create asset: %s", args[0]))
    }
    return shim.Success(nil)
}

// Invoke is called per transaction on the chaincode. Each transaction is
// either a 'get' or a 'set' on the asset created by Init function. The Set
// method may create a new asset by specifying a new key-value pair.
func (t *SimpleAsset) Invoke(stub shim.ChaincodeStubInterface) peer.Response {
    // Extract the function and args from the transaction proposal
    fn, args := stub.GetFunctionAndParameters()

    var result string
    var err error
    if fn == "set" {
            result, err = set(stub, args)
    } else { // assume 'get' even if fn is nil
            result, err = get(stub, args)
    }
    if err != nil {
            return shim.Error(err.Error())
    }

    // Return the result as success payload
    return shim.Success([]byte(result))
}

// Set stores the asset (both key and value) on the ledger. If the key exists,
// it will override the value with the new one
func set(stub shim.ChaincodeStubInterface, args []string) (string, error) {
    if len(args) != 2 {
            return "", fmt.Errorf("Incorrect arguments. Expecting a key and a value")
    }

    err := stub.PutState(args[0], []byte(args[1]))
    if err != nil {
            return "", fmt.Errorf("Failed to set asset: %s", args[0])
    }
    return args[1], nil
}

// Get returns the value of the specified asset key
func get(stub shim.ChaincodeStubInterface, args []string) (string, error) {
    if len(args) != 1 {
            return "", fmt.Errorf("Incorrect arguments. Expecting a key")
    }

    value, err := stub.GetState(args[0])
    if err != nil {
            return "", fmt.Errorf("Failed to get asset: %s with error: %s", args[0], err)
    }
    if value == nil {
            return "", fmt.Errorf("Asset not found: %s", args[0])
    }
    return string(value), nil
}

// main function starts up the chaincode in the container during instantiate
func main() {
    if err := shim.Start(new(SimpleAsset)); err != nil {
            fmt.Printf("Error starting SimpleAsset chaincode: %s", err)
    }
}

Building Chaincode

go get -u --tags nopkcs11 github.com/hyperledger/fabric/core/chaincode/shim
go build --tags nopkcs11
ls -l

hyperledger@vm001:~$ docker rm -f $(docker ps -aq)                              8f61aaea4cab                                                                    09fbaebdb246                                                                    0af63086082d                                                                    3126b5044ada                                                                    70f8d47b1acf                                                                    b4fdc2483faa                                                                    hyperledger@vm001:~$ docker network prune                                       WARNING! This will remove all networks not used by at least one container.      Are you sure you want to continue? [y/N] y                                      Deleted Networks:                                                               net_basic                                                                                                                                                       hyperledger@vm001:~$ mkdir -p $GOPATH/src/sacc                                  hyperledger@vm001:~$ cd /home/hyperledger/go/src/sacc/                          hyperledger@vm001:~/go/src/sacc$ touch sacc.go                                  hyperledger@vm001:~/go/src/sacc$                                                hyperledger@vm001:~/go/src/sacc$ vi sacc.go                                     hyperledger@vm001:~/go/src/sacc$ go get -u --tags nopkcs11 github.com/hyperledgeode/shim/core/chainc                                                            hyperledger@vm001:~/go/src/sacc$ go build --tags nopkcs11                       hyperledger@vm001:~/go/src/sacc$ exit                                                                                                                                                                                                           
01:47

Testing Using dev mode

cd ~/workspace/fabric-samples
cd chaincode-docker-devmode

Terminal 1 - Start the network

docker-compose -f docker-compose-simple.yaml up

elID:myc                                                                        peer         | 2018-03-21 17:14:04.016 UTC [chaincode] Execute -> DEBU 600 Exit peer         | 2018-03-21 17:14:04.017 UTC [endorser] callChaincode -> DEBU 601 [myc][b744daa9] Exit                                                            peer         | 2018-03-21 17:14:04.017 UTC [endorser] endorseProposal -> DEBU 602 [myc][b744daa9] Exit                                                          peer         | 2018-03-21 17:14:04.017 UTC [lockbasedtxmgr] Done -> DEBU 603 Done with transaction simulation / query execution [b744daa99303998fa993be592a55a10fee5b641b1a1aa5a994a2bc74c551ed5e]                                              peer         | 2018-03-21 17:14:04.017 UTC [endorser] ProcessProposal -> DEBU 604 Exit: request from%!(EXTRA string=172.18.0.5:41662)                           peer         | 2018-03-21 17:14:12.671 UTC [chaincode] processStream -> ERRO 605 Error handling chaincode support stream: rpc error: code = Canceled desc = context canceled                                                                    peer         | 2018-03-21 17:14:12.671 UTC [chaincode] deregisterHandler -> DEBU 606 Deregister handler: mycc:0                                                 peer         | 2018-03-21 17:14:12.672 UTC [chaincode] deregisterHandler -> DEBU 607 Deregistered handler with key: mycc:0                                      ^CGracefully stopping... (press Ctrl+C again to force)                          Stopping chaincode ... done                                                     Stopping cli       ... done                                                     Stopping peer      ... done                                                     Stopping orderer   ... done                                                     hyperledger@vm001:~/workspace/fabric-samples/chaincode-docker-devmode$          
02:06

Terminal 2 - Build & start the chaincode

docker exec -it chaincode bash

cd sacc
go build
CORE_PEER_ADDRESS=peer:7052 CORE_CHAINCODE_ID_NAME=mycc:0 ./sacc

<ocker exec -it chaincode bash                                                                                                                                  <ocker exec -it chaincode bash                                                                                                                                  root@ef10c48eb1da:/opt/gopath/src/chaincode#                                    root@ef10c48eb1da:/opt/gopath/src/chaincode# cd sacc                            root@ef10c48eb1da:/opt/gopath/src/chaincode/sacc# go build                      root@ef10c48eb1da:/opt/gopath/src/chaincode/sacc# CORE_PEER_ADDRESS=peer:7052 CORE_CHAINCODE_ID_NAME=mycc:0 ./sacc                                              2018-03-21 17:13:32.622 UTC [shim] SetupChaincodeLogging -> INFO 001 Chaincode log level not provided; defaulting to: INFO                                      2018-03-21 17:13:32.622 UTC [shim] SetupChaincodeLogging -> INFO 002 Chaincode (build level: ) starting up ...                                                  ^C                                                                              root@ef10c48eb1da:/opt/gopath/src/chaincode/sacc# exit                          hyperledger@vm001:~/workspace/fabric-samples/chaincode-docker-devmode$                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
01:27

Terminal 3 - Use the chaincode

docker exec -it cli bash

peer chaincode install -p chaincodedev/chaincode/sacc -n mycc -v 0
peer chaincode instantiate -n mycc -v 0 -c '{"Args":["a","10"]}' -C myc
peer chaincode invoke -n mycc -c '{"Args":["set", "a", "20"]}' -C myc
peer chaincode query -n mycc -c '{"Args":["query","a"]}' -C myc

2018-03-21 17:13:58.623 UTC [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 063 Chaincode invoke successful. result: status:200 payload:"20"                      2018-03-21 17:13:58.624 UTC [main] main -> INFO 064 Exiting.....                root@56f8f1df8756:/opt/gopath/src/chaincodedev# peer chaincode query -n mycc -c '{"Args":["query","a"]}' -C myc                                                 2018-03-21 17:14:03.967 UTC [msp] GetLocalMSP -> DEBU 001 Returning existing local MSP                                                                          2018-03-21 17:14:03.967 UTC [msp] GetDefaultSigningIdentity -> DEBU 002 Obtaining default signing identity                                                      2018-03-21 17:14:03.968 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 003 Using default escc                                                               2018-03-21 17:14:03.968 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 004 Using default vscc                                                               2018-03-21 17:14:03.969 UTC [chaincodeCmd] getChaincodeSpec -> DEBU 005 java chaincode disabled                                                                 2018-03-21 17:14:03.970 UTC [msp/identity] Sign -> DEBU 006 Sign: plaintext: 0AC9070A6108031A0C08DBA5CAD50510...6D7963631A0A0A0571756572790A0161                2018-03-21 17:14:03.971 UTC [msp/identity] Sign -> DEBU 007 Sign: digest: AC79AD026CACD8C7654C5879C5A10182260604A3163EF4940DD42932B1066409                      Query Result: 20                                                                2018-03-21 17:14:04.020 UTC [main] main -> INFO 008 Exiting.....                root@56f8f1df8756:/opt/gopath/src/chaincodedev# exit                            hyperledger@vm001:~/workspace/fabric-samples/chaincode-docker-devmode$                                                                                          
00:39