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
Enrolling the Admin User
node enrollAdmin.js
Register and Enroll user1
node registerUser.js
Querying the Ledger
node 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
Updating the Ledger
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
const request = {
//targets : --- letting this default to the peers assigned to the channel
chaincodeId: 'fabcar',
fcn: 'queryCar',
args: ['CAR10']
};
node query.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
네트워크 삭제
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
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$
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$
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$