#重启网络 # 1 解散网络并清理容器和映像 docker-compose -f ./artifacts/docker-compose.yaml down # 2 清理内存 rm -rf ./fabric-client-kv-org* # 3 重启网络 docker-compose -f ./artifacts/docker-compose.yaml up -d #安装NodeModules npm install #启动node服务器 PORT=4000 node app
# # Copyright IBM Corp. All Rights Reserved. # # SPDX-License-Identifier: Apache-2.0 # version: '2' services: ca.org1.example.com: image: hyperledger/fabric-ca environment: - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server - FABRIC_CA_SERVER_CA_NAME=ca-org1 - FABRIC_CA_SERVER_CA_CERTFILE=/etc/hyperledger/fabric-ca-server-config/ca.org1.example.com-cert.pem - FABRIC_CA_SERVER_CA_KEYFILE=/etc/hyperledger/fabric-ca-server-config/0e729224e8b3f31784c8a93c5b8ef6f4c1c91d9e6e577c45c33163609fe40011_sk - FABRIC_CA_SERVER_TLS_ENABLED=true - FABRIC_CA_SERVER_TLS_CERTFILE=/etc/hyperledger/fabric-ca-server-config/ca.org1.example.com-cert.pem - FABRIC_CA_SERVER_TLS_KEYFILE=/etc/hyperledger/fabric-ca-server-config/0e729224e8b3f31784c8a93c5b8ef6f4c1c91d9e6e577c45c33163609fe40011_sk ports: - "7054:7054" command: sh -c 'fabric-ca-server start -b admin:adminpw -d' volumes: - ./channel/crypto-config/peerOrganizations/org1.example.com/ca/:/etc/hyperledger/fabric-ca-server-config container_name: ca_peerOrg1 ca.org2.example.com: image: hyperledger/fabric-ca environment: - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server - FABRIC_CA_SERVER_CA_NAME=ca-org2 - FABRIC_CA_SERVER_CA_CERTFILE=/etc/hyperledger/fabric-ca-server-config/ca.org2.example.com-cert.pem - FABRIC_CA_SERVER_CA_KEYFILE=/etc/hyperledger/fabric-ca-server-config/a7d47efa46a6ba07730c850fed2c1375df27360d7227f48cdc2f80e505678005_sk - FABRIC_CA_SERVER_TLS_ENABLED=true - FABRIC_CA_SERVER_TLS_CERTFILE=/etc/hyperledger/fabric-ca-server-config/ca.org2.example.com-cert.pem - FABRIC_CA_SERVER_TLS_KEYFILE=/etc/hyperledger/fabric-ca-server-config/a7d47efa46a6ba07730c850fed2c1375df27360d7227f48cdc2f80e505678005_sk ports: - "8054:7054" command: sh -c 'fabric-ca-server start -b admin:adminpw -d' volumes: - ./channel/crypto-config/peerOrganizations/org2.example.com/ca/:/etc/hyperledger/fabric-ca-server-config container_name: ca_peerOrg2 orderer.example.com: container_name: orderer.example.com image: hyperledger/fabric-orderer environment: - ORDERER_GENERAL_LOGLEVEL=debug - ORDERER_GENERAL_LISTENADDRESS=0.0.0.0 - ORDERER_GENERAL_GENESISMETHOD=file - ORDERER_GENERAL_GENESISFILE=/etc/hyperledger/configtx/genesis.block - ORDERER_GENERAL_LOCALMSPID=OrdererMSP - ORDERER_GENERAL_LOCALMSPDIR=/etc/hyperledger/crypto/orderer/msp - ORDERER_GENERAL_TLS_ENABLED=true - ORDERER_GENERAL_TLS_PRIVATEKEY=/etc/hyperledger/crypto/orderer/tls/server.key - ORDERER_GENERAL_TLS_CERTIFICATE=/etc/hyperledger/crypto/orderer/tls/server.crt - ORDERER_GENERAL_TLS_ROOTCAS=[/etc/hyperledger/crypto/orderer/tls/ca.crt, /etc/hyperledger/crypto/peerOrg1/tls/ca.crt, /etc/hyperledger/crypto/peerOrg2/tls/ca.crt] working_dir: /opt/gopath/src/github.com/hyperledger/fabric/orderers command: orderer ports: - 7050:7050 volumes: - ./channel:/etc/hyperledger/configtx - ./channel/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/:/etc/hyperledger/crypto/orderer - ./channel/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/:/etc/hyperledger/crypto/peerOrg1 - ./channel/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/:/etc/hyperledger/crypto/peerOrg2 peer0.org1.example.com: container_name: peer0.org1.example.com extends: file: base.yaml service: peer-base environment: - CORE_PEER_ID=peer0.org1.example.com - CORE_PEER_LOCALMSPID=Org1MSP - CORE_PEER_ADDRESS=peer0.org1.example.com:7051 ports: - 7051:7051 - 7053:7053 volumes: - ./channel/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/:/etc/hyperledger/crypto/peer depends_on: - orderer.example.com peer1.org1.example.com: container_name: peer1.org1.example.com extends: file: base.yaml service: peer-base environment: - CORE_PEER_ID=peer1.org1.example.com - CORE_PEER_LOCALMSPID=Org1MSP - CORE_PEER_ADDRESS=peer1.org1.example.com:7051 ports: - 7056:7051 - 7058:7053 volumes: - ./channel/crypto-config/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/:/etc/hyperledger/crypto/peer depends_on: - orderer.example.com peer0.org2.example.com: container_name: peer0.org2.example.com extends: file: base.yaml service: peer-base environment: - CORE_PEER_ID=peer0.org2.example.com - CORE_PEER_LOCALMSPID=Org2MSP - CORE_PEER_ADDRESS=peer0.org2.example.com:7051 ports: - 8051:7051 - 8053:7053 volumes: - ./channel/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/:/etc/hyperledger/crypto/peer depends_on: - orderer.example.com peer1.org2.example.com: container_name: peer1.org2.example.com extends: file: base.yaml service: peer-base environment: - CORE_PEER_ID=peer1.org2.example.com - CORE_PEER_LOCALMSPID=Org2MSP - CORE_PEER_ADDRESS=peer1.org2.example.com:7051 ports: - 8056:7051 - 8058:7053 volumes: - ./channel/crypto-config/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/:/etc/hyperledger/crypto/peer depends_on: - orderer.example.com
starttime=$(date +%s) LANGUAGE="golang" ## 1 set chaincode path CC_SRC_PATH="github.com/example_cc/go" #golang,node则为CC_SRC_PATH="$PWD/artifacts/src/github.com/example_cc/node" ## 2 POST 请求在 Org1 上注册 ORG1_TOKEN=$(curl -s -X POST \ http://localhost:4000/users \ -H "content-type: application/x-www-form-urlencoded" \ -d 'username=Jim&orgName=Org1') ORG1_TOKEN=$(echo $ORG1_TOKEN | jq ".token" | sed "s/\"//g") # 3 POST 请求在 Org2 上注册 ORG2_TOKEN=$(curl -s -X POST \ http://localhost:4000/users \ -H "content-type: application/x-www-form-urlencoded" \ -d 'username=Barry&orgName=Org2') ORG2_TOKEN=$(echo $ORG2_TOKEN | jq ".token" | sed "s/\"//g") # 4 POST 请求创建通道 curl -s -X POST \ http://localhost:4000/channels \ -H "authorization: Bearer $ORG1_TOKEN" \ -H "content-type: application/json" \ -d '{ "channelName":"mychannel", "channelConfigPath":"../artifacts/channel/mychannel.tx" }' sleep 5 # 5 POST request Join channel on Org1 curl -s -X POST \ http://localhost:4000/channels/mychannel/peers \ -H "authorization: Bearer $ORG1_TOKEN" \ -H "content-type: application/json" \ -d '{ "peers": ["peer0.org1.example.com","peer1.org1.example.com"] }' # 6 POST request Join channel on Org2 curl -s -X POST \ http://localhost:4000/channels/mychannel/peers \ -H "authorization: Bearer $ORG2_TOKEN" \ -H "content-type: application/json" \ -d '{ "peers": ["peer0.org2.example.com","peer1.org2.example.com"] }' # 7 POST Install chaincode on Org1 curl -s -X POST \ http://localhost:4000/chaincodes \ -H "authorization: Bearer $ORG1_TOKEN" \ -H "content-type: application/json" \ -d "{ \"peers\": [\"peer0.org1.example.com\",\"peer1.org1.example.com\"], \"chaincodeName\":\"mycc\", \"chaincodePath\":\"$CC_SRC_PATH\", \"chaincodeType\": \"$LANGUAGE\", \"chaincodeVersion\":\"v0\" }" # 8 POST Install chaincode on Org2 curl -s -X POST \ http://localhost:4000/chaincodes \ -H "authorization: Bearer $ORG2_TOKEN" \ -H "content-type: application/json" \ -d "{ \"peers\": [\"peer0.org2.example.com\",\"peer1.org2.example.com\"], \"chaincodeName\":\"mycc\", \"chaincodePath\":\"$CC_SRC_PATH\", \"chaincodeType\": \"$LANGUAGE\", \"chaincodeVersion\":\"v0\" }" # 9 POST instantiate chaincode on peer1 of Org1" curl -s -X POST \ http://localhost:4000/channels/mychannel/chaincodes \ -H "authorization: Bearer $ORG1_TOKEN" \ -H "content-type: application/json" \ -d "{ \"chaincodeName\":\"mycc\", \"chaincodeVersion\":\"v0\", \"chaincodeType\": \"$LANGUAGE\", \"args\":[\"a\",\"100\",\"b\",\"200\"] }" # 10 "POST invoke chaincode on peers of Org1" TRX_ID=$(curl -s -X POST \ http://localhost:4000/channels/mychannel/chaincodes/mycc \ -H "authorization: Bearer $ORG1_TOKEN" \ -H "content-type: application/json" \ -d '{ "peers": ["peer0.org1.example.com","peer1.org1.example.com"], "fcn":"move", "args":["a","b","10"] }') echo "Transacton ID is $TRX_ID" echo "GET query chaincode on peer1 of Org1" echo curl -s -X GET \ "http://localhost:4000/channels/mychannel/chaincodes/mycc?peer=peer0.org1.example.com&fcn=query&args=%5B%22a%22%5D" \ -H "authorization: Bearer $ORG1_TOKEN" \ -H "content-type: application/json" echo "GET query Block by blockNumber" echo curl -s -X GET \ "http://localhost:4000/channels/mychannel/blocks/1?peer=peer0.org1.example.com" \ -H "authorization: Bearer $ORG1_TOKEN" \ -H "content-type: application/json" echo "GET query Transaction by TransactionID" echo curl -s -X GET http://localhost:4000/channels/mychannel/transactions/$TRX_ID?peer=peer0.org1.example.com \ -H "authorization: Bearer $ORG1_TOKEN" \ -H "content-type: application/json" ############################################################################ ### TODO: What to pass to fetch the Block information ############################################################################ #echo "GET query Block by Hash" #echo #hash=???? #curl -s -X GET \ # "http://localhost:4000/channels/mychannel/blocks?hash=$hash&peer=peer1" \ # -H "authorization: Bearer $ORG1_TOKEN" \ # -H "cache-control: no-cache" \ # -H "content-type: application/json" \ # -H "x-access-token: $ORG1_TOKEN" #echo #echo echo "GET query ChainInfo" echo curl -s -X GET \ "http://localhost:4000/channels/mychannel?peer=peer0.org1.example.com" \ -H "authorization: Bearer $ORG1_TOKEN" \ -H "content-type: application/json" echo echo echo "GET query Installed chaincodes" echo curl -s -X GET \ "http://localhost:4000/chaincodes?peer=peer0.org1.example.com" \ -H "authorization: Bearer $ORG1_TOKEN" \ -H "content-type: application/json" echo echo echo "GET query Instantiated chaincodes" echo curl -s -X GET \ "http://localhost:4000/channels/mychannel/chaincodes?peer=peer0.org1.example.com" \ -H "authorization: Bearer $ORG1_TOKEN" \ -H "content-type: application/json" echo echo echo "GET query Channels" echo curl -s -X GET \ "http://localhost:4000/channels?peer=peer0.org1.example.com" \ -H "authorization: Bearer $ORG1_TOKEN" \ -H "content-type: application/json" echo echo echo "Total execution time : $(($(date +%s)-starttime)) secs ..."
A sample Node.js app to demonstrate fabric-client & fabric-ca-client Node.js SDK APIs
cd fabric-samples/balance-transfer/
Once you have completed the above setup, you will have provisioned a local network with the following docker container configuration:
There are two options available for running the balance-transfer sample
对于这些选项中的每一个,您可以选择使用用 golang
或 node.js
编写的链代码运行。
docker-compose -f artifacts/docker-compose.yaml up
npm install
PORT=4000 node app
cd fabric-samples/balance-transfer ./runApp.sh
In order for the following shell script to properly parse the JSON, you must install jq
:
instructions https://stedolan.github.io/jq/
With the application started in terminal 1, next, test the APIs by executing the script - testAPIs.sh:
cd fabric-samples/balance-transfer ## To use golang chaincode execute the following command ./testAPIs.sh -l golang ## OR use node.js chaincode ./testAPIs.sh -l node
curl -s -X POST http://localhost:4000/users -H "content-type: application/x-www-form-urlencoded" -d 'username=Jim&orgName=Org1'
OUTPUT:
{ "success": true, "secret": "RaxhMgevgJcm", "message": "Jim enrolled Successfully", "token": "<put JSON Web Token here>" }
The response contains the success/failure status, an enrollment Secret and a JSON Web Token (JWT) that is a required string in the Request Headers for subsequent requests.
curl -s -X POST \ http://localhost:4000/channels \ -H "authorization: Bearer <put JSON Web Token here>" \ -H "content-type: application/json" \ -d '{ "channelName":"mychannel", "channelConfigPath":"../artifacts/channel/mychannel.tx" }'
Please note that the Header authorization must contain the JWT returned from the POST /users
call
curl -s -X POST \ http://localhost:4000/channels/mychannel/peers \ -H "authorization: Bearer <put JSON Web Token here>" \ -H "content-type: application/json" \ -d '{ "peers": ["peer0.org1.example.com","peer1.org1.example.com"] }'
curl -s -X POST \ http://localhost:4000/chaincodes \ -H "authorization: Bearer <put JSON Web Token here>" \ -H "content-type: application/json" \ -d '{ "peers": ["peer0.org1.example.com","peer1.org1.example.com"], "chaincodeName":"mycc", "chaincodePath":"github.com/example_cc/go", "chaincodeType": "golang", "chaincodeVersion":"v0" }'
NOTE: chaincodeType must be set to node when node.js chaincode is used and chaincodePath must be set to the location of the node.js chaincode. Also put in the $PWD
ex: curl -s -X POST \ http://localhost:4000/chaincodes \ -H "authorization: Bearer <put JSON Web Token here>" \ -H "content-type: application/json" \ -d '{ "peers": ["peer0.org1.example.com","peer1.org1.example.com"], "chaincodeName":"mycc", "chaincodePath":"$PWD/artifacts/src/github.com/example_cc/node", "chaincodeType": "node", "chaincodeVersion":"v0" }'
curl -s -X POST \ http://localhost:4000/channels/mychannel/chaincodes \ -H "authorization: Bearer <put JSON Web Token here>" \ -H "content-type: application/json" \ -d '{ "peers": ["peer0.org1.example.com","peer1.org1.example.com"], "chaincodeName":"mycc", "chaincodeVersion":"v0", "chaincodeType": "golang", "args":["a","100","b","200"] }'
NOTE: chaincodeType must be set to node when node.js chaincode is used
curl -s -X POST \ http://localhost:4000/channels/mychannel/chaincodes/mycc \ -H "authorization: Bearer <put JSON Web Token here>" \ -H "content-type: application/json" \ -d '{ "peers": ["peer0.org1.example.com","peer1.org1.example.com"], "fcn":"move", "args":["a","b","10"] }'
NOTE: Ensure that you save the Transaction ID from the response in order to pass this string in the subsequent query transactions.
curl -s -X GET \ "http://localhost:4000/channels/mychannel/chaincodes/mycc?peer=peer0.org1.example.com&fcn=query&args=%5B%22a%22%5D" \ -H "authorization: Bearer <put JSON Web Token here>" \ -H "content-type: application/json"
curl -s -X GET \ "http://localhost:4000/channels/mychannel/blocks/1?peer=peer0.org1.example.com" \ -H "authorization: Bearer <put JSON Web Token here>" \ -H "content-type: application/json"
curl -s -X GET http://localhost:4000/channels/mychannel/transactions/<put transaction id here>?peer=peer0.org1.example.com \ -H "authorization: Bearer <put JSON Web Token here>" \ -H "content-type: application/json"
NOTE: The transaction id can be from any previous invoke transaction, see results of the invoke request, will look something like 8a95b1794cb17e7772164c3f1292f8410fcfdc1943955a35c9764a21fcd1d1b3
.
curl -s -X GET \ "http://localhost:4000/channels/mychannel?peer=peer0.org1.example.com" \ -H "authorization: Bearer <put JSON Web Token here>" \ -H "content-type: application/json"
curl -s -X GET \ "http://localhost:4000/chaincodes?peer=peer0.org1.example.com&type=installed" \ -H "authorization: Bearer <put JSON Web Token here>" \ -H "content-type: application/json"
curl -s -X GET \ "http://localhost:4000/chaincodes?peer=peer0.org1.example.com&type=instantiated" \ -H "authorization: Bearer <put JSON Web Token here>" \ -H "content-type: application/json"
curl -s -X GET \ "http://localhost:4000/channels?peer=peer0.org1.example.com" \ -H "authorization: Bearer <put JSON Web Token here>" \ -H "content-type: application/json"
The network will still be running at this point. Before starting the network manually again, here are the commands which cleans the containers and artifacts.
docker rm -f $(docker ps -aq) docker rmi -f $(docker images | grep dev | awk '{print $3}') rm -rf fabric-client-kv-org[1-2]
You have the ability to change configuration parameters by either directly editing the network-config.yaml file or provide an additional file for an alternative target network. The app uses an optional environment variable "TARGET_NETWORK" to control the configuration files to use. For example, if you deployed the target network on Amazon Web Services EC2, you can add a file "network-config-aws.yaml", and set the "TARGET_NETWORK" environment to 'aws'. The app will pick up the settings inside the "network-config-aws.yaml" file.
If you choose to customize your docker-compose yaml file by hardcoding IP Addresses and PORT information for your peers and orderer, then you MUST also add the identical values into the network-config.yaml file. The url and eventUrl settings will need to be adjusted to match your docker-compose yaml file.
peer1.org1.example.com: url: grpcs://x.x.x.x:7056 eventUrl: grpcs://x.x.x.x:7058
To retrieve the IP Address for one of your network entities, issue the following command:
# this will return the IP Address for peer0 docker inspect peer0 | grep IPAddress