mirror of
https://github.com/hyperledger/fabric-samples.git
synced 2026-06-17 15:35:09 +00:00
[FAB-5363] fabric-samples update balance
Update balance transfer sample to use the connection profile and node 8. Change-Id: I17c74c6cb23ebe55a8f2bba735d41525ae9e5ab1 Signed-off-by: Bret Harrison <beharrison@nc.rr.com> Signed-off-by: ratnakar <asara.ratnakar@gmail.com>
This commit is contained in:
parent
6b2799e620
commit
bb3ac84e6e
21 changed files with 3864 additions and 1047 deletions
|
|
@ -7,7 +7,7 @@ A sample Node.js app to demonstrate **__fabric-client__** & **__fabric-ca-client
|
|||
* [Docker](https://www.docker.com/products/overview) - v1.12 or higher
|
||||
* [Docker Compose](https://docs.docker.com/compose/overview/) - v1.8 or higher
|
||||
* [Git client](https://git-scm.com/downloads) - needed for clone commands
|
||||
* **Node.js** v6.9.0 - 6.10.0 ( __Node v7+ is not supported__ )
|
||||
* **Node.js** v8.4.0 or higher
|
||||
* [Download Docker images](http://hyperledger-fabric.readthedocs.io/en/latest/samples.html#binaries)
|
||||
|
||||
```
|
||||
|
|
@ -99,7 +99,7 @@ cd fabric-samples/balance-transfer
|
|||
|
||||
* Register and enroll new users in Organization - **Org1**:
|
||||
|
||||
`curl -s -X POST http://localhost:4000/users -H "content-type: application/x-www-form-urlencoded" -d 'username=Jim&orgName=org1'`
|
||||
`curl -s -X POST http://localhost:4000/users -H "content-type: application/x-www-form-urlencoded" -d 'username=Jim&orgName=Org1'`
|
||||
|
||||
**OUTPUT:**
|
||||
|
||||
|
|
@ -137,7 +137,7 @@ curl -s -X POST \
|
|||
-H "authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0OTQ4NjU1OTEsInVzZXJuYW1lIjoiSmltIiwib3JnTmFtZSI6Im9yZzEiLCJpYXQiOjE0OTQ4NjE5OTF9.yWaJhFDuTvMQRaZIqg20Is5t-JJ_1BP58yrNLOKxtNI" \
|
||||
-H "content-type: application/json" \
|
||||
-d '{
|
||||
"peers": ["peer1","peer2"]
|
||||
"peers": ["peer0.org1.example.com","peer1.org1.example.com"]
|
||||
}'
|
||||
```
|
||||
### Install chaincode
|
||||
|
|
@ -148,7 +148,7 @@ curl -s -X POST \
|
|||
-H "authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0OTQ4NjU1OTEsInVzZXJuYW1lIjoiSmltIiwib3JnTmFtZSI6Im9yZzEiLCJpYXQiOjE0OTQ4NjE5OTF9.yWaJhFDuTvMQRaZIqg20Is5t-JJ_1BP58yrNLOKxtNI" \
|
||||
-H "content-type: application/json" \
|
||||
-d '{
|
||||
"peers": ["peer1","peer2"],
|
||||
"peers": ["peer0.org1.example.com","peer1.org1.example.com"],
|
||||
"chaincodeName":"mycc",
|
||||
"chaincodePath":"github.com/example_cc",
|
||||
"chaincodeType": "golang",
|
||||
|
|
@ -163,7 +163,7 @@ curl -s -X POST \
|
|||
-H "authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0OTQ4NjU1OTEsInVzZXJuYW1lIjoiSmltIiwib3JnTmFtZSI6Im9yZzEiLCJpYXQiOjE0OTQ4NjE5OTF9.yWaJhFDuTvMQRaZIqg20Is5t-JJ_1BP58yrNLOKxtNI" \
|
||||
-H "content-type: application/json" \
|
||||
-d "{
|
||||
\"peers\": [\"peer1\",\"peer2\"],
|
||||
\"peers\": [\"peer0.org1.example.com\",\"peer1.org1.example.com\"],
|
||||
\"chaincodeName\":\"mycc\",
|
||||
\"chaincodePath\":\"$PWD/artifacts/src/github.com/example_cc/node\",
|
||||
\"chaincodeType\": \"node\",
|
||||
|
|
@ -205,7 +205,7 @@ curl -s -X POST \
|
|||
|
||||
```
|
||||
curl -s -X GET \
|
||||
"http://localhost:4000/channels/mychannel/chaincodes/mycc?peer=peer1&fcn=query&args=%5B%22a%22%5D" \
|
||||
"http://localhost:4000/channels/mychannel/chaincodes/mycc?peer=peer0.org1.example.com&fcn=query&args=%5B%22a%22%5D" \
|
||||
-H "authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0OTQ4NjU1OTEsInVzZXJuYW1lIjoiSmltIiwib3JnTmFtZSI6Im9yZzEiLCJpYXQiOjE0OTQ4NjE5OTF9.yWaJhFDuTvMQRaZIqg20Is5t-JJ_1BP58yrNLOKxtNI" \
|
||||
-H "content-type: application/json"
|
||||
```
|
||||
|
|
@ -214,7 +214,7 @@ curl -s -X GET \
|
|||
|
||||
```
|
||||
curl -s -X GET \
|
||||
"http://localhost:4000/channels/mychannel/blocks/1?peer=peer1" \
|
||||
"http://localhost:4000/channels/mychannel/blocks/1?peer=peer0.org1.example.com" \
|
||||
-H "authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0OTQ4NjU1OTEsInVzZXJuYW1lIjoiSmltIiwib3JnTmFtZSI6Im9yZzEiLCJpYXQiOjE0OTQ4NjE5OTF9.yWaJhFDuTvMQRaZIqg20Is5t-JJ_1BP58yrNLOKxtNI" \
|
||||
-H "content-type: application/json"
|
||||
```
|
||||
|
|
@ -222,18 +222,18 @@ curl -s -X GET \
|
|||
### Query Transaction by TransactionID
|
||||
|
||||
```
|
||||
curl -s -X GET http://localhost:4000/channels/mychannel/transactions/TRX_ID?peer=peer1 \
|
||||
curl -s -X GET http://localhost:4000/channels/mychannel/transactions/TRX_ID?peer=peer0.org1.example.com \
|
||||
-H "authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0OTQ4NjU1OTEsInVzZXJuYW1lIjoiSmltIiwib3JnTmFtZSI6Im9yZzEiLCJpYXQiOjE0OTQ4NjE5OTF9.yWaJhFDuTvMQRaZIqg20Is5t-JJ_1BP58yrNLOKxtNI" \
|
||||
-H "content-type: application/json"
|
||||
```
|
||||
**NOTE**: Here the TRX_ID can be from any previous invoke transaction
|
||||
**NOTE**: Here the TRX_ID can be from any previous invoke transaction, see results of the invoke request, will look something like `8a95b1794cb17e7772164c3f1292f8410fcfdc1943955a35c9764a21fcd1d1b3`.
|
||||
|
||||
|
||||
### Query ChainInfo
|
||||
|
||||
```
|
||||
curl -s -X GET \
|
||||
"http://localhost:4000/channels/mychannel?peer=peer1" \
|
||||
"http://localhost:4000/channels/mychannel?peer=peer0.org1.example.com" \
|
||||
-H "authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0OTQ4NjU1OTEsInVzZXJuYW1lIjoiSmltIiwib3JnTmFtZSI6Im9yZzEiLCJpYXQiOjE0OTQ4NjE5OTF9.yWaJhFDuTvMQRaZIqg20Is5t-JJ_1BP58yrNLOKxtNI" \
|
||||
-H "content-type: application/json"
|
||||
```
|
||||
|
|
@ -242,7 +242,7 @@ curl -s -X GET \
|
|||
|
||||
```
|
||||
curl -s -X GET \
|
||||
"http://localhost:4000/chaincodes?peer=peer1&type=installed" \
|
||||
"http://localhost:4000/chaincodes?peer=peer0.org1.example.com&type=installed" \
|
||||
-H "authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0OTQ4NjU1OTEsInVzZXJuYW1lIjoiSmltIiwib3JnTmFtZSI6Im9yZzEiLCJpYXQiOjE0OTQ4NjE5OTF9.yWaJhFDuTvMQRaZIqg20Is5t-JJ_1BP58yrNLOKxtNI" \
|
||||
-H "content-type: application/json"
|
||||
```
|
||||
|
|
@ -251,7 +251,7 @@ curl -s -X GET \
|
|||
|
||||
```
|
||||
curl -s -X GET \
|
||||
"http://localhost:4000/chaincodes?peer=peer1&type=instantiated" \
|
||||
"http://localhost:4000/chaincodes?peer=peer0.org1.example.com&type=instantiated" \
|
||||
-H "authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0OTQ4NjU1OTEsInVzZXJuYW1lIjoiSmltIiwib3JnTmFtZSI6Im9yZzEiLCJpYXQiOjE0OTQ4NjE5OTF9.yWaJhFDuTvMQRaZIqg20Is5t-JJ_1BP58yrNLOKxtNI" \
|
||||
-H "content-type: application/json"
|
||||
```
|
||||
|
|
@ -260,50 +260,23 @@ curl -s -X GET \
|
|||
|
||||
```
|
||||
curl -s -X GET \
|
||||
"http://localhost:4000/channels?peer=peer1" \
|
||||
"http://localhost:4000/channels?peer=peer0.org1.example.com" \
|
||||
-H "authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0OTQ4NjU1OTEsInVzZXJuYW1lIjoiSmltIiwib3JnTmFtZSI6Im9yZzEiLCJpYXQiOjE0OTQ4NjE5OTF9.yWaJhFDuTvMQRaZIqg20Is5t-JJ_1BP58yrNLOKxtNI" \
|
||||
-H "content-type: application/json"
|
||||
```
|
||||
|
||||
### Network configuration considerations
|
||||
|
||||
You have the ability to change configuration parameters by either directly editing the network-config.json 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.json", and set the "TARGET_NETWORK" environment to 'aws'. The app will pick up the settings inside the "network-config-aws.json" file.
|
||||
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.
|
||||
|
||||
#### IP Address** and PORT information
|
||||
|
||||
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.json file. The paths shown below will need to be adjusted to match your docker-compose 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.
|
||||
|
||||
```
|
||||
"orderer": {
|
||||
"url": "grpcs://x.x.x.x:7050",
|
||||
"server-hostname": "orderer0",
|
||||
"tls_cacerts": "../artifacts/tls/orderer/ca-cert.pem"
|
||||
},
|
||||
"org1": {
|
||||
"ca": "http://x.x.x.x:7054",
|
||||
"peer1": {
|
||||
"requests": "grpcs://x.x.x.x:7051",
|
||||
"events": "grpcs://x.x.x.x:7053",
|
||||
...
|
||||
},
|
||||
"peer2": {
|
||||
"requests": "grpcs://x.x.x.x:7056",
|
||||
"events": "grpcs://x.x.x.x:7058",
|
||||
...
|
||||
}
|
||||
},
|
||||
"org2": {
|
||||
"ca": "http://x.x.x.x:8054",
|
||||
"peer1": {
|
||||
"requests": "grpcs://x.x.x.x:8051",
|
||||
"events": "grpcs://x.x.x.x:8053",
|
||||
... },
|
||||
"peer2": {
|
||||
"requests": "grpcs://x.x.x.x:8056",
|
||||
"events": "grpcs://x.x.x.x:8058",
|
||||
...
|
||||
}
|
||||
}
|
||||
peer1.org1.example.com:
|
||||
url: grpcs://x.x.x.x:7056
|
||||
eventUrl: grpcs://x.x.x.x:7058
|
||||
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ require('./config.js');
|
|||
var hfc = require('fabric-client');
|
||||
|
||||
var helper = require('./app/helper.js');
|
||||
var channels = require('./app/create-channel.js');
|
||||
var createChannel = require('./app/create-channel.js');
|
||||
var join = require('./app/join-channel.js');
|
||||
var install = require('./app/install-chaincode.js');
|
||||
var instantiate = require('./app/instantiate-chaincode.js');
|
||||
|
|
@ -60,6 +60,7 @@ app.use(expressJWT({
|
|||
}));
|
||||
app.use(bearerToken());
|
||||
app.use(function(req, res, next) {
|
||||
logger.debug(' ------>>>>>> new request for %s',req.originalUrl);
|
||||
if (req.originalUrl.indexOf('/users') >= 0) {
|
||||
return next();
|
||||
}
|
||||
|
|
@ -90,8 +91,7 @@ app.use(function(req, res, next) {
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
var server = http.createServer(app).listen(port, function() {});
|
||||
logger.info('****************** SERVER STARTED ************************');
|
||||
logger.info('************** http://' + host + ':' + port +
|
||||
' ******************');
|
||||
logger.info('*************** http://%s:%s ******************',host,port);
|
||||
server.timeout = 240000;
|
||||
|
||||
function getErrorMessage(field) {
|
||||
|
|
@ -106,7 +106,7 @@ function getErrorMessage(field) {
|
|||
///////////////////////// REST ENDPOINTS START HERE ///////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Register and enroll user
|
||||
app.post('/users', function(req, res) {
|
||||
app.post('/users', async function(req, res) {
|
||||
var username = req.body.username;
|
||||
var orgName = req.body.orgName;
|
||||
logger.debug('End point : /users');
|
||||
|
|
@ -125,20 +125,18 @@ app.post('/users', function(req, res) {
|
|||
username: username,
|
||||
orgName: orgName
|
||||
}, app.get('secret'));
|
||||
helper.getRegisteredUsers(username, orgName, true).then(function(response) {
|
||||
if (response && typeof response !== 'string') {
|
||||
response.token = token;
|
||||
res.json(response);
|
||||
} else {
|
||||
res.json({
|
||||
success: false,
|
||||
message: response
|
||||
});
|
||||
}
|
||||
});
|
||||
let response = await helper.getRegisteredUser(username, orgName, true);
|
||||
logger.debug('Successfully returned from registering the username %s for organization %s',username,orgName);
|
||||
if (response && typeof response !== 'string') {
|
||||
response.token = token;
|
||||
res.json(response);
|
||||
} else {
|
||||
res.json({success: false, message: response});
|
||||
}
|
||||
|
||||
});
|
||||
// Create Channel
|
||||
app.post('/channels', function(req, res) {
|
||||
app.post('/channels', async function(req, res) {
|
||||
logger.info('<<<<<<<<<<<<<<<<< C R E A T E C H A N N E L >>>>>>>>>>>>>>>>>');
|
||||
logger.debug('End point : /channels');
|
||||
var channelName = req.body.channelName;
|
||||
|
|
@ -154,18 +152,19 @@ app.post('/channels', function(req, res) {
|
|||
return;
|
||||
}
|
||||
|
||||
channels.createChannel(channelName, channelConfigPath, req.username, req.orgname)
|
||||
.then(function(message) {
|
||||
res.send(message);
|
||||
});
|
||||
let message = await createChannel.createChannel(channelName, channelConfigPath, req.username, req.orgname);
|
||||
res.send(message);
|
||||
});
|
||||
// Join Channel
|
||||
app.post('/channels/:channelName/peers', function(req, res) {
|
||||
app.post('/channels/:channelName/peers', async function(req, res) {
|
||||
logger.info('<<<<<<<<<<<<<<<<< J O I N C H A N N E L >>>>>>>>>>>>>>>>>');
|
||||
var channelName = req.params.channelName;
|
||||
var peers = req.body.peers;
|
||||
logger.debug('channelName : ' + channelName);
|
||||
logger.debug('peers : ' + peers);
|
||||
logger.debug('username :' + req.username);
|
||||
logger.debug('orgname:' + req.orgname);
|
||||
|
||||
if (!channelName) {
|
||||
res.json(getErrorMessage('\'channelName\''));
|
||||
return;
|
||||
|
|
@ -175,13 +174,11 @@ app.post('/channels/:channelName/peers', function(req, res) {
|
|||
return;
|
||||
}
|
||||
|
||||
join.joinChannel(channelName, peers, req.username, req.orgname)
|
||||
.then(function(message) {
|
||||
res.send(message);
|
||||
});
|
||||
let message = await join.joinChannel(channelName, peers, req.username, req.orgname);
|
||||
res.send(message);
|
||||
});
|
||||
// Install chaincode on target peers
|
||||
app.post('/chaincodes', function(req, res) {
|
||||
app.post('/chaincodes', async function(req, res) {
|
||||
logger.debug('==================== INSTALL CHAINCODE ==================');
|
||||
var peers = req.body.peers;
|
||||
var chaincodeName = req.body.chaincodeName;
|
||||
|
|
@ -213,13 +210,10 @@ app.post('/chaincodes', function(req, res) {
|
|||
res.json(getErrorMessage('\'chaincodeType\''));
|
||||
return;
|
||||
}
|
||||
install.installChaincode(peers, chaincodeName, chaincodePath, chaincodeVersion, chaincodeType, req.username, req.orgname)
|
||||
.then(function(message) {
|
||||
res.send(message);
|
||||
});
|
||||
});
|
||||
let message = await install.installChaincode(peers, chaincodeName, chaincodePath, chaincodeVersion, chaincodeType, req.username, req.orgname)
|
||||
res.send(message);});
|
||||
// Instantiate chaincode on target peers
|
||||
app.post('/channels/:channelName/chaincodes', function(req, res) {
|
||||
app.post('/channels/:channelName/chaincodes', async function(req, res) {
|
||||
logger.debug('==================== INSTANTIATE CHAINCODE ==================');
|
||||
var chaincodeName = req.body.chaincodeName;
|
||||
var chaincodeVersion = req.body.chaincodeVersion;
|
||||
|
|
@ -253,13 +247,12 @@ app.post('/channels/:channelName/chaincodes', function(req, res) {
|
|||
res.json(getErrorMessage('\'args\''));
|
||||
return;
|
||||
}
|
||||
instantiate.instantiateChaincode(channelName, chaincodeName, chaincodeVersion, chaincodeType, fcn, args, req.username, req.orgname)
|
||||
.then(function(message) {
|
||||
res.send(message);
|
||||
});
|
||||
|
||||
let message = await instantiate.instantiateChaincode(channelName, chaincodeName, chaincodeVersion, chaincodeType, fcn, args, req.username, req.orgname);
|
||||
res.send(message);
|
||||
});
|
||||
// Invoke transaction on chaincode on target peers
|
||||
app.post('/channels/:channelName/chaincodes/:chaincodeName', function(req, res) {
|
||||
app.post('/channels/:channelName/chaincodes/:chaincodeName', async function(req, res) {
|
||||
logger.debug('==================== INVOKE ON CHAINCODE ==================');
|
||||
var peers = req.body.peers;
|
||||
var chaincodeName = req.params.chaincodeName;
|
||||
|
|
@ -287,13 +280,11 @@ app.post('/channels/:channelName/chaincodes/:chaincodeName', function(req, res)
|
|||
return;
|
||||
}
|
||||
|
||||
invoke.invokeChaincode(peers, channelName, chaincodeName, fcn, args, req.username, req.orgname)
|
||||
.then(function(message) {
|
||||
res.send(message);
|
||||
});
|
||||
let message = await invoke.invokeChaincode(peers, channelName, chaincodeName, fcn, args, req.username, req.orgname);
|
||||
res.send(message);
|
||||
});
|
||||
// Query on chaincode on target peers
|
||||
app.get('/channels/:channelName/chaincodes/:chaincodeName', function(req, res) {
|
||||
app.get('/channels/:channelName/chaincodes/:chaincodeName', async function(req, res) {
|
||||
logger.debug('==================== QUERY BY CHAINCODE ==================');
|
||||
var channelName = req.params.channelName;
|
||||
var chaincodeName = req.params.chaincodeName;
|
||||
|
|
@ -326,13 +317,11 @@ app.get('/channels/:channelName/chaincodes/:chaincodeName', function(req, res) {
|
|||
args = JSON.parse(args);
|
||||
logger.debug(args);
|
||||
|
||||
query.queryChaincode(peer, channelName, chaincodeName, args, fcn, req.username, req.orgname)
|
||||
.then(function(message) {
|
||||
res.send(message);
|
||||
});
|
||||
let message = await query.queryChaincode(peer, channelName, chaincodeName, args, fcn, req.username, req.orgname);
|
||||
res.send(message);
|
||||
});
|
||||
// Query Get Block by BlockNumber
|
||||
app.get('/channels/:channelName/blocks/:blockId', function(req, res) {
|
||||
app.get('/channels/:channelName/blocks/:blockId', async function(req, res) {
|
||||
logger.debug('==================== GET BLOCK BY NUMBER ==================');
|
||||
let blockId = req.params.blockId;
|
||||
let peer = req.query.peer;
|
||||
|
|
@ -344,16 +333,12 @@ app.get('/channels/:channelName/blocks/:blockId', function(req, res) {
|
|||
return;
|
||||
}
|
||||
|
||||
query.getBlockByNumber(peer, blockId, req.username, req.orgname)
|
||||
.then(function(message) {
|
||||
res.send(message);
|
||||
});
|
||||
let message = await query.getBlockByNumber(peer, req.params.channelName, blockId, req.username, req.orgname);
|
||||
res.send(message);
|
||||
});
|
||||
// Query Get Transaction by Transaction ID
|
||||
app.get('/channels/:channelName/transactions/:trxnId', function(req, res) {
|
||||
logger.debug(
|
||||
'================ GET TRANSACTION BY TRANSACTION_ID ======================'
|
||||
);
|
||||
app.get('/channels/:channelName/transactions/:trxnId', async function(req, res) {
|
||||
logger.debug('================ GET TRANSACTION BY TRANSACTION_ID ======================');
|
||||
logger.debug('channelName : ' + req.params.channelName);
|
||||
let trxnId = req.params.trxnId;
|
||||
let peer = req.query.peer;
|
||||
|
|
@ -362,13 +347,11 @@ app.get('/channels/:channelName/transactions/:trxnId', function(req, res) {
|
|||
return;
|
||||
}
|
||||
|
||||
query.getTransactionByID(peer, trxnId, req.username, req.orgname)
|
||||
.then(function(message) {
|
||||
res.send(message);
|
||||
});
|
||||
let message = await query.getTransactionByID(peer, req.params.channelName, trxnId, req.username, req.orgname);
|
||||
res.send(message);
|
||||
});
|
||||
// Query Get Block by Hash
|
||||
app.get('/channels/:channelName/blocks', function(req, res) {
|
||||
app.get('/channels/:channelName/blocks', async function(req, res) {
|
||||
logger.debug('================ GET BLOCK BY HASH ======================');
|
||||
logger.debug('channelName : ' + req.params.channelName);
|
||||
let hash = req.query.hash;
|
||||
|
|
@ -378,43 +361,38 @@ app.get('/channels/:channelName/blocks', function(req, res) {
|
|||
return;
|
||||
}
|
||||
|
||||
query.getBlockByHash(peer, hash, req.username, req.orgname).then(
|
||||
function(message) {
|
||||
res.send(message);
|
||||
});
|
||||
let message = await query.getBlockByHash(peer, req.params.channelName, hash, req.username, req.orgname);
|
||||
res.send(message);
|
||||
});
|
||||
//Query for Channel Information
|
||||
app.get('/channels/:channelName', function(req, res) {
|
||||
logger.debug(
|
||||
'================ GET CHANNEL INFORMATION ======================');
|
||||
app.get('/channels/:channelName', async function(req, res) {
|
||||
logger.debug('================ GET CHANNEL INFORMATION ======================');
|
||||
logger.debug('channelName : ' + req.params.channelName);
|
||||
let peer = req.query.peer;
|
||||
|
||||
query.getChainInfo(peer, req.username, req.orgname).then(
|
||||
function(message) {
|
||||
res.send(message);
|
||||
});
|
||||
let message = await query.getChainInfo(peer, req.params.channelName, req.username, req.orgname);
|
||||
res.send(message);
|
||||
});
|
||||
//Query for Channel instantiated chaincodes
|
||||
app.get('/channels/:channelName/chaincodes', async function(req, res) {
|
||||
logger.debug('================ GET INSTANTIATED CHAINCODES ======================');
|
||||
logger.debug('channelName : ' + req.params.channelName);
|
||||
let peer = req.query.peer;
|
||||
|
||||
let message = await query.getInstalledChaincodes(peer, req.params.channelName, 'instantiated', req.username, req.orgname);
|
||||
res.send(message);
|
||||
});
|
||||
// Query to fetch all Installed/instantiated chaincodes
|
||||
app.get('/chaincodes', function(req, res) {
|
||||
app.get('/chaincodes', async function(req, res) {
|
||||
var peer = req.query.peer;
|
||||
var installType = req.query.type;
|
||||
//TODO: add Constnats
|
||||
if (installType === 'installed') {
|
||||
logger.debug(
|
||||
'================ GET INSTALLED CHAINCODES ======================');
|
||||
} else {
|
||||
logger.debug(
|
||||
'================ GET INSTANTIATED CHAINCODES ======================');
|
||||
}
|
||||
logger.debug('================ GET INSTALLED CHAINCODES ======================');
|
||||
|
||||
query.getInstalledChaincodes(peer, installType, req.username, req.orgname)
|
||||
.then(function(message) {
|
||||
res.send(message);
|
||||
});
|
||||
let message = await query.getInstalledChaincodes(peer, null, 'installed', req.username, req.orgname)
|
||||
res.send(message);
|
||||
});
|
||||
// Query to fetch channels
|
||||
app.get('/channels', function(req, res) {
|
||||
app.get('/channels', async function(req, res) {
|
||||
logger.debug('================ GET CHANNELS ======================');
|
||||
logger.debug('peer: ' + req.query.peer);
|
||||
var peer = req.query.peer;
|
||||
|
|
@ -423,9 +401,6 @@ app.get('/channels', function(req, res) {
|
|||
return;
|
||||
}
|
||||
|
||||
query.getChannels(peer, req.username, req.orgname)
|
||||
.then(function(
|
||||
message) {
|
||||
res.send(message);
|
||||
});
|
||||
let message = await query.getChannels(peer, req.username, req.orgname);
|
||||
res.send(message);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -16,41 +16,37 @@
|
|||
var util = require('util');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var config = require('../config.json');
|
||||
|
||||
var helper = require('./helper.js');
|
||||
var logger = helper.getLogger('Create-Channel');
|
||||
//Attempt to send a request to the orderer with the sendCreateChain method
|
||||
var createChannel = function(channelName, channelConfigPath, username, orgName) {
|
||||
//Attempt to send a request to the orderer with the sendTransaction method
|
||||
var createChannel = async function(channelName, channelConfigPath, username, orgName) {
|
||||
logger.debug('\n====== Creating Channel \'' + channelName + '\' ======\n');
|
||||
var client = helper.getClientForOrg(orgName);
|
||||
var channel = helper.getChannelForOrg(orgName);
|
||||
try {
|
||||
// first setup the client for this org
|
||||
var client = await helper.getClientForOrg(orgName);
|
||||
logger.debug('Successfully got the fabric client for the organization "%s"', orgName);
|
||||
|
||||
// read in the envelope for the channel config raw bytes
|
||||
var envelope = fs.readFileSync(path.join(__dirname, channelConfigPath));
|
||||
// extract the channel config bytes from the envelope to be signed
|
||||
var channelConfig = client.extractChannelConfig(envelope);
|
||||
// read in the envelope for the channel config raw bytes
|
||||
var envelope = fs.readFileSync(path.join(__dirname, channelConfigPath));
|
||||
// extract the channel config bytes from the envelope to be signed
|
||||
var channelConfig = client.extractChannelConfig(envelope);
|
||||
|
||||
//Acting as a client in the given organization provided with "orgName" param
|
||||
return helper.getOrgAdmin(orgName).then((admin) => {
|
||||
logger.debug(util.format('Successfully acquired admin user for the organization "%s"', orgName));
|
||||
//Acting as a client in the given organization provided with "orgName" param
|
||||
// sign the channel config bytes as "endorsement", this is required by
|
||||
// the orderer's channel creation policy
|
||||
// this will use the admin identity assigned to the client when the connection profile was loaded
|
||||
let signature = client.signChannelConfig(channelConfig);
|
||||
|
||||
let request = {
|
||||
config: channelConfig,
|
||||
signatures: [signature],
|
||||
name: channelName,
|
||||
orderer: channel.getOrderers()[0],
|
||||
txId: client.newTransactionID()
|
||||
txId: client.newTransactionID(true) // get an admin based transactionID
|
||||
};
|
||||
|
||||
// send to orderer
|
||||
return client.createChannel(request);
|
||||
}, (err) => {
|
||||
logger.error('Failed to enroll user \''+username+'\'. Error: ' + err);
|
||||
throw new Error('Failed to enroll user \''+username+'\'' + err);
|
||||
}).then((response) => {
|
||||
var response = await client.createChannel(request)
|
||||
logger.debug(' response ::%j', response);
|
||||
if (response && response.status === 'SUCCESS') {
|
||||
logger.debug('Successfully created the channel.');
|
||||
|
|
@ -58,17 +54,16 @@ var createChannel = function(channelName, channelConfigPath, username, orgName)
|
|||
success: true,
|
||||
message: 'Channel \'' + channelName + '\' created Successfully'
|
||||
};
|
||||
return response;
|
||||
return response;
|
||||
} else {
|
||||
logger.error('\n!!!!!!!!! Failed to create the channel \'' + channelName +
|
||||
'\' !!!!!!!!!\n\n');
|
||||
throw new Error('Failed to create the channel \'' + channelName + '\'');
|
||||
}
|
||||
}, (err) => {
|
||||
logger.error('Failed to initialize the channel: ' + err.stack ? err.stack :
|
||||
err);
|
||||
throw new Error('Failed to initialize the channel: ' + err.stack ? err.stack : err);
|
||||
});
|
||||
} catch (err) {
|
||||
logger.error('Failed to initialize the channel: ' + err.stack ? err.stack : err);
|
||||
throw new Error('Failed to initialize the channel: ' + err.toString());
|
||||
}
|
||||
};
|
||||
|
||||
exports.createChannel = createChannel;
|
||||
|
|
|
|||
|
|
@ -33,270 +33,89 @@ var clients = {};
|
|||
var channels = {};
|
||||
var caClients = {};
|
||||
|
||||
// set up the client and channel objects for each org
|
||||
for (let key in ORGS) {
|
||||
if (key.indexOf('org') === 0) {
|
||||
let client = new hfc();
|
||||
|
||||
let cryptoSuite = hfc.newCryptoSuite();
|
||||
cryptoSuite.setCryptoKeyStore(hfc.newCryptoKeyStore({path: getKeyStoreForOrg(ORGS[key].name)}));
|
||||
client.setCryptoSuite(cryptoSuite);
|
||||
|
||||
let channel = client.newChannel(hfc.getConfigSetting('channelName'));
|
||||
channel.addOrderer(newOrderer(client));
|
||||
|
||||
clients[key] = client;
|
||||
channels[key] = channel;
|
||||
|
||||
setupPeers(channel, key, client);
|
||||
|
||||
let caUrl = ORGS[key].ca;
|
||||
caClients[key] = new copService(caUrl, null /*defautl TLS opts*/, '' /* default CA */, cryptoSuite);
|
||||
}
|
||||
var sleep = async function (sleep_time_ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, sleep_time_ms));
|
||||
}
|
||||
|
||||
function setupPeers(channel, org, client) {
|
||||
for (let key in ORGS[org].peers) {
|
||||
let data = fs.readFileSync(path.join(__dirname, ORGS[org].peers[key]['tls_cacerts']));
|
||||
let peer = client.newPeer(
|
||||
ORGS[org].peers[key].requests,
|
||||
{
|
||||
pem: Buffer.from(data).toString(),
|
||||
'ssl-target-name-override': ORGS[org].peers[key]['server-hostname']
|
||||
}
|
||||
);
|
||||
peer.setName(key);
|
||||
async function getClientForOrg (userorg, username) {
|
||||
logger.debug('getClientForOrg - ****** START %s %s', userorg, username)
|
||||
// get a fabric client loaded with a connection profile for this org
|
||||
let config = '-connection-profile-path';
|
||||
|
||||
channel.addPeer(peer);
|
||||
}
|
||||
}
|
||||
// build a client context and load it with a connection profile
|
||||
// lets only load the network settings and save the client for later
|
||||
let client = hfc.loadFromConfig(hfc.getConfigSetting('network'+config));
|
||||
|
||||
function newOrderer(client) {
|
||||
var caRootsPath = ORGS.orderer.tls_cacerts;
|
||||
let data = fs.readFileSync(path.join(__dirname, caRootsPath));
|
||||
let caroots = Buffer.from(data).toString();
|
||||
return client.newOrderer(ORGS.orderer.url, {
|
||||
'pem': caroots,
|
||||
'ssl-target-name-override': ORGS.orderer['server-hostname']
|
||||
});
|
||||
}
|
||||
// This will load a connection profile over the top of the current one one
|
||||
// since the first one did not have a client section and the following one does
|
||||
// nothing will actually be replaced.
|
||||
// This will also set an admin identity because the organization defined in the
|
||||
// client section has one defined
|
||||
client.loadFromConfig(hfc.getConfigSetting(userorg+config));
|
||||
|
||||
function readAllFiles(dir) {
|
||||
var files = fs.readdirSync(dir);
|
||||
var certs = [];
|
||||
files.forEach((file_name) => {
|
||||
let file_path = path.join(dir,file_name);
|
||||
let data = fs.readFileSync(file_path);
|
||||
certs.push(data);
|
||||
});
|
||||
return certs;
|
||||
}
|
||||
// this will create both the state store and the crypto store based
|
||||
// on the settings in the client section of the connection profile
|
||||
await client.initCredentialStores();
|
||||
|
||||
function getOrgName(org) {
|
||||
return ORGS[org].name;
|
||||
}
|
||||
|
||||
function getKeyStoreForOrg(org) {
|
||||
return hfc.getConfigSetting('keyValueStore') + '_' + org;
|
||||
}
|
||||
|
||||
function newRemotes(names, forPeers, userOrg) {
|
||||
let client = getClientForOrg(userOrg);
|
||||
|
||||
let targets = [];
|
||||
// find the peer that match the names
|
||||
for (let idx in names) {
|
||||
let peerName = names[idx];
|
||||
if (ORGS[userOrg].peers[peerName]) {
|
||||
// found a peer matching the name
|
||||
let data = fs.readFileSync(path.join(__dirname, ORGS[userOrg].peers[peerName]['tls_cacerts']));
|
||||
let grpcOpts = {
|
||||
pem: Buffer.from(data).toString(),
|
||||
'ssl-target-name-override': ORGS[userOrg].peers[peerName]['server-hostname']
|
||||
};
|
||||
|
||||
if (forPeers) {
|
||||
targets.push(client.newPeer(ORGS[userOrg].peers[peerName].requests, grpcOpts));
|
||||
} else {
|
||||
let eh = client.newEventHub();
|
||||
eh.setPeerAddr(ORGS[userOrg].peers[peerName].events, grpcOpts);
|
||||
targets.push(eh);
|
||||
}
|
||||
// The getUserContext call tries to get the user from persistence.
|
||||
// If the user has been saved to persistence then that means the user has
|
||||
// been registered and enrolled. If the user is found in persistence
|
||||
// the call will then assign the user to the client object.
|
||||
if(username) {
|
||||
let user = await client.getUserContext(username, true);
|
||||
if(!user) {
|
||||
throw new Error(util.format('User was not found :', username));
|
||||
} else {
|
||||
logger.debug('User %s was found to be registered and enrolled', username);
|
||||
}
|
||||
}
|
||||
logger.debug('getClientForOrg - ****** END %s %s \n\n', userorg, username)
|
||||
|
||||
if (targets.length === 0) {
|
||||
logger.error(util.format('Failed to find peers matching the names %s', names));
|
||||
}
|
||||
|
||||
return targets;
|
||||
return client;
|
||||
}
|
||||
|
||||
//-------------------------------------//
|
||||
// APIs
|
||||
//-------------------------------------//
|
||||
var getChannelForOrg = function(org) {
|
||||
return channels[org];
|
||||
};
|
||||
|
||||
var getClientForOrg = function(org) {
|
||||
return clients[org];
|
||||
};
|
||||
|
||||
var newPeers = function(names, org) {
|
||||
return newRemotes(names, true, org);
|
||||
};
|
||||
|
||||
var newEventHubs = function(names, org) {
|
||||
return newRemotes(names, false, org);
|
||||
};
|
||||
|
||||
var getMspID = function(org) {
|
||||
logger.debug('Msp ID : ' + ORGS[org].mspid);
|
||||
return ORGS[org].mspid;
|
||||
};
|
||||
|
||||
var getAdminUser = function(userOrg) {
|
||||
var users = hfc.getConfigSetting('admins');
|
||||
var username = users[0].username;
|
||||
var password = users[0].secret;
|
||||
var member;
|
||||
var client = getClientForOrg(userOrg);
|
||||
|
||||
return hfc.newDefaultKeyValueStore({
|
||||
path: getKeyStoreForOrg(getOrgName(userOrg))
|
||||
}).then((store) => {
|
||||
client.setStateStore(store);
|
||||
// clearing the user context before switching
|
||||
client._userContext = null;
|
||||
return client.getUserContext(username, true).then((user) => {
|
||||
if (user && user.isEnrolled()) {
|
||||
logger.info('Successfully loaded member from persistence');
|
||||
return user;
|
||||
} else {
|
||||
let caClient = caClients[userOrg];
|
||||
// need to enroll it with CA server
|
||||
return caClient.enroll({
|
||||
enrollmentID: username,
|
||||
enrollmentSecret: password
|
||||
}).then((enrollment) => {
|
||||
logger.info('Successfully enrolled user \'' + username + '\'');
|
||||
member = new User(username);
|
||||
member.setCryptoSuite(client.getCryptoSuite());
|
||||
return member.setEnrollment(enrollment.key, enrollment.certificate, getMspID(userOrg));
|
||||
}).then(() => {
|
||||
return client.setUserContext(member);
|
||||
}).then(() => {
|
||||
return member;
|
||||
}).catch((err) => {
|
||||
logger.error('Failed to enroll and persist user. Error: ' + err.stack ?
|
||||
err.stack : err);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
var getRegisteredUsers = function(username, userOrg, isJson) {
|
||||
var member;
|
||||
var client = getClientForOrg(userOrg);
|
||||
var enrollmentSecret = null;
|
||||
return hfc.newDefaultKeyValueStore({
|
||||
path: getKeyStoreForOrg(getOrgName(userOrg))
|
||||
}).then((store) => {
|
||||
client.setStateStore(store);
|
||||
// clearing the user context before switching
|
||||
client._userContext = null;
|
||||
return client.getUserContext(username, true).then((user) => {
|
||||
if (user && user.isEnrolled()) {
|
||||
logger.info('Successfully loaded member from persistence');
|
||||
return user;
|
||||
} else {
|
||||
let caClient = caClients[userOrg];
|
||||
return getAdminUser(userOrg).then(function(adminUserObj) {
|
||||
member = adminUserObj;
|
||||
return caClient.register({
|
||||
enrollmentID: username,
|
||||
affiliation: userOrg + '.department1'
|
||||
}, member);
|
||||
}).then((secret) => {
|
||||
enrollmentSecret = secret;
|
||||
logger.debug(username + ' registered successfully');
|
||||
return caClient.enroll({
|
||||
enrollmentID: username,
|
||||
enrollmentSecret: secret
|
||||
});
|
||||
}, (err) => {
|
||||
logger.debug(username + ' failed to register');
|
||||
return '' + err;
|
||||
//return 'Failed to register '+username+'. Error: ' + err.stack ? err.stack : err;
|
||||
}).then((message) => {
|
||||
if (message && typeof message === 'string' && message.includes(
|
||||
'Error:')) {
|
||||
logger.error(username + ' enrollment failed');
|
||||
return message;
|
||||
}
|
||||
logger.debug(username + ' enrolled successfully');
|
||||
|
||||
member = new User(username);
|
||||
member._enrollmentSecret = enrollmentSecret;
|
||||
return member.setEnrollment(message.key, message.certificate, getMspID(userOrg));
|
||||
}).then(() => {
|
||||
client.setUserContext(member);
|
||||
return member;
|
||||
}, (err) => {
|
||||
logger.error(util.format('%s enroll failed: %s', username, err.stack ? err.stack : err));
|
||||
return '' + err;
|
||||
});;
|
||||
}
|
||||
});
|
||||
}).then((user) => {
|
||||
if (isJson && isJson === true) {
|
||||
var response = {
|
||||
success: true,
|
||||
secret: user._enrollmentSecret,
|
||||
message: username + ' enrolled Successfully',
|
||||
};
|
||||
return response;
|
||||
var getRegisteredUser = async function(username, userOrg, isJson) {
|
||||
try {
|
||||
var client = await getClientForOrg(userOrg);
|
||||
logger.debug('Successfully initialized the credential stores');
|
||||
// client can now act as an agent for organization Org1
|
||||
// first check to see if the user is already enrolled
|
||||
var user = await client.getUserContext(username, true);
|
||||
if (user && user.isEnrolled()) {
|
||||
logger.info('Successfully loaded member from persistence');
|
||||
} else {
|
||||
// user was not enrolled, so we will need an admin user object to register
|
||||
var admins = hfc.getConfigSetting('admins');
|
||||
let adminUserObj = await client.setUserContext({username: admins[0].username, password: admins[0].secret});
|
||||
let caClient = client.getCertificateAuthority();
|
||||
let secret = await caClient.register({
|
||||
enrollmentID: username,
|
||||
affiliation: userOrg.toLowerCase() + '.department1'
|
||||
}, adminUserObj);
|
||||
logger.debug('Successfully got the secret for user %s',username);
|
||||
user = await client.setUserContext({username:username, password:secret});
|
||||
logger.debug('Successfully enrolled username %s and setUserContext on the client object', username);
|
||||
}
|
||||
return user;
|
||||
}, (err) => {
|
||||
logger.error(util.format('Failed to get registered user: %s, error: %s', username, err.stack ? err.stack : err));
|
||||
return '' + err;
|
||||
});
|
||||
};
|
||||
|
||||
var getOrgAdmin = function(userOrg) {
|
||||
var admin = ORGS[userOrg].admin;
|
||||
var keyPath = path.join(__dirname, admin.key);
|
||||
var keyPEM = Buffer.from(readAllFiles(keyPath)[0]).toString();
|
||||
var certPath = path.join(__dirname, admin.cert);
|
||||
var certPEM = readAllFiles(certPath)[0].toString();
|
||||
|
||||
var client = getClientForOrg(userOrg);
|
||||
var cryptoSuite = hfc.newCryptoSuite();
|
||||
if (userOrg) {
|
||||
cryptoSuite.setCryptoKeyStore(hfc.newCryptoKeyStore({path: getKeyStoreForOrg(getOrgName(userOrg))}));
|
||||
client.setCryptoSuite(cryptoSuite);
|
||||
if(user && user.isEnrolled) {
|
||||
if (isJson && isJson === true) {
|
||||
var response = {
|
||||
success: true,
|
||||
secret: user._enrollmentSecret,
|
||||
message: username + ' enrolled Successfully',
|
||||
};
|
||||
return response;
|
||||
}
|
||||
} else {
|
||||
throw new Error('User was not enrolled ');
|
||||
}
|
||||
} catch(error) {
|
||||
logger.error('Failed to get registered user: %s with error: %s', username, error.toString());
|
||||
return 'failed '+error.toString();
|
||||
}
|
||||
|
||||
return hfc.newDefaultKeyValueStore({
|
||||
path: getKeyStoreForOrg(getOrgName(userOrg))
|
||||
}).then((store) => {
|
||||
client.setStateStore(store);
|
||||
|
||||
return client.createUser({
|
||||
username: 'peer'+userOrg+'Admin',
|
||||
mspid: getMspID(userOrg),
|
||||
cryptoContent: {
|
||||
privateKeyPEM: keyPEM,
|
||||
signedCertPEM: certPEM
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
var setupChaincodeDeploy = function() {
|
||||
process.env.GOPATH = path.join(__dirname, hfc.getConfigSetting('CC_SRC_PATH'));
|
||||
};
|
||||
|
|
@ -307,13 +126,7 @@ var getLogger = function(moduleName) {
|
|||
return logger;
|
||||
};
|
||||
|
||||
exports.getChannelForOrg = getChannelForOrg;
|
||||
exports.getClientForOrg = getClientForOrg;
|
||||
exports.getLogger = getLogger;
|
||||
exports.setupChaincodeDeploy = setupChaincodeDeploy;
|
||||
exports.getMspID = getMspID;
|
||||
exports.ORGS = ORGS;
|
||||
exports.newPeers = newPeers;
|
||||
exports.newEventHubs = newEventHubs;
|
||||
exports.getRegisteredUsers = getRegisteredUsers;
|
||||
exports.getOrgAdmin = getOrgAdmin;
|
||||
exports.getRegisteredUser = getRegisteredUser;
|
||||
|
|
|
|||
|
|
@ -22,29 +22,36 @@ var helper = require('./helper.js');
|
|||
var logger = helper.getLogger('install-chaincode');
|
||||
var tx_id = null;
|
||||
|
||||
var installChaincode = function(peers, chaincodeName, chaincodePath,
|
||||
chaincodeVersion, chaincodeType, username, org) {
|
||||
logger.debug(
|
||||
'\n============ Install chaincode on organizations ============\n');
|
||||
var installChaincode = async function(peers, chaincodeName, chaincodePath,
|
||||
chaincodeVersion, chaincodeType, username, org_name) {
|
||||
logger.debug('\n\n============ Install chaincode on organizations ============\n');
|
||||
helper.setupChaincodeDeploy();
|
||||
var channel = helper.getChannelForOrg(org);
|
||||
var client = helper.getClientForOrg(org);
|
||||
let error_message = null;
|
||||
try {
|
||||
logger.info('Calling peers in organization "%s" to join the channel', org_name);
|
||||
|
||||
return helper.getOrgAdmin(org).then((user) => {
|
||||
// first setup the client for this org
|
||||
var client = await helper.getClientForOrg(org_name, username);
|
||||
logger.debug('Successfully got the fabric client for the organization "%s"', org_name);
|
||||
|
||||
tx_id = client.newTransactionID(true); //get an admin transactionID
|
||||
var request = {
|
||||
targets: helper.newPeers(peers, org),
|
||||
targets: peers,
|
||||
chaincodePath: chaincodePath,
|
||||
chaincodeId: chaincodeName,
|
||||
chaincodeVersion: chaincodeVersion,
|
||||
chaincodeType: chaincodeType
|
||||
};
|
||||
return client.installChaincode(request);
|
||||
}, (err) => {
|
||||
logger.error('Failed to enroll user \'' + username + '\'. ' + err);
|
||||
throw new Error('Failed to enroll user \'' + username + '\'. ' + err);
|
||||
}).then((results) => {
|
||||
let results = await client.installChaincode(request);
|
||||
// the returned object has both the endorsement results
|
||||
// and the actual proposal, the proposal will be needed
|
||||
// later when we send a transaction to the orederer
|
||||
var proposalResponses = results[0];
|
||||
var proposal = results[1];
|
||||
|
||||
// lets have a look at the responses to see if they are
|
||||
// all good, if good they will also include signatures
|
||||
// required to be committed
|
||||
var all_good = true;
|
||||
for (var i in proposalResponses) {
|
||||
let one_good = false;
|
||||
|
|
@ -53,28 +60,34 @@ var installChaincode = function(peers, chaincodeName, chaincodePath,
|
|||
one_good = true;
|
||||
logger.info('install proposal was good');
|
||||
} else {
|
||||
logger.error('install proposal was bad');
|
||||
logger.error('install proposal was bad %j',proposalResponses.toJSON());
|
||||
}
|
||||
all_good = all_good & one_good;
|
||||
}
|
||||
if (all_good) {
|
||||
logger.info(util.format(
|
||||
'Successfully sent install Proposal and received ProposalResponse: Status - %s',
|
||||
proposalResponses[0].response.status));
|
||||
logger.debug('\nSuccessfully Installed chaincode on organization ' + org +
|
||||
'\n');
|
||||
return 'Successfully Installed chaincode on organization ' + org;
|
||||
logger.info('Successfully sent install Proposal and received ProposalResponse');
|
||||
} else {
|
||||
logger.error(
|
||||
'Failed to send install Proposal or receive valid response. Response null or status is not 200. exiting...'
|
||||
);
|
||||
return 'Failed to send install Proposal or receive valid response. Response null or status is not 200. exiting...';
|
||||
error_message = 'Failed to send install Proposal or receive valid response. Response null or status is not 200'
|
||||
logger.error(error_message);
|
||||
}
|
||||
}, (err) => {
|
||||
logger.error('Failed to send install proposal due to error: ' + err.stack ?
|
||||
err.stack : err);
|
||||
throw new Error('Failed to send install proposal due to error: ' + err.stack ?
|
||||
err.stack : err);
|
||||
});
|
||||
} catch(error) {
|
||||
logger.error('Failed to install due to error: ' + error.stack ? error.stack : error);
|
||||
error_message = error.toString();
|
||||
}
|
||||
|
||||
if (!error_message) {
|
||||
let message = util.format('Successfully install chaincode');
|
||||
logger.info(message);
|
||||
// build a response to send back to the REST caller
|
||||
let response = {
|
||||
success: true,
|
||||
message: message
|
||||
};
|
||||
return response;
|
||||
} else {
|
||||
let message = util.format('Failed to install due to:%s',error_message);
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
};
|
||||
exports.installChaincode = installChaincode;
|
||||
|
|
|
|||
|
|
@ -18,32 +18,31 @@ var path = require('path');
|
|||
var fs = require('fs');
|
||||
var util = require('util');
|
||||
var hfc = require('fabric-client');
|
||||
var Peer = require('fabric-client/lib/Peer.js');
|
||||
var EventHub = require('fabric-client/lib/EventHub.js');
|
||||
var helper = require('./helper.js');
|
||||
var logger = helper.getLogger('instantiate-chaincode');
|
||||
var ORGS = hfc.getConfigSetting('network-config');
|
||||
var tx_id = null;
|
||||
var eh = null;
|
||||
|
||||
var instantiateChaincode = function(channelName, chaincodeName, chaincodeVersion, functionName, chaincodeType,
|
||||
args, username, org) {
|
||||
logger.debug('\n============ Instantiate chaincode on organization ' + org +
|
||||
var instantiateChaincode = async function(channelName, chaincodeName, chaincodeVersion, functionName, chaincodeType, args, username, org_name) {
|
||||
logger.debug('\n\n============ Instantiate chaincode on channel ' + channelName +
|
||||
' ============\n');
|
||||
var error_message = null;
|
||||
var eventhubs_in_use = [];
|
||||
try {
|
||||
// first setup the client for this org
|
||||
var client = await helper.getClientForOrg(org_name, username);
|
||||
logger.debug('Successfully got the fabric client for the organization "%s"', org_name);
|
||||
var channel = client.getChannel(channelName);
|
||||
if(!channel) {
|
||||
let message = util.format('Channel %s was not defined in the connection profile', channelName);
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
var tx_id = client.newTransactionID(true); // Get an admin based transactionID
|
||||
// An admin based transactionID will
|
||||
// indicate that admin identity should
|
||||
// be used to sign the proposal request.
|
||||
// will need the transaction ID string for the event registration later
|
||||
var deployId = tx_id.getTransactionID();
|
||||
|
||||
var channel = helper.getChannelForOrg(org);
|
||||
var client = helper.getClientForOrg(org);
|
||||
|
||||
return helper.getOrgAdmin(org).then((user) => {
|
||||
// read the config block from the orderer for the channel
|
||||
// and initialize the verify MSPs based on the participating
|
||||
// organizations
|
||||
return channel.initialize();
|
||||
}, (err) => {
|
||||
logger.error('Failed to enroll user \'' + username + '\'. ' + err);
|
||||
throw new Error('Failed to enroll user \'' + username + '\'. ' + err);
|
||||
}).then((success) => {
|
||||
tx_id = client.newTransactionID();
|
||||
// send proposal to endorser
|
||||
var request = {
|
||||
chaincodeId: chaincodeName,
|
||||
|
|
@ -56,13 +55,17 @@ var instantiateChaincode = function(channelName, chaincodeName, chaincodeVersion
|
|||
if (functionName)
|
||||
request.fcn = functionName;
|
||||
|
||||
return channel.sendInstantiateProposal(request);
|
||||
}, (err) => {
|
||||
logger.error('Failed to initialize the channel');
|
||||
throw new Error('Failed to initialize the channel');
|
||||
}).then((results) => {
|
||||
let results = await channel.sendInstantiateProposal(request, 60000); //instantiate takes much longer
|
||||
|
||||
// the returned object has both the endorsement results
|
||||
// and the actual proposal, the proposal will be needed
|
||||
// later when we send a transaction to the orderer
|
||||
var proposalResponses = results[0];
|
||||
var proposal = results[1];
|
||||
|
||||
// lets have a look at the responses to see if they are
|
||||
// all good, if good they will also include signatures
|
||||
// required to be committed
|
||||
var all_good = true;
|
||||
for (var i in proposalResponses) {
|
||||
let one_good = false;
|
||||
|
|
@ -75,89 +78,118 @@ var instantiateChaincode = function(channelName, chaincodeName, chaincodeVersion
|
|||
}
|
||||
all_good = all_good & one_good;
|
||||
}
|
||||
|
||||
if (all_good) {
|
||||
logger.info(util.format(
|
||||
'Successfully sent Proposal and received ProposalResponse: Status - %s, message - "%s", metadata - "%s", endorsement signature: %s',
|
||||
proposalResponses[0].response.status, proposalResponses[0].response.message,
|
||||
proposalResponses[0].response.payload, proposalResponses[0].endorsement
|
||||
.signature));
|
||||
var request = {
|
||||
|
||||
// tell each peer to join and wait for the event hub of each peer to tell us
|
||||
// that the channel has been created on each peer
|
||||
var promises = [];
|
||||
let event_hubs = client.getEventHubsForOrg(org_name);
|
||||
logger.debug('found %s eventhubs for this organization %s',event_hubs.length, org_name);
|
||||
event_hubs.forEach((eh) => {
|
||||
let instantiateEventPromise = new Promise((resolve, reject) => {
|
||||
logger.debug('instantiateEventPromise - setting up event');
|
||||
let event_timeout = setTimeout(() => {
|
||||
let message = 'REQUEST_TIMEOUT:' + eh._ep._endpoint.addr;
|
||||
logger.error(message);
|
||||
eh.disconnect();
|
||||
reject(new Error(message));
|
||||
}, 60000);
|
||||
eh.registerTxEvent(deployId, (tx, code) => {
|
||||
logger.info('The chaincode instantiate transaction has been committed on peer %s',eh._ep._endpoint.addr);
|
||||
clearTimeout(event_timeout);
|
||||
eh.unregisterTxEvent(deployId);
|
||||
|
||||
if (code !== 'VALID') {
|
||||
let message = until.format('The chaincode instantiate transaction was invalid, code:%s',code);
|
||||
logger.error(message);
|
||||
reject(new Error(message));
|
||||
} else {
|
||||
let message = 'The chaincode instantiate transaction was valid.';
|
||||
logger.info(message);
|
||||
resolve(message);
|
||||
}
|
||||
}, (err) => {
|
||||
clearTimeout(event_timeout);
|
||||
eh.unregisterTxEvent(deployId);
|
||||
let message = 'Problem setting up the event hub :'+ err.toString();
|
||||
logger.error(message);
|
||||
reject(new Error(message));
|
||||
});
|
||||
});
|
||||
promises.push(instantiateEventPromise);
|
||||
eh.connect();
|
||||
eventhubs_in_use.push(eh);
|
||||
});
|
||||
|
||||
var orderer_request = {
|
||||
txId: tx_id, //must includethe transaction id so that the outbound
|
||||
// transaction to the orderer will be signed by the admin
|
||||
// id as was the proposal above, notice that transactionID
|
||||
// generated above was based on the admin id not userContext.
|
||||
proposalResponses: proposalResponses,
|
||||
proposal: proposal
|
||||
};
|
||||
// set the transaction listener and set a timeout of 30sec
|
||||
// if the transaction did not get committed within the timeout period,
|
||||
// fail the test
|
||||
var deployId = tx_id.getTransactionID();
|
||||
var sendPromise = channel.sendTransaction(orderer_request);
|
||||
// put the send to the orderer last so that the events get registered and
|
||||
// are ready for the orderering and committing
|
||||
promises.push(sendPromise);
|
||||
let results = await Promise.all(promises);
|
||||
logger.debug(util.format('------->>> R E S P O N S E : %j', results));
|
||||
let response = results.pop(); // orderer results are last in the results
|
||||
if (response.status === 'SUCCESS') {
|
||||
logger.info('Successfully sent transaction to the orderer.');
|
||||
} else {
|
||||
error_message = util.format('Failed to order the transaction. Error code: %s',response.status);
|
||||
logger.debug(error_message);
|
||||
}
|
||||
|
||||
eh = client.newEventHub();
|
||||
let data = fs.readFileSync(path.join(__dirname, ORGS[org].peers['peer1'][
|
||||
'tls_cacerts'
|
||||
]));
|
||||
eh.setPeerAddr(ORGS[org].peers['peer1']['events'], {
|
||||
pem: Buffer.from(data).toString(),
|
||||
'ssl-target-name-override': ORGS[org].peers['peer1']['server-hostname']
|
||||
});
|
||||
eh.connect();
|
||||
|
||||
let txPromise = new Promise((resolve, reject) => {
|
||||
let handle = setTimeout(() => {
|
||||
eh.disconnect();
|
||||
reject();
|
||||
}, 30000);
|
||||
|
||||
eh.registerTxEvent(deployId, (tx, code) => {
|
||||
logger.info(
|
||||
'The chaincode instantiate transaction has been committed on peer ' +
|
||||
eh._ep._endpoint.addr);
|
||||
clearTimeout(handle);
|
||||
eh.unregisterTxEvent(deployId);
|
||||
eh.disconnect();
|
||||
|
||||
if (code !== 'VALID') {
|
||||
logger.error('The chaincode instantiate transaction was invalid, code = ' + code);
|
||||
reject();
|
||||
} else {
|
||||
logger.info('The chaincode instantiate transaction was valid.');
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
var sendPromise = channel.sendTransaction(request);
|
||||
return Promise.all([sendPromise].concat([txPromise])).then((results) => {
|
||||
logger.debug('Event promise all complete and testing complete');
|
||||
return results[0]; // the first returned value is from the 'sendPromise' which is from the 'sendTransaction()' call
|
||||
}).catch((err) => {
|
||||
logger.error(
|
||||
util.format('Failed to send instantiate transaction and get notifications within the timeout period. %s', err)
|
||||
);
|
||||
return 'Failed to send instantiate transaction and get notifications within the timeout period.';
|
||||
});
|
||||
// now see what each of the event hubs reported
|
||||
for(let i in results) {
|
||||
let event_hub_result = results[i];
|
||||
let event_hub = event_hubs[i];
|
||||
logger.debug('Event results for event hub :%s',event_hub._ep._endpoint.addr);
|
||||
if(typeof event_hub_result === 'string') {
|
||||
logger.debug(event_hub_result);
|
||||
} else {
|
||||
if(!error_message) error_message = event_hub_result.toString();
|
||||
logger.debug(event_hub_result.toString());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logger.error(
|
||||
'Failed to send instantiate Proposal or receive valid response. Response null or status is not 200. exiting...'
|
||||
);
|
||||
return 'Failed to send instantiate Proposal or receive valid response. Response null or status is not 200. exiting...';
|
||||
error_message = util.format('Failed to send Proposal and receive all good ProposalResponse');
|
||||
logger.debug(error_message);
|
||||
}
|
||||
}, (err) => {
|
||||
logger.error('Failed to send instantiate proposal due to error: ' + err.stack ?
|
||||
err.stack : err);
|
||||
return 'Failed to send instantiate proposal due to error: ' + err.stack ?
|
||||
err.stack : err;
|
||||
}).then((response) => {
|
||||
if (response.status === 'SUCCESS') {
|
||||
logger.info('Successfully sent transaction to the orderer.');
|
||||
return 'Chaincode Instantiation is SUCCESS';
|
||||
} else {
|
||||
logger.error('Failed to order the transaction. Error code: ' + response.status);
|
||||
return 'Failed to order the transaction. Error code: ' + response.status;
|
||||
}
|
||||
}, (err) => {
|
||||
logger.error('Failed to send instantiate due to error: ' + err.stack ? err
|
||||
.stack : err);
|
||||
return 'Failed to send instantiate due to error: ' + err.stack ? err.stack :
|
||||
err;
|
||||
} catch (error) {
|
||||
logger.error('Failed to send instantiate due to error: ' + error.stack ? error.stack : error);
|
||||
error_message = error.toString();
|
||||
}
|
||||
|
||||
// need to shutdown open event streams
|
||||
eventhubs_in_use.forEach((eh) => {
|
||||
eh.disconnect();
|
||||
});
|
||||
|
||||
if (!error_message) {
|
||||
let message = util.format(
|
||||
'Successfully instantiate chaingcode in organization %s to the channel \'%s\'',
|
||||
org_name, channelName);
|
||||
logger.info(message);
|
||||
// build a response to send back to the REST caller
|
||||
let response = {
|
||||
success: true,
|
||||
message: message
|
||||
};
|
||||
return response;
|
||||
} else {
|
||||
let message = util.format('Failed to instantiate. cause:%s',error_message);
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
};
|
||||
exports.instantiateChaincode = instantiateChaincode;
|
||||
|
|
|
|||
|
|
@ -18,22 +18,28 @@ var path = require('path');
|
|||
var fs = require('fs');
|
||||
var util = require('util');
|
||||
var hfc = require('fabric-client');
|
||||
var Peer = require('fabric-client/lib/Peer.js');
|
||||
var helper = require('./helper.js');
|
||||
var logger = helper.getLogger('invoke-chaincode');
|
||||
var EventHub = require('fabric-client/lib/EventHub.js');
|
||||
var ORGS = hfc.getConfigSetting('network-config');
|
||||
|
||||
var invokeChaincode = function(peerNames, channelName, chaincodeName, fcn, args, username, org) {
|
||||
logger.debug(util.format('\n============ invoke transaction on organization %s ============\n', org));
|
||||
var client = helper.getClientForOrg(org);
|
||||
var channel = helper.getChannelForOrg(org);
|
||||
var targets = (peerNames) ? helper.newPeers(peerNames, org) : undefined;
|
||||
var tx_id = null;
|
||||
var invokeChaincode = async function(peerNames, channelName, chaincodeName, fcn, args, username, org_name) {
|
||||
logger.debug(util.format('\n============ invoke transaction on channel %s ============\n', channelName));
|
||||
var error_message = null;
|
||||
var eventhubs_in_use = [];
|
||||
var tx_id_string = null;
|
||||
try {
|
||||
// first setup the client for this org
|
||||
var client = await helper.getClientForOrg(org_name, username);
|
||||
logger.debug('Successfully got the fabric client for the organization "%s"', org_name);
|
||||
var channel = client.getChannel(channelName);
|
||||
if(!channel) {
|
||||
let message = util.format('Channel %s was not defined in the connection profile', channelName);
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
var tx_id = client.newTransactionID();
|
||||
// will need the transaction ID string for the event registration later
|
||||
tx_id_string = tx_id.getTransactionID();
|
||||
|
||||
return helper.getRegisteredUsers(username, org).then((user) => {
|
||||
tx_id = client.newTransactionID();
|
||||
logger.debug(util.format('Sending transaction "%j"', tx_id));
|
||||
// send proposal to endorser
|
||||
var request = {
|
||||
chaincodeId: chaincodeName,
|
||||
|
|
@ -43,115 +49,133 @@ var invokeChaincode = function(peerNames, channelName, chaincodeName, fcn, args,
|
|||
txId: tx_id
|
||||
};
|
||||
|
||||
if (targets)
|
||||
request.targets = targets;
|
||||
let results = await channel.sendTransactionProposal(request);
|
||||
|
||||
return channel.sendTransactionProposal(request);
|
||||
}, (err) => {
|
||||
logger.error('Failed to enroll user \'' + username + '\'. ' + err);
|
||||
throw new Error('Failed to enroll user \'' + username + '\'. ' + err);
|
||||
}).then((results) => {
|
||||
// the returned object has both the endorsement results
|
||||
// and the actual proposal, the proposal will be needed
|
||||
// later when we send a transaction to the orderer
|
||||
var proposalResponses = results[0];
|
||||
var proposal = results[1];
|
||||
|
||||
// lets have a look at the responses to see if they are
|
||||
// all good, if good they will also include signatures
|
||||
// required to be committed
|
||||
var all_good = true;
|
||||
for (var i in proposalResponses) {
|
||||
let one_good = false;
|
||||
if (proposalResponses && proposalResponses[i].response &&
|
||||
proposalResponses[i].response.status === 200) {
|
||||
one_good = true;
|
||||
logger.info('transaction proposal was good');
|
||||
logger.info('invoke chaincode proposal was good');
|
||||
} else {
|
||||
logger.error('transaction proposal was bad');
|
||||
logger.error('invoke chaincode proposal was bad');
|
||||
}
|
||||
all_good = all_good & one_good;
|
||||
}
|
||||
|
||||
if (all_good) {
|
||||
logger.debug(util.format(
|
||||
logger.info(util.format(
|
||||
'Successfully sent Proposal and received ProposalResponse: Status - %s, message - "%s", metadata - "%s", endorsement signature: %s',
|
||||
proposalResponses[0].response.status, proposalResponses[0].response.message,
|
||||
proposalResponses[0].response.payload, proposalResponses[0].endorsement
|
||||
.signature));
|
||||
var request = {
|
||||
|
||||
// tell each peer to join and wait for the event hub of each peer to tell us
|
||||
// that the channel has been created on each peer
|
||||
var promises = [];
|
||||
let event_hubs = client.getEventHubsForOrg(org_name);
|
||||
event_hubs.forEach((eh) => {
|
||||
logger.debug('invokeEventPromise - setting up event');
|
||||
let invokeEventPromise = new Promise((resolve, reject) => {
|
||||
let event_timeout = setTimeout(() => {
|
||||
let message = 'REQUEST_TIMEOUT:' + eh._ep._endpoint.addr;
|
||||
logger.error(message);
|
||||
eh.disconnect();
|
||||
reject(new Error(message));
|
||||
}, 3000);
|
||||
eh.registerTxEvent(tx_id_string, (tx, code) => {
|
||||
logger.info('The chaincode invoke chaincode transaction has been committed on peer %s',eh._ep._endpoint.addr);
|
||||
clearTimeout(event_timeout);
|
||||
eh.unregisterTxEvent(tx_id_string);
|
||||
|
||||
if (code !== 'VALID') {
|
||||
let message = until.format('The invoke chaincode transaction was invalid, code:%s',code);
|
||||
logger.error(message);
|
||||
reject(new Error(message));
|
||||
} else {
|
||||
let message = 'The invoke chaincode transaction was valid.';
|
||||
logger.info(message);
|
||||
resolve(message);
|
||||
}
|
||||
}, (err) => {
|
||||
clearTimeout(event_timeout);
|
||||
eh.unregisterTxEvent(tx_id_string);
|
||||
let message = 'Problem setting up the event hub :'+ err.toString();
|
||||
logger.error(message);
|
||||
reject(new Error(message));
|
||||
});
|
||||
});
|
||||
promises.push(invokeEventPromise);
|
||||
eh.connect();
|
||||
eventhubs_in_use.push(eh);
|
||||
});
|
||||
|
||||
var orderer_request = {
|
||||
txId: tx_id,
|
||||
proposalResponses: proposalResponses,
|
||||
proposal: proposal
|
||||
};
|
||||
// set the transaction listener and set a timeout of 30sec
|
||||
// if the transaction did not get committed within the timeout period,
|
||||
// fail the test
|
||||
var transactionID = tx_id.getTransactionID();
|
||||
var eventPromises = [];
|
||||
|
||||
if (!peerNames) {
|
||||
peerNames = channel.getPeers().map(function(peer) {
|
||||
return peer.getName();
|
||||
});
|
||||
var sendPromise = channel.sendTransaction(orderer_request);
|
||||
// put the send to the orderer last so that the events get registered and
|
||||
// are ready for the orderering and committing
|
||||
promises.push(sendPromise);
|
||||
let results = await Promise.all(promises);
|
||||
logger.debug(util.format('------->>> R E S P O N S E : %j', results));
|
||||
let response = results.pop(); // orderer results are last in the results
|
||||
if (response.status === 'SUCCESS') {
|
||||
logger.info('Successfully sent transaction to the orderer.');
|
||||
} else {
|
||||
error_message = util.format('Failed to order the transaction. Error code: %s',response.status);
|
||||
logger.debug(error_message);
|
||||
}
|
||||
|
||||
var eventhubs = helper.newEventHubs(peerNames, org);
|
||||
for (let key in eventhubs) {
|
||||
let eh = eventhubs[key];
|
||||
eh.connect();
|
||||
|
||||
let txPromise = new Promise((resolve, reject) => {
|
||||
let handle = setTimeout(() => {
|
||||
eh.disconnect();
|
||||
reject();
|
||||
}, 30000);
|
||||
|
||||
eh.registerTxEvent(transactionID, (tx, code) => {
|
||||
clearTimeout(handle);
|
||||
eh.unregisterTxEvent(transactionID);
|
||||
eh.disconnect();
|
||||
|
||||
if (code !== 'VALID') {
|
||||
logger.error(
|
||||
'The balance transfer transaction was invalid, code = ' + code);
|
||||
reject();
|
||||
} else {
|
||||
logger.info(
|
||||
'The balance transfer transaction has been committed on peer ' +
|
||||
eh._ep._endpoint.addr);
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
eventPromises.push(txPromise);
|
||||
};
|
||||
var sendPromise = channel.sendTransaction(request);
|
||||
return Promise.all([sendPromise].concat(eventPromises)).then((results) => {
|
||||
logger.debug(' event promise all complete and testing complete');
|
||||
return results[0]; // the first returned value is from the 'sendPromise' which is from the 'sendTransaction()' call
|
||||
}).catch((err) => {
|
||||
logger.error(
|
||||
'Failed to send transaction and get notifications within the timeout period.'
|
||||
);
|
||||
return 'Failed to send transaction and get notifications within the timeout period.';
|
||||
});
|
||||
// now see what each of the event hubs reported
|
||||
for(let i in results) {
|
||||
let event_hub_result = results[i];
|
||||
let event_hub = event_hubs[i];
|
||||
logger.debug('Event results for event hub :%s',event_hub._ep._endpoint.addr);
|
||||
if(typeof event_hub_result === 'string') {
|
||||
logger.debug(event_hub_result);
|
||||
} else {
|
||||
if(!error_message) error_message = event_hub_result.toString();
|
||||
logger.debug(event_hub_result.toString());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logger.error(
|
||||
'Failed to send Proposal or receive valid response. Response null or status is not 200. exiting...'
|
||||
);
|
||||
return 'Failed to send Proposal or receive valid response. Response null or status is not 200. exiting...';
|
||||
error_message = util.format('Failed to send Proposal and receive all good ProposalResponse');
|
||||
logger.debug(error_message);
|
||||
}
|
||||
}, (err) => {
|
||||
logger.error('Failed to send proposal due to error: ' + err.stack ? err.stack :
|
||||
err);
|
||||
return 'Failed to send proposal due to error: ' + err.stack ? err.stack :
|
||||
err;
|
||||
}).then((response) => {
|
||||
if (response.status === 'SUCCESS') {
|
||||
logger.info('Successfully sent transaction to the orderer.');
|
||||
return tx_id.getTransactionID();
|
||||
} else {
|
||||
logger.error('Failed to order the transaction. Error code: ' + response.status);
|
||||
return 'Failed to order the transaction. Error code: ' + response.status;
|
||||
}
|
||||
}, (err) => {
|
||||
logger.error('Failed to send transaction due to error: ' + err.stack ? err
|
||||
.stack : err);
|
||||
return 'Failed to send transaction due to error: ' + err.stack ? err.stack :
|
||||
err;
|
||||
} catch (error) {
|
||||
logger.error('Failed to invoke due to error: ' + error.stack ? error.stack : error);
|
||||
error_message = error.toString();
|
||||
}
|
||||
|
||||
// need to shutdown open event streams
|
||||
eventhubs_in_use.forEach((eh) => {
|
||||
eh.disconnect();
|
||||
});
|
||||
|
||||
if (!error_message) {
|
||||
let message = util.format(
|
||||
'Successfully invoked the chaincode %s to the channel \'%s\'',
|
||||
org_name, channelName);
|
||||
logger.info(message);
|
||||
return tx_id_string;
|
||||
} else {
|
||||
let message = util.format('Failed to invoke chaincode. cause:%s',error_message);
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
};
|
||||
|
||||
exports.invokeChaincode = invokeChaincode;
|
||||
|
|
|
|||
|
|
@ -17,123 +17,144 @@ var util = require('util');
|
|||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
|
||||
var Peer = require('fabric-client/lib/Peer.js');
|
||||
var EventHub = require('fabric-client/lib/EventHub.js');
|
||||
var tx_id = null;
|
||||
var nonce = null;
|
||||
var config = require('../config.json');
|
||||
var helper = require('./helper.js');
|
||||
var logger = helper.getLogger('Join-Channel');
|
||||
//helper.hfc.addConfigFile(path.join(__dirname, 'network-config.json'));
|
||||
var ORGS = helper.ORGS;
|
||||
var allEventhubs = [];
|
||||
|
||||
//
|
||||
//Attempt to send a request to the orderer with the sendCreateChain method
|
||||
//
|
||||
var joinChannel = function(channelName, peers, username, org) {
|
||||
// on process exit, always disconnect the event hub
|
||||
var closeConnections = function(isSuccess) {
|
||||
if (isSuccess) {
|
||||
logger.debug('\n============ Join Channel is SUCCESS ============\n');
|
||||
} else {
|
||||
logger.debug('\n!!!!!!!! ERROR: Join Channel FAILED !!!!!!!!\n');
|
||||
/*
|
||||
* Have an organization join a channel
|
||||
*/
|
||||
var joinChannel = async function(channel_name, peers, username, org_name) {
|
||||
logger.debug('\n\n============ Join Channel start ============\n')
|
||||
var error_message = null;
|
||||
var all_eventhubs = [];
|
||||
try {
|
||||
logger.info('Calling peers in organization "%s" to join the channel', org_name);
|
||||
|
||||
// first setup the client for this org
|
||||
var client = await helper.getClientForOrg(org_name, username);
|
||||
logger.debug('Successfully got the fabric client for the organization "%s"', org_name);
|
||||
var channel = client.getChannel(channel_name);
|
||||
if(!channel) {
|
||||
let message = util.format('Channel %s was not defined in the connection profile', channel_name);
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
logger.debug('');
|
||||
for (var key in allEventhubs) {
|
||||
var eventhub = allEventhubs[key];
|
||||
if (eventhub && eventhub.isconnected()) {
|
||||
//logger.debug('Disconnecting the event hub');
|
||||
eventhub.disconnect();
|
||||
}
|
||||
}
|
||||
};
|
||||
//logger.debug('\n============ Join Channel ============\n')
|
||||
logger.info(util.format(
|
||||
'Calling peers in organization "%s" to join the channel', org));
|
||||
|
||||
var client = helper.getClientForOrg(org);
|
||||
var channel = helper.getChannelForOrg(org);
|
||||
var eventhubs = [];
|
||||
|
||||
return helper.getOrgAdmin(org).then((admin) => {
|
||||
logger.info(util.format('received member object for admin of the organization "%s": ', org));
|
||||
tx_id = client.newTransactionID();
|
||||
// next step is to get the genesis_block from the orderer,
|
||||
// the starting point for the channel that we want to join
|
||||
let request = {
|
||||
txId : tx_id
|
||||
txId : client.newTransactionID(true) //get an admin based transactionID
|
||||
};
|
||||
let genesis_block = await channel.getGenesisBlock(request);
|
||||
|
||||
return channel.getGenesisBlock(request);
|
||||
}).then((genesis_block) => {
|
||||
tx_id = client.newTransactionID();
|
||||
var request = {
|
||||
targets: helper.newPeers(peers, org),
|
||||
txId: tx_id,
|
||||
block: genesis_block
|
||||
};
|
||||
|
||||
eventhubs = helper.newEventHubs(peers, org);
|
||||
for (let key in eventhubs) {
|
||||
let eh = eventhubs[key];
|
||||
eh.connect();
|
||||
allEventhubs.push(eh);
|
||||
}
|
||||
|
||||
var eventPromises = [];
|
||||
eventhubs.forEach((eh) => {
|
||||
let txPromise = new Promise((resolve, reject) => {
|
||||
let handle = setTimeout(reject, parseInt(config.eventWaitTime));
|
||||
eh.registerBlockEvent((block) => {
|
||||
clearTimeout(handle);
|
||||
// in real-world situations, a peer may have more than one channels so
|
||||
// we must check that this block came from the channel we asked the peer to join
|
||||
// tell each peer to join and wait for the event hub of each peer to tell us
|
||||
// that the channel has been created on each peer
|
||||
var promises = [];
|
||||
var block_registration_numbers = [];
|
||||
let event_hubs = client.getEventHubsForOrg(org_name);
|
||||
event_hubs.forEach((eh) => {
|
||||
let configBlockPromise = new Promise((resolve, reject) => {
|
||||
let event_timeout = setTimeout(() => {
|
||||
let message = 'REQUEST_TIMEOUT:' + eh._ep._endpoint.addr;
|
||||
logger.error(message);
|
||||
eh.disconnect();
|
||||
reject(new Error(message));
|
||||
}, 60000);
|
||||
let block_registration_number = eh.registerBlockEvent((block) => {
|
||||
clearTimeout(event_timeout);
|
||||
// a peer may have more than one channel so
|
||||
// we must check that this block came from the channel we
|
||||
// asked the peer to join
|
||||
if (block.data.data.length === 1) {
|
||||
// Config block must only contain one transaction
|
||||
var channel_header = block.data.data[0].payload.header.channel_header;
|
||||
if (channel_header.channel_id === channelName) {
|
||||
resolve();
|
||||
}
|
||||
else {
|
||||
reject();
|
||||
if (channel_header.channel_id === channel_name) {
|
||||
let message = util.format('EventHub % has reported a block update for channel %s',eh._ep._endpoint.addr,channel_name);
|
||||
logger.info(message)
|
||||
resolve(message);
|
||||
} else {
|
||||
let message = util.format('Unknown channel block event received from %s',eh._ep._endpoint.addr);
|
||||
logger.error(message);
|
||||
reject(new Error(message));
|
||||
}
|
||||
}
|
||||
}, (err) => {
|
||||
clearTimeout(event_timeout);
|
||||
let message = 'Problem setting up the event hub :'+ err.toString();
|
||||
logger.error(message);
|
||||
reject(new Error(message));
|
||||
});
|
||||
// save the registration handle so able to deregister
|
||||
block_registration_numbers.push(block_registration_number);
|
||||
all_eventhubs.push(eh); //save for later so that we can shut it down
|
||||
});
|
||||
eventPromises.push(txPromise);
|
||||
promises.push(configBlockPromise);
|
||||
eh.connect(); //this opens the event stream that must be shutdown at some point with a disconnect()
|
||||
});
|
||||
let sendPromise = channel.joinChannel(request);
|
||||
return Promise.all([sendPromise].concat(eventPromises));
|
||||
}, (err) => {
|
||||
logger.error('Failed to enroll user \'' + username + '\' due to error: ' +
|
||||
err.stack ? err.stack : err);
|
||||
throw new Error('Failed to enroll user \'' + username +
|
||||
'\' due to error: ' + err.stack ? err.stack : err);
|
||||
}).then((results) => {
|
||||
|
||||
let join_request = {
|
||||
targets: peers, //using the peer names which only is allowed when a connection profile is loaded
|
||||
txId: client.newTransactionID(true), //get an admin based transactionID
|
||||
block: genesis_block
|
||||
};
|
||||
let join_promise = channel.joinChannel(join_request);
|
||||
promises.push(join_promise);
|
||||
let results = await Promise.all(promises);
|
||||
logger.debug(util.format('Join Channel R E S P O N S E : %j', results));
|
||||
if (results[0] && results[0][0] && results[0][0].response && results[0][0]
|
||||
.response.status == 200) {
|
||||
logger.info(util.format(
|
||||
'Successfully joined peers in organization %s to the channel \'%s\'',
|
||||
org, channelName));
|
||||
closeConnections(true);
|
||||
let response = {
|
||||
success: true,
|
||||
message: util.format(
|
||||
'Successfully joined peers in organization %s to the channel \'%s\'',
|
||||
org, channelName)
|
||||
};
|
||||
return response;
|
||||
} else {
|
||||
logger.error(' Failed to join channel');
|
||||
closeConnections();
|
||||
throw new Error('Failed to join channel');
|
||||
|
||||
// lets check the results of sending to the peers which is
|
||||
// last in the results array
|
||||
let peers_results = results.pop();
|
||||
// then each peer results
|
||||
for(let i in peers_results) {
|
||||
let peer_result = peers_results[i];
|
||||
if(peer_result.response && peer_result.response.status == 200) {
|
||||
logger.info('Successfully joined peer to the channel %s',channel_name);
|
||||
} else {
|
||||
let message = util.format('Failed to joined peer to the channel %s',channel_name);
|
||||
error_message = message;
|
||||
logger.error(message);
|
||||
}
|
||||
}
|
||||
}, (err) => {
|
||||
logger.error('Failed to join channel due to error: ' + err.stack ? err.stack :
|
||||
err);
|
||||
closeConnections();
|
||||
throw new Error('Failed to join channel due to error: ' + err.stack ? err.stack :
|
||||
err);
|
||||
// now see what each of the event hubs reported
|
||||
for(let i in results) {
|
||||
let event_hub_result = results[i];
|
||||
let event_hub = event_hubs[i];
|
||||
let block_registration_number = block_registration_numbers[i];
|
||||
logger.debug('Event results for event hub :%s',event_hub._ep._endpoint.addr);
|
||||
if(typeof event_hub_result === 'string') {
|
||||
logger.debug(event_hub_result);
|
||||
} else {
|
||||
if(!error_message) error_message = event_hub_result.toString();
|
||||
logger.debug(event_hub_result.toString());
|
||||
}
|
||||
event_hub.unregisterBlockEvent(block_registration_number);
|
||||
}
|
||||
} catch(error) {
|
||||
logger.error('Failed to join channel due to error: ' + error.stack ? error.stack : error);
|
||||
error_message = error.toString();
|
||||
}
|
||||
|
||||
// need to shutdown open event streams
|
||||
all_eventhubs.forEach((eh) => {
|
||||
eh.disconnect();
|
||||
});
|
||||
|
||||
if (!error_message) {
|
||||
let message = util.format(
|
||||
'Successfully joined peers in organization %s to the channel:%s',
|
||||
org_name, channel_name);
|
||||
logger.info(message);
|
||||
// build a response to send back to the REST caller
|
||||
let response = {
|
||||
success: true,
|
||||
message: message
|
||||
};
|
||||
return response;
|
||||
} else {
|
||||
let message = util.format('Failed to join all peers to channel. cause:%s',error_message);
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
};
|
||||
exports.joinChannel = joinChannel;
|
||||
|
|
|
|||
|
|
@ -1,55 +0,0 @@
|
|||
{
|
||||
"network-config": {
|
||||
"orderer": {
|
||||
"url": "grpc://ec2-13-59-99-140.us-east-2.compute.amazonaws.com:7050",
|
||||
"server-hostname": "orderer.example.com",
|
||||
"tls_cacerts": "../artifacts/channel/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt"
|
||||
},
|
||||
"org1": {
|
||||
"name": "peerOrg1",
|
||||
"mspid": "Org1MSP",
|
||||
"ca": "https://ec2-13-59-99-140.us-east-2.compute.amazonaws.com:7054",
|
||||
"peers": {
|
||||
"peer1": {
|
||||
"requests": "grpc://ec2-13-59-99-140.us-east-2.compute.amazonaws.com:7051",
|
||||
"events": "grpc://ec2-13-59-99-140.us-east-2.compute.amazonaws.com:7053",
|
||||
"server-hostname": "peer0.org1.example.com",
|
||||
"tls_cacerts": "../artifacts/channel/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt"
|
||||
},
|
||||
"peer2": {
|
||||
"requests": "grpc://ec2-13-59-99-140.us-east-2.compute.amazonaws.com:7056",
|
||||
"events": "grpc://ec2-13-59-99-140.us-east-2.compute.amazonaws.com:7058",
|
||||
"server-hostname": "peer1.org1.example.com",
|
||||
"tls_cacerts": "../artifacts/channel/crypto-config/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/ca.crt"
|
||||
}
|
||||
},
|
||||
"admin": {
|
||||
"key": "../artifacts/channel/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore",
|
||||
"cert": "../artifacts/channel/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/signcerts"
|
||||
}
|
||||
},
|
||||
"org2": {
|
||||
"name": "peerOrg2",
|
||||
"mspid": "Org2MSP",
|
||||
"ca": "https://ec2-13-59-99-140.us-east-2.compute.amazonaws.com:8054",
|
||||
"peers": {
|
||||
"peer1": {
|
||||
"requests": "grpc://ec2-13-59-99-140.us-east-2.compute.amazonaws.com:8051",
|
||||
"events": "grpc://ec2-13-59-99-140.us-east-2.compute.amazonaws.com:8053",
|
||||
"server-hostname": "peer0.org2.example.com",
|
||||
"tls_cacerts": "../artifacts/channel/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt"
|
||||
},
|
||||
"peer2": {
|
||||
"requests": "grpc://ec2-13-59-99-140.us-east-2.compute.amazonaws.com:8056",
|
||||
"events": "grpc://ec2-13-59-99-140.us-east-2.compute.amazonaws.com:8058",
|
||||
"server-hostname": "peer1.org2.example.com",
|
||||
"tls_cacerts": "../artifacts/channel/crypto-config/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls/ca.crt"
|
||||
}
|
||||
},
|
||||
"admin": {
|
||||
"key": "../artifacts/channel/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp/keystore",
|
||||
"cert": "../artifacts/channel/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp/signcerts"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
{
|
||||
"network-config": {
|
||||
"orderer": {
|
||||
"url": "grpcs://localhost:7050",
|
||||
"server-hostname": "orderer.example.com",
|
||||
"tls_cacerts": "../artifacts/channel/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt"
|
||||
},
|
||||
"org1": {
|
||||
"name": "peerOrg1",
|
||||
"mspid": "Org1MSP",
|
||||
"ca": "https://localhost:7054",
|
||||
"peers": {
|
||||
"peer1": {
|
||||
"requests": "grpcs://localhost:7051",
|
||||
"events": "grpcs://localhost:7053",
|
||||
"server-hostname": "peer0.org1.example.com",
|
||||
"tls_cacerts": "../artifacts/channel/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt"
|
||||
},
|
||||
"peer2": {
|
||||
"requests": "grpcs://localhost:7056",
|
||||
"events": "grpcs://localhost:7058",
|
||||
"server-hostname": "peer1.org1.example.com",
|
||||
"tls_cacerts": "../artifacts/channel/crypto-config/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/ca.crt"
|
||||
}
|
||||
},
|
||||
"admin": {
|
||||
"key": "../artifacts/channel/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore",
|
||||
"cert": "../artifacts/channel/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/signcerts"
|
||||
}
|
||||
},
|
||||
"org2": {
|
||||
"name": "peerOrg2",
|
||||
"mspid": "Org2MSP",
|
||||
"ca": "https://localhost:8054",
|
||||
"peers": {
|
||||
"peer1": {
|
||||
"requests": "grpcs://localhost:8051",
|
||||
"events": "grpcs://localhost:8053",
|
||||
"server-hostname": "peer0.org2.example.com",
|
||||
"tls_cacerts": "../artifacts/channel/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt"
|
||||
},
|
||||
"peer2": {
|
||||
"requests": "grpcs://localhost:8056",
|
||||
"events": "grpcs://localhost:8058",
|
||||
"server-hostname": "peer1.org2.example.com",
|
||||
"tls_cacerts": "../artifacts/channel/crypto-config/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls/ca.crt"
|
||||
}
|
||||
},
|
||||
"admin": {
|
||||
"key": "../artifacts/channel/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp/keystore",
|
||||
"cert": "../artifacts/channel/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp/signcerts"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -17,31 +17,29 @@ var path = require('path');
|
|||
var fs = require('fs');
|
||||
var util = require('util');
|
||||
var hfc = require('fabric-client');
|
||||
var Peer = require('fabric-client/lib/Peer.js');
|
||||
var EventHub = require('fabric-client/lib/EventHub.js');
|
||||
var config = require('../config.json');
|
||||
var helper = require('./helper.js');
|
||||
var logger = helper.getLogger('Query');
|
||||
|
||||
var queryChaincode = function(peer, channelName, chaincodeName, args, fcn, username, org) {
|
||||
var channel = helper.getChannelForOrg(org);
|
||||
var client = helper.getClientForOrg(org);
|
||||
var target = buildTarget(peer, org);
|
||||
return helper.getRegisteredUsers(username, org).then((user) => {
|
||||
tx_id = client.newTransactionID();
|
||||
var queryChaincode = async function(peer, channelName, chaincodeName, args, fcn, username, org_name) {
|
||||
try {
|
||||
// first setup the client for this org
|
||||
var client = await helper.getClientForOrg(org_name, username);
|
||||
logger.debug('Successfully got the fabric client for the organization "%s"', org_name);
|
||||
var channel = client.getChannel(channelName);
|
||||
if(!channel) {
|
||||
let message = util.format('Channel %s was not defined in the connection profile', channelName);
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
// send query
|
||||
var request = {
|
||||
targets : [peer], //queryByChaincode allows for multiple targets
|
||||
chaincodeId: chaincodeName,
|
||||
txId: tx_id,
|
||||
fcn: fcn,
|
||||
args: args
|
||||
};
|
||||
return channel.queryByChaincode(request, target);
|
||||
}, (err) => {
|
||||
logger.info('Failed to get submitter \''+username+'\'');
|
||||
return 'Failed to get submitter \''+username+'\'. Error: ' + err.stack ? err.stack :
|
||||
err;
|
||||
}).then((response_payloads) => {
|
||||
let response_payloads = await channel.queryByChaincode(request);
|
||||
if (response_payloads) {
|
||||
for (let i = 0; i < response_payloads.length; i++) {
|
||||
logger.info(args[0]+' now has ' + response_payloads[i].toString('utf8') +
|
||||
|
|
@ -53,147 +51,130 @@ var queryChaincode = function(peer, channelName, chaincodeName, args, fcn, usern
|
|||
logger.error('response_payloads is null');
|
||||
return 'response_payloads is null';
|
||||
}
|
||||
}, (err) => {
|
||||
logger.error('Failed to send query due to error: ' + err.stack ? err.stack :
|
||||
err);
|
||||
return 'Failed to send query due to error: ' + err.stack ? err.stack : err;
|
||||
}).catch((err) => {
|
||||
logger.error('Failed to end to end test with error:' + err.stack ? err.stack :
|
||||
err);
|
||||
return 'Failed to end to end test with error:' + err.stack ? err.stack :
|
||||
err;
|
||||
});
|
||||
} catch(error) {
|
||||
logger.error('Failed to query due to error: ' + error.stack ? error.stack : error);
|
||||
return error.toString();
|
||||
}
|
||||
};
|
||||
var getBlockByNumber = function(peer, blockNumber, username, org) {
|
||||
var target = buildTarget(peer, org);
|
||||
var channel = helper.getChannelForOrg(org);
|
||||
|
||||
return helper.getRegisteredUsers(username, org).then((member) => {
|
||||
return channel.queryBlock(parseInt(blockNumber), target);
|
||||
}, (err) => {
|
||||
logger.info('Failed to get submitter "' + username + '"');
|
||||
return 'Failed to get submitter "' + username + '". Error: ' + err.stack ?
|
||||
err.stack : err;
|
||||
}).then((response_payloads) => {
|
||||
if (response_payloads) {
|
||||
//logger.debug(response_payloads);
|
||||
logger.debug(response_payloads);
|
||||
return response_payloads; //response_payloads.data.data[0].buffer;
|
||||
} else {
|
||||
logger.error('response_payloads is null');
|
||||
return 'response_payloads is null';
|
||||
var getBlockByNumber = async function(peer, channelName, blockNumber, username, org_name) {
|
||||
try {
|
||||
// first setup the client for this org
|
||||
var client = await helper.getClientForOrg(org_name, username);
|
||||
logger.debug('Successfully got the fabric client for the organization "%s"', org_name);
|
||||
var channel = client.getChannel(channelName);
|
||||
if(!channel) {
|
||||
let message = util.format('Channel %s was not defined in the connection profile', channelName);
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
}, (err) => {
|
||||
logger.error('Failed to send query due to error: ' + err.stack ? err.stack :
|
||||
err);
|
||||
return 'Failed to send query due to error: ' + err.stack ? err.stack : err;
|
||||
}).catch((err) => {
|
||||
logger.error('Failed to query with error:' + err.stack ? err.stack : err);
|
||||
return 'Failed to query with error:' + err.stack ? err.stack : err;
|
||||
});
|
||||
|
||||
let response_payload = await channel.queryBlock(parseInt(blockNumber, peer));
|
||||
if (response_payload) {
|
||||
logger.debug(response_payload);
|
||||
return response_payload;
|
||||
} else {
|
||||
logger.error('response_payload is null');
|
||||
return 'response_payload is null';
|
||||
}
|
||||
} catch(error) {
|
||||
logger.error('Failed to query due to error: ' + error.stack ? error.stack : error);
|
||||
return error.toString();
|
||||
}
|
||||
};
|
||||
var getTransactionByID = function(peer, trxnID, username, org) {
|
||||
var target = buildTarget(peer, org);
|
||||
var channel = helper.getChannelForOrg(org);
|
||||
|
||||
return helper.getRegisteredUsers(username, org).then((member) => {
|
||||
return channel.queryTransaction(trxnID, target);
|
||||
}, (err) => {
|
||||
logger.info('Failed to get submitter "' + username + '"');
|
||||
return 'Failed to get submitter "' + username + '". Error: ' + err.stack ?
|
||||
err.stack : err;
|
||||
}).then((response_payloads) => {
|
||||
if (response_payloads) {
|
||||
logger.debug(response_payloads);
|
||||
return response_payloads;
|
||||
} else {
|
||||
logger.error('response_payloads is null');
|
||||
return 'response_payloads is null';
|
||||
var getTransactionByID = async function(peer, channelName, trxnID, username, org_name) {
|
||||
try {
|
||||
// first setup the client for this org
|
||||
var client = await helper.getClientForOrg(org_name, username);
|
||||
logger.debug('Successfully got the fabric client for the organization "%s"', org_name);
|
||||
var channel = client.getChannel(channelName);
|
||||
if(!channel) {
|
||||
let message = util.format('Channel %s was not defined in the connection profile', channelName);
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
}, (err) => {
|
||||
logger.error('Failed to send query due to error: ' + err.stack ? err.stack :
|
||||
err);
|
||||
return 'Failed to send query due to error: ' + err.stack ? err.stack : err;
|
||||
}).catch((err) => {
|
||||
logger.error('Failed to query with error:' + err.stack ? err.stack : err);
|
||||
return 'Failed to query with error:' + err.stack ? err.stack : err;
|
||||
});
|
||||
|
||||
let response_payload = await channel.queryTransaction(trxnID, peer);
|
||||
if (response_payload) {
|
||||
logger.debug(response_payload);
|
||||
return response_payload;
|
||||
} else {
|
||||
logger.error('response_payload is null');
|
||||
return 'response_payload is null';
|
||||
}
|
||||
} catch(error) {
|
||||
logger.error('Failed to query due to error: ' + error.stack ? error.stack : error);
|
||||
return error.toString();
|
||||
}
|
||||
};
|
||||
var getBlockByHash = function(peer, hash, username, org) {
|
||||
var target = buildTarget(peer, org);
|
||||
var channel = helper.getChannelForOrg(org);
|
||||
|
||||
return helper.getRegisteredUsers(username, org).then((member) => {
|
||||
return channel.queryBlockByHash(Buffer.from(hash), target);
|
||||
}, (err) => {
|
||||
logger.info('Failed to get submitter "' + username + '"');
|
||||
return 'Failed to get submitter "' + username + '". Error: ' + err.stack ?
|
||||
err.stack : err;
|
||||
}).then((response_payloads) => {
|
||||
if (response_payloads) {
|
||||
logger.debug(response_payloads);
|
||||
return response_payloads;
|
||||
} else {
|
||||
logger.error('response_payloads is null');
|
||||
return 'response_payloads is null';
|
||||
var getBlockByHash = async function(peer, channelName, hash, username, org_name) {
|
||||
try {
|
||||
// first setup the client for this org
|
||||
var client = await helper.getClientForOrg(org_name, username);
|
||||
logger.debug('Successfully got the fabric client for the organization "%s"', org_name);
|
||||
var channel = client.getChannel(channelName);
|
||||
if(!channel) {
|
||||
let message = util.format('Channel %s was not defined in the connection profile', channelName);
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
}, (err) => {
|
||||
logger.error('Failed to send query due to error: ' + err.stack ? err.stack :
|
||||
err);
|
||||
return 'Failed to send query due to error: ' + err.stack ? err.stack : err;
|
||||
}).catch((err) => {
|
||||
logger.error('Failed to query with error:' + err.stack ? err.stack : err);
|
||||
return 'Failed to query with error:' + err.stack ? err.stack : err;
|
||||
});
|
||||
|
||||
let response_payload = await channel.queryBlockByHash(Buffer.from(hash), peer);
|
||||
if (response_payload) {
|
||||
logger.debug(response_payload);
|
||||
return response_payload;
|
||||
} else {
|
||||
logger.error('response_payload is null');
|
||||
return 'response_payload is null';
|
||||
}
|
||||
} catch(error) {
|
||||
logger.error('Failed to query due to error: ' + error.stack ? error.stack : error);
|
||||
return error.toString();
|
||||
}
|
||||
};
|
||||
var getChainInfo = function(peer, username, org) {
|
||||
var target = buildTarget(peer, org);
|
||||
var channel = helper.getChannelForOrg(org);
|
||||
|
||||
return helper.getRegisteredUsers(username, org).then((member) => {
|
||||
return channel.queryInfo(target);
|
||||
}, (err) => {
|
||||
logger.info('Failed to get submitter "' + username + '"');
|
||||
return 'Failed to get submitter "' + username + '". Error: ' + err.stack ?
|
||||
err.stack : err;
|
||||
}).then((blockchainInfo) => {
|
||||
if (blockchainInfo) {
|
||||
// FIXME: Save this for testing 'getBlockByHash' ?
|
||||
logger.debug('===========================================');
|
||||
logger.debug(blockchainInfo.currentBlockHash);
|
||||
logger.debug('===========================================');
|
||||
//logger.debug(blockchainInfo);
|
||||
return blockchainInfo;
|
||||
} else {
|
||||
logger.error('response_payloads is null');
|
||||
return 'response_payloads is null';
|
||||
var getChainInfo = async function(peer, channelName, username, org_name) {
|
||||
try {
|
||||
// first setup the client for this org
|
||||
var client = await helper.getClientForOrg(org_name, username);
|
||||
logger.debug('Successfully got the fabric client for the organization "%s"', org_name);
|
||||
var channel = client.getChannel(channelName);
|
||||
if(!channel) {
|
||||
let message = util.format('Channel %s was not defined in the connection profile', channelName);
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
}, (err) => {
|
||||
logger.error('Failed to send query due to error: ' + err.stack ? err.stack :
|
||||
err);
|
||||
return 'Failed to send query due to error: ' + err.stack ? err.stack : err;
|
||||
}).catch((err) => {
|
||||
logger.error('Failed to query with error:' + err.stack ? err.stack : err);
|
||||
return 'Failed to query with error:' + err.stack ? err.stack : err;
|
||||
});
|
||||
|
||||
let response_payload = await channel.queryInfo(peer);
|
||||
if (response_payload) {
|
||||
logger.debug(response_payload);
|
||||
return response_payload;
|
||||
} else {
|
||||
logger.error('response_payload is null');
|
||||
return 'response_payload is null';
|
||||
}
|
||||
} catch(error) {
|
||||
logger.error('Failed to query due to error: ' + error.stack ? error.stack : error);
|
||||
return error.toString();
|
||||
}
|
||||
};
|
||||
//getInstalledChaincodes
|
||||
var getInstalledChaincodes = function(peer, type, username, org) {
|
||||
var target = buildTarget(peer, org);
|
||||
var channel = helper.getChannelForOrg(org);
|
||||
var client = helper.getClientForOrg(org);
|
||||
var getInstalledChaincodes = async function(peer, channelName, type, username, org_name) {
|
||||
try {
|
||||
// first setup the client for this org
|
||||
var client = await helper.getClientForOrg(org_name, username);
|
||||
logger.debug('Successfully got the fabric client for the organization "%s"', org_name);
|
||||
|
||||
return helper.getOrgAdmin(org).then((member) => {
|
||||
let response = null
|
||||
if (type === 'installed') {
|
||||
return client.queryInstalledChaincodes(target);
|
||||
response = await client.queryInstalledChaincodes(peer, true); //use the admin identity
|
||||
} else {
|
||||
return channel.queryInstantiatedChaincodes(target);
|
||||
var channel = client.getChannel(channelName);
|
||||
if(!channel) {
|
||||
let message = util.format('Channel %s was not defined in the connection profile', channelName);
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
response = await channel.queryInstantiatedChaincodes(peer, true); //use the admin identity
|
||||
}
|
||||
}, (err) => {
|
||||
logger.info('Failed to get submitter "' + username + '"');
|
||||
return 'Failed to get submitter "' + username + '". Error: ' + err.stack ?
|
||||
err.stack : err;
|
||||
}).then((response) => {
|
||||
if (response) {
|
||||
if (type === 'installed') {
|
||||
logger.debug('<<< Installed Chaincodes >>>');
|
||||
|
|
@ -214,28 +195,18 @@ var getInstalledChaincodes = function(peer, type, username, org) {
|
|||
logger.error('response is null');
|
||||
return 'response is null';
|
||||
}
|
||||
}, (err) => {
|
||||
logger.error('Failed to send query due to error: ' + err.stack ? err.stack :
|
||||
err);
|
||||
return 'Failed to send query due to error: ' + err.stack ? err.stack : err;
|
||||
}).catch((err) => {
|
||||
logger.error('Failed to query with error:' + err.stack ? err.stack : err);
|
||||
return 'Failed to query with error:' + err.stack ? err.stack : err;
|
||||
});
|
||||
} catch(error) {
|
||||
logger.error('Failed to query due to error: ' + error.stack ? error.stack : error);
|
||||
return error.toString();
|
||||
}
|
||||
};
|
||||
var getChannels = function(peer, username, org) {
|
||||
var target = buildTarget(peer, org);
|
||||
var channel = helper.getChannelForOrg(org);
|
||||
var client = helper.getClientForOrg(org);
|
||||
var getChannels = async function(peer, username, org_name) {
|
||||
try {
|
||||
// first setup the client for this org
|
||||
var client = await helper.getClientForOrg(org_name, username);
|
||||
logger.debug('Successfully got the fabric client for the organization "%s"', org_name);
|
||||
|
||||
return helper.getRegisteredUsers(username, org).then((member) => {
|
||||
//channel.setPrimaryPeer(targets[0]);
|
||||
return client.queryChannels(target);
|
||||
}, (err) => {
|
||||
logger.info('Failed to get submitter "' + username + '"');
|
||||
return 'Failed to get submitter "' + username + '". Error: ' + err.stack ?
|
||||
err.stack : err;
|
||||
}).then((response) => {
|
||||
let response = await client.queryChannels(peer);
|
||||
if (response) {
|
||||
logger.debug('<<< channels >>>');
|
||||
var channelNames = [];
|
||||
|
|
@ -248,25 +219,11 @@ var getChannels = function(peer, username, org) {
|
|||
logger.error('response_payloads is null');
|
||||
return 'response_payloads is null';
|
||||
}
|
||||
}, (err) => {
|
||||
logger.error('Failed to send query due to error: ' + err.stack ? err.stack :
|
||||
err);
|
||||
return 'Failed to send query due to error: ' + err.stack ? err.stack : err;
|
||||
}).catch((err) => {
|
||||
logger.error('Failed to query with error:' + err.stack ? err.stack : err);
|
||||
return 'Failed to query with error:' + err.stack ? err.stack : err;
|
||||
});
|
||||
};
|
||||
|
||||
function buildTarget(peer, org) {
|
||||
var target = null;
|
||||
if (typeof peer !== 'undefined') {
|
||||
let targets = helper.newPeers([peer], org);
|
||||
if (targets && targets.length > 0) target = targets[0];
|
||||
} catch(error) {
|
||||
logger.error('Failed to query due to error: ' + error.stack ? error.stack : error);
|
||||
return error.toString();
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
};
|
||||
|
||||
exports.queryChaincode = queryChaincode;
|
||||
exports.getBlockByNumber = getBlockByNumber;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ services:
|
|||
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
|
||||
|
|
@ -27,6 +28,7 @@ services:
|
|||
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
|
||||
|
|
|
|||
236
balance-transfer/artifacts/network-config-aws.yaml
Normal file
236
balance-transfer/artifacts/network-config-aws.yaml
Normal file
|
|
@ -0,0 +1,236 @@
|
|||
---
|
||||
#
|
||||
# The network connection profile provides client applications the information about the target
|
||||
# blockchain network that are necessary for the applications to interact with it. These are all
|
||||
# knowledge that must be acquired from out-of-band sources. This file provides such a source.
|
||||
#
|
||||
name: "balance-transfer"
|
||||
|
||||
#
|
||||
# Any properties with an "x-" prefix will be treated as application-specific, exactly like how naming
|
||||
# in HTTP headers or swagger properties work. The SDK will simply ignore these fields and leave
|
||||
# them for the applications to process. This is a mechanism for different components of an application
|
||||
# to exchange information that are not part of the standard schema described below. In particular,
|
||||
# the "x-type" property with the "hlfv1" value example below is used by Hyperledger Composer to
|
||||
# determine the type of Fabric networks (v0.6 vs. v1.0) it needs to work with.
|
||||
#
|
||||
x-type: "hlfv1"
|
||||
|
||||
#
|
||||
# Describe what the target network is/does.
|
||||
#
|
||||
description: "Balance Transfer Network"
|
||||
|
||||
#
|
||||
# Schema version of the content. Used by the SDK to apply the corresponding parsing rules.
|
||||
#
|
||||
version: "1.0"
|
||||
|
||||
#
|
||||
# The client section will be added on a per org basis see org1.yaml and org2.yaml
|
||||
#
|
||||
#client:
|
||||
|
||||
#
|
||||
# [Optional]. But most apps would have this section so that channel objects can be constructed
|
||||
# based on the content below. If an app is creating channels, then it likely will not need this
|
||||
# section.
|
||||
#
|
||||
channels:
|
||||
# name of the channel
|
||||
mychannel:
|
||||
# Required. list of orderers designated by the application to use for transactions on this
|
||||
# channel. This list can be a result of access control ("org1" can only access "ordererA"), or
|
||||
# operational decisions to share loads from applications among the orderers. The values must
|
||||
# be "names" of orgs defined under "organizations/peers"
|
||||
orderers:
|
||||
- orderer.example.com
|
||||
|
||||
# Required. list of peers from participating orgs
|
||||
peers:
|
||||
peer0.org1.example.com:
|
||||
# [Optional]. will this peer be sent transaction proposals for endorsement? The peer must
|
||||
# have the chaincode installed. The app can also use this property to decide which peers
|
||||
# to send the chaincode install request. Default: true
|
||||
endorsingPeer: true
|
||||
|
||||
# [Optional]. will this peer be sent query proposals? The peer must have the chaincode
|
||||
# installed. The app can also use this property to decide which peers to send the
|
||||
# chaincode install request. Default: true
|
||||
chaincodeQuery: true
|
||||
|
||||
# [Optional]. will this peer be sent query proposals that do not require chaincodes, like
|
||||
# queryBlock(), queryTransaction(), etc. Default: true
|
||||
ledgerQuery: true
|
||||
|
||||
# [Optional]. will this peer be the target of the SDK's listener registration? All peers can
|
||||
# produce events but the app typically only needs to connect to one to listen to events.
|
||||
# Default: true
|
||||
eventSource: true
|
||||
|
||||
peer1.org1.example.com:
|
||||
endorsingPeer: false
|
||||
chaincodeQuery: true
|
||||
ledgerQuery: true
|
||||
eventSource: false
|
||||
|
||||
peer0.org2.example.com:
|
||||
endorsingPeer: true
|
||||
chaincodeQuery: true
|
||||
ledgerQuery: true
|
||||
eventSource: true
|
||||
|
||||
peer1.org2.example.com:
|
||||
endorsingPeer: false
|
||||
chaincodeQuery: true
|
||||
ledgerQuery: true
|
||||
eventSource: false
|
||||
|
||||
# [Optional]. what chaincodes are expected to exist on this channel? The application can use
|
||||
# this information to validate that the target peers are in the expected state by comparing
|
||||
# this list with the query results of getInstalledChaincodes() and getInstantiatedChaincodes()
|
||||
chaincodes:
|
||||
# the format follows the "cannonical name" of chaincodes by fabric code
|
||||
- mycc:v0
|
||||
|
||||
#
|
||||
# list of participating organizations in this network
|
||||
#
|
||||
organizations:
|
||||
Org1:
|
||||
mspid: Org1MSP
|
||||
|
||||
peers:
|
||||
- peer0.org1.example.com
|
||||
- peer1.org1.example.com
|
||||
|
||||
# [Optional]. Certificate Authorities issue certificates for identification purposes in a Fabric based
|
||||
# network. Typically certificates provisioning is done in a separate process outside of the
|
||||
# runtime network. Fabric-CA is a special certificate authority that provides a REST APIs for
|
||||
# dynamic certificate management (enroll, revoke, re-enroll). The following section is only for
|
||||
# Fabric-CA servers.
|
||||
certificateAuthorities:
|
||||
- ca-org1
|
||||
|
||||
# [Optional]. If the application is going to make requests that are reserved to organization
|
||||
# administrators, including creating/updating channels, installing/instantiating chaincodes, it
|
||||
# must have access to the admin identity represented by the private key and signing certificate.
|
||||
# Both properties can be the PEM string or local path to the PEM file. Note that this is mainly for
|
||||
# convenience in development mode, production systems should not expose sensitive information
|
||||
# this way. The SDK should allow applications to set the org admin identity via APIs, and only use
|
||||
# this route as an alternative when it exists.
|
||||
adminPrivateKey:
|
||||
path: artifacts/channel/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore/5890f0061619c06fb29dea8cb304edecc020fe63f41a6db109f1e227cc1cb2a8_sk
|
||||
signedCert:
|
||||
path: artifacts/channel/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/signcerts/Admin@org1.example.com-cert.pem
|
||||
|
||||
# the profile will contain public information about organizations other than the one it belongs to.
|
||||
# These are necessary information to make transaction lifecycles work, including MSP IDs and
|
||||
# peers with a public URL to send transaction proposals. The file will not contain private
|
||||
# information reserved for members of the organization, such as admin key and certificate,
|
||||
# fabric-ca registrar enroll ID and secret, etc.
|
||||
Org2:
|
||||
mspid: Org2MSP
|
||||
peers:
|
||||
- peer0.org2.example.com
|
||||
- peer1.org2.example.com
|
||||
certificateAuthorities:
|
||||
- ca-org2
|
||||
adminPrivateKey:
|
||||
path: artifacts/channel/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp/keystore/1995b11d6573ed3be52fcd7a5fa477bc0f183e1f5f398c8281d0ce7c2c75a076_sk
|
||||
signedCert:
|
||||
path: artifacts/channel/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp/signcerts/Admin@org2.example.com-cert.pem
|
||||
|
||||
#
|
||||
# List of orderers to send transaction and channel create/update requests to. For the time
|
||||
# being only one orderer is needed. If more than one is defined, which one get used by the
|
||||
# SDK is implementation specific. Consult each SDK's documentation for its handling of orderers.
|
||||
#
|
||||
orderers:
|
||||
orderer.example.com:
|
||||
url: grpcs://ec2-13-59-99-140.us-east-2.compute.amazonaws.com:7050
|
||||
|
||||
# these are standard properties defined by the gRPC library
|
||||
# they will be passed in as-is to gRPC client constructor
|
||||
grpcOptions:
|
||||
ssl-target-name-override: orderer.example.com
|
||||
grpc-max-send-message-length: 15
|
||||
|
||||
tlsCACerts:
|
||||
path: artifacts/channel/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt
|
||||
|
||||
#
|
||||
# List of peers to send various requests to, including endorsement, query
|
||||
# and event listener registration.
|
||||
#
|
||||
peers:
|
||||
peer0.org1.example.com:
|
||||
# this URL is used to send endorsement and query requests
|
||||
url: grpcs://ec2-13-59-99-140.us-east-2.compute.amazonaws.com:7051
|
||||
|
||||
# this URL is used to connect the EventHub and registering event listeners
|
||||
eventUrl: grpcs://ec2-13-59-99-140.us-east-2.compute.amazonaws.com:7053
|
||||
|
||||
grpcOptions:
|
||||
ssl-target-name-override: peer0.org1.example.com
|
||||
tlsCACerts:
|
||||
path: artifacts/channel/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
|
||||
|
||||
peer1.org1.example.com:
|
||||
url: grpcs://ec2-13-59-99-140.us-east-2.compute.amazonaws.com:7056
|
||||
eventUrl: grpcs://ec2-13-59-99-140.us-east-2.compute.amazonaws.com:7058
|
||||
grpcOptions:
|
||||
ssl-target-name-override: peer1.org1.example.com
|
||||
tlsCACerts:
|
||||
path: artifacts/channel/crypto-config/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/ca.crt
|
||||
|
||||
peer0.org2.example.com:
|
||||
url: grpcs://ec2-13-59-99-140.us-east-2.compute.amazonaws.com:8051
|
||||
eventUrl: grpcs://ec2-13-59-99-140.us-east-2.compute.amazonaws.com:8053
|
||||
grpcOptions:
|
||||
ssl-target-name-override: peer0.org2.example.com
|
||||
tlsCACerts:
|
||||
path: artifacts/channel/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
|
||||
|
||||
peer1.org2.example.com:
|
||||
url: grpcs://ec2-13-59-99-140.us-east-2.compute.amazonaws.com:8056
|
||||
eventUrl: grpcs://ec2-13-59-99-140.us-east-2.compute.amazonaws.com:8058
|
||||
grpcOptions:
|
||||
ssl-target-name-override: peer1.org2.example.com
|
||||
tlsCACerts:
|
||||
path: artifacts/channel/crypto-config/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls/ca.crt
|
||||
|
||||
#
|
||||
# Fabric-CA is a special kind of Certificate Authority provided by Hyperledger Fabric which allows
|
||||
# certificate management to be done via REST APIs. Application may choose to use a standard
|
||||
# Certificate Authority instead of Fabric-CA, in which case this section would not be specified.
|
||||
#
|
||||
certificateAuthorities:
|
||||
ca-org1:
|
||||
url: https://ec2-13-59-99-140.us-east-2.compute.amazonaws.com:7054
|
||||
# the properties specified under this object are passed to the 'http' client verbatim when
|
||||
# making the request to the Fabric-CA server
|
||||
httpOptions:
|
||||
verify: false
|
||||
tlsCACerts:
|
||||
path: artifacts/channel/crypto-config/peerOrganizations/org1.example.com/ca/ca.org1.example.com-cert.pem
|
||||
|
||||
# Fabric-CA supports dynamic user enrollment via REST APIs. A "root" user, a.k.a registrar, is
|
||||
# needed to enroll and invoke new users.
|
||||
registrar:
|
||||
- enrollId: admin
|
||||
enrollSecret: adminpw
|
||||
# [Optional] The optional name of the CA.
|
||||
caName: ca-org1
|
||||
|
||||
ca-org2:
|
||||
url: https://ec2-13-59-99-140.us-east-2.compute.amazonaws.com:8054
|
||||
httpOptions:
|
||||
verify: false
|
||||
tlsCACerts:
|
||||
path: artifacts/channel/crypto-config/peerOrganizations/org2.example.com/ca/ca.org2.example.com-cert.pem
|
||||
registrar:
|
||||
- enrollId: admin
|
||||
enrollSecret: adminpw
|
||||
# [Optional] The optional name of the CA.
|
||||
caName: ca-org2
|
||||
236
balance-transfer/artifacts/network-config.yaml
Normal file
236
balance-transfer/artifacts/network-config.yaml
Normal file
|
|
@ -0,0 +1,236 @@
|
|||
---
|
||||
#
|
||||
# The network connection profile provides client applications the information about the target
|
||||
# blockchain network that are necessary for the applications to interact with it. These are all
|
||||
# knowledge that must be acquired from out-of-band sources. This file provides such a source.
|
||||
#
|
||||
name: "balance-transfer"
|
||||
|
||||
#
|
||||
# Any properties with an "x-" prefix will be treated as application-specific, exactly like how naming
|
||||
# in HTTP headers or swagger properties work. The SDK will simply ignore these fields and leave
|
||||
# them for the applications to process. This is a mechanism for different components of an application
|
||||
# to exchange information that are not part of the standard schema described below. In particular,
|
||||
# the "x-type" property with the "hlfv1" value example below is used by Hyperledger Composer to
|
||||
# determine the type of Fabric networks (v0.6 vs. v1.0) it needs to work with.
|
||||
#
|
||||
x-type: "hlfv1"
|
||||
|
||||
#
|
||||
# Describe what the target network is/does.
|
||||
#
|
||||
description: "Balance Transfer Network"
|
||||
|
||||
#
|
||||
# Schema version of the content. Used by the SDK to apply the corresponding parsing rules.
|
||||
#
|
||||
version: "1.0"
|
||||
|
||||
#
|
||||
# The client section will be added on a per org basis see org1.yaml and org2.yaml
|
||||
#
|
||||
#client:
|
||||
|
||||
#
|
||||
# [Optional]. But most apps would have this section so that channel objects can be constructed
|
||||
# based on the content below. If an app is creating channels, then it likely will not need this
|
||||
# section.
|
||||
#
|
||||
channels:
|
||||
# name of the channel
|
||||
mychannel:
|
||||
# Required. list of orderers designated by the application to use for transactions on this
|
||||
# channel. This list can be a result of access control ("org1" can only access "ordererA"), or
|
||||
# operational decisions to share loads from applications among the orderers. The values must
|
||||
# be "names" of orgs defined under "organizations/peers"
|
||||
orderers:
|
||||
- orderer.example.com
|
||||
|
||||
# Required. list of peers from participating orgs
|
||||
peers:
|
||||
peer0.org1.example.com:
|
||||
# [Optional]. will this peer be sent transaction proposals for endorsement? The peer must
|
||||
# have the chaincode installed. The app can also use this property to decide which peers
|
||||
# to send the chaincode install request. Default: true
|
||||
endorsingPeer: true
|
||||
|
||||
# [Optional]. will this peer be sent query proposals? The peer must have the chaincode
|
||||
# installed. The app can also use this property to decide which peers to send the
|
||||
# chaincode install request. Default: true
|
||||
chaincodeQuery: true
|
||||
|
||||
# [Optional]. will this peer be sent query proposals that do not require chaincodes, like
|
||||
# queryBlock(), queryTransaction(), etc. Default: true
|
||||
ledgerQuery: true
|
||||
|
||||
# [Optional]. will this peer be the target of the SDK's listener registration? All peers can
|
||||
# produce events but the app typically only needs to connect to one to listen to events.
|
||||
# Default: true
|
||||
eventSource: true
|
||||
|
||||
peer1.org1.example.com:
|
||||
endorsingPeer: false
|
||||
chaincodeQuery: true
|
||||
ledgerQuery: true
|
||||
eventSource: false
|
||||
|
||||
peer0.org2.example.com:
|
||||
endorsingPeer: true
|
||||
chaincodeQuery: true
|
||||
ledgerQuery: true
|
||||
eventSource: true
|
||||
|
||||
peer1.org2.example.com:
|
||||
endorsingPeer: false
|
||||
chaincodeQuery: true
|
||||
ledgerQuery: true
|
||||
eventSource: false
|
||||
|
||||
# [Optional]. what chaincodes are expected to exist on this channel? The application can use
|
||||
# this information to validate that the target peers are in the expected state by comparing
|
||||
# this list with the query results of getInstalledChaincodes() and getInstantiatedChaincodes()
|
||||
chaincodes:
|
||||
# the format follows the "cannonical name" of chaincodes by fabric code
|
||||
- mycc:v0
|
||||
|
||||
#
|
||||
# list of participating organizations in this network
|
||||
#
|
||||
organizations:
|
||||
Org1:
|
||||
mspid: Org1MSP
|
||||
|
||||
peers:
|
||||
- peer0.org1.example.com
|
||||
- peer1.org1.example.com
|
||||
|
||||
# [Optional]. Certificate Authorities issue certificates for identification purposes in a Fabric based
|
||||
# network. Typically certificates provisioning is done in a separate process outside of the
|
||||
# runtime network. Fabric-CA is a special certificate authority that provides a REST APIs for
|
||||
# dynamic certificate management (enroll, revoke, re-enroll). The following section is only for
|
||||
# Fabric-CA servers.
|
||||
certificateAuthorities:
|
||||
- ca-org1
|
||||
|
||||
# [Optional]. If the application is going to make requests that are reserved to organization
|
||||
# administrators, including creating/updating channels, installing/instantiating chaincodes, it
|
||||
# must have access to the admin identity represented by the private key and signing certificate.
|
||||
# Both properties can be the PEM string or local path to the PEM file. Note that this is mainly for
|
||||
# convenience in development mode, production systems should not expose sensitive information
|
||||
# this way. The SDK should allow applications to set the org admin identity via APIs, and only use
|
||||
# this route as an alternative when it exists.
|
||||
adminPrivateKey:
|
||||
path: artifacts/channel/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore/5890f0061619c06fb29dea8cb304edecc020fe63f41a6db109f1e227cc1cb2a8_sk
|
||||
signedCert:
|
||||
path: artifacts/channel/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/signcerts/Admin@org1.example.com-cert.pem
|
||||
|
||||
# the profile will contain public information about organizations other than the one it belongs to.
|
||||
# These are necessary information to make transaction lifecycles work, including MSP IDs and
|
||||
# peers with a public URL to send transaction proposals. The file will not contain private
|
||||
# information reserved for members of the organization, such as admin key and certificate,
|
||||
# fabric-ca registrar enroll ID and secret, etc.
|
||||
Org2:
|
||||
mspid: Org2MSP
|
||||
peers:
|
||||
- peer0.org2.example.com
|
||||
- peer1.org2.example.com
|
||||
certificateAuthorities:
|
||||
- ca-org2
|
||||
adminPrivateKey:
|
||||
path: artifacts/channel/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp/keystore/1995b11d6573ed3be52fcd7a5fa477bc0f183e1f5f398c8281d0ce7c2c75a076_sk
|
||||
signedCert:
|
||||
path: artifacts/channel/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp/signcerts/Admin@org2.example.com-cert.pem
|
||||
|
||||
#
|
||||
# List of orderers to send transaction and channel create/update requests to. For the time
|
||||
# being only one orderer is needed. If more than one is defined, which one get used by the
|
||||
# SDK is implementation specific. Consult each SDK's documentation for its handling of orderers.
|
||||
#
|
||||
orderers:
|
||||
orderer.example.com:
|
||||
url: grpcs://localhost:7050
|
||||
|
||||
# these are standard properties defined by the gRPC library
|
||||
# they will be passed in as-is to gRPC client constructor
|
||||
grpcOptions:
|
||||
ssl-target-name-override: orderer.example.com
|
||||
grpc-max-send-message-length: 15
|
||||
|
||||
tlsCACerts:
|
||||
path: artifacts/channel/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt
|
||||
|
||||
#
|
||||
# List of peers to send various requests to, including endorsement, query
|
||||
# and event listener registration.
|
||||
#
|
||||
peers:
|
||||
peer0.org1.example.com:
|
||||
# this URL is used to send endorsement and query requests
|
||||
url: grpcs://localhost:7051
|
||||
|
||||
# this URL is used to connect the EventHub and registering event listeners
|
||||
eventUrl: grpcs://localhost:7053
|
||||
|
||||
grpcOptions:
|
||||
ssl-target-name-override: peer0.org1.example.com
|
||||
tlsCACerts:
|
||||
path: artifacts/channel/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
|
||||
|
||||
peer1.org1.example.com:
|
||||
url: grpcs://localhost:7056
|
||||
eventUrl: grpcs://localhost:7058
|
||||
grpcOptions:
|
||||
ssl-target-name-override: peer1.org1.example.com
|
||||
tlsCACerts:
|
||||
path: artifacts/channel/crypto-config/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/ca.crt
|
||||
|
||||
peer0.org2.example.com:
|
||||
url: grpcs://localhost:8051
|
||||
eventUrl: grpcs://localhost:8053
|
||||
grpcOptions:
|
||||
ssl-target-name-override: peer0.org2.example.com
|
||||
tlsCACerts:
|
||||
path: artifacts/channel/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
|
||||
|
||||
peer1.org2.example.com:
|
||||
url: grpcs://localhost:8056
|
||||
eventUrl: grpcs://localhost:8058
|
||||
grpcOptions:
|
||||
ssl-target-name-override: peer1.org2.example.com
|
||||
tlsCACerts:
|
||||
path: artifacts/channel/crypto-config/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls/ca.crt
|
||||
|
||||
#
|
||||
# Fabric-CA is a special kind of Certificate Authority provided by Hyperledger Fabric which allows
|
||||
# certificate management to be done via REST APIs. Application may choose to use a standard
|
||||
# Certificate Authority instead of Fabric-CA, in which case this section would not be specified.
|
||||
#
|
||||
certificateAuthorities:
|
||||
ca-org1:
|
||||
url: https://localhost:7054
|
||||
# the properties specified under this object are passed to the 'http' client verbatim when
|
||||
# making the request to the Fabric-CA server
|
||||
httpOptions:
|
||||
verify: false
|
||||
tlsCACerts:
|
||||
path: artifacts/channel/crypto-config/peerOrganizations/org1.example.com/ca/ca.org1.example.com-cert.pem
|
||||
|
||||
# Fabric-CA supports dynamic user enrollment via REST APIs. A "root" user, a.k.a registrar, is
|
||||
# needed to enroll and invoke new users.
|
||||
registrar:
|
||||
- enrollId: admin
|
||||
enrollSecret: adminpw
|
||||
# [Optional] The optional name of the CA.
|
||||
caName: ca-org1
|
||||
|
||||
ca-org2:
|
||||
url: https://localhost:8054
|
||||
httpOptions:
|
||||
verify: false
|
||||
tlsCACerts:
|
||||
path: artifacts/channel/crypto-config/peerOrganizations/org2.example.com/ca/ca.org2.example.com-cert.pem
|
||||
registrar:
|
||||
- enrollId: admin
|
||||
enrollSecret: adminpw
|
||||
# [Optional] The optional name of the CA.
|
||||
caName: ca-org2
|
||||
53
balance-transfer/artifacts/org1.yaml
Normal file
53
balance-transfer/artifacts/org1.yaml
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
---
|
||||
#
|
||||
# The network connection profile provides client applications the information about the target
|
||||
# blockchain network that are necessary for the applications to interact with it. These are all
|
||||
# knowledge that must be acquired from out-of-band sources. This file provides such a source.
|
||||
#
|
||||
name: "balance-transfer-org1"
|
||||
|
||||
#
|
||||
# Any properties with an "x-" prefix will be treated as application-specific, exactly like how naming
|
||||
# in HTTP headers or swagger properties work. The SDK will simply ignore these fields and leave
|
||||
# them for the applications to process. This is a mechanism for different components of an application
|
||||
# to exchange information that are not part of the standard schema described below. In particular,
|
||||
# the "x-type" property with the "hlfv1" value example below is used by Hyperledger Composer to
|
||||
# determine the type of Fabric networks (v0.6 vs. v1.0) it needs to work with.
|
||||
#
|
||||
x-type: "hlfv1"
|
||||
|
||||
#
|
||||
# Describe what the target network is/does.
|
||||
#
|
||||
description: "Balance Transfer Network - client definition for Org1"
|
||||
|
||||
#
|
||||
# Schema version of the content. Used by the SDK to apply the corresponding parsing rules.
|
||||
#
|
||||
version: "1.0"
|
||||
|
||||
#
|
||||
# The client section is SDK-specific. The sample below is for the node.js SDK
|
||||
#
|
||||
client:
|
||||
# Which organization does this application instance belong to? The value must be the name of an org
|
||||
# defined under "organizations"
|
||||
organization: Org1
|
||||
|
||||
# Some SDKs support pluggable KV stores, the properties under "credentialStore"
|
||||
# are implementation specific
|
||||
credentialStore:
|
||||
# [Optional]. Specific to FileKeyValueStore.js or similar implementations in other SDKs. Can be others
|
||||
# if using an alternative impl. For instance, CouchDBKeyValueStore.js would require an object
|
||||
# here for properties like url, db name, etc.
|
||||
path: "./fabric-client-kv-org1"
|
||||
|
||||
# [Optional]. Specific to the CryptoSuite implementation. Software-based implementations like
|
||||
# CryptoSuite_ECDSA_AES.js in node SDK requires a key store. PKCS#11 based implementations does
|
||||
# not.
|
||||
cryptoStore:
|
||||
# Specific to the underlying KeyValueStore that backs the crypto key store.
|
||||
path: "/tmp/fabric-client-kv-org1"
|
||||
|
||||
# [Optional]. Specific to Composer environment
|
||||
wallet: wallet-name
|
||||
53
balance-transfer/artifacts/org2.yaml
Normal file
53
balance-transfer/artifacts/org2.yaml
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
---
|
||||
#
|
||||
# The network connection profile provides client applications the information about the target
|
||||
# blockchain network that are necessary for the applications to interact with it. These are all
|
||||
# knowledge that must be acquired from out-of-band sources. This file provides such a source.
|
||||
#
|
||||
name: "balance-transfer-org2"
|
||||
|
||||
#
|
||||
# Any properties with an "x-" prefix will be treated as application-specific, exactly like how naming
|
||||
# in HTTP headers or swagger properties work. The SDK will simply ignore these fields and leave
|
||||
# them for the applications to process. This is a mechanism for different components of an application
|
||||
# to exchange information that are not part of the standard schema described below. In particular,
|
||||
# the "x-type" property with the "hlfv1" value example below is used by Hyperledger Composer to
|
||||
# determine the type of Fabric networks (v0.6 vs. v1.0) it needs to work with.
|
||||
#
|
||||
x-type: "hlfv1"
|
||||
|
||||
#
|
||||
# Describe what the target network is/does.
|
||||
#
|
||||
description: "Balance Transfer Network - client definition for Org2"
|
||||
|
||||
#
|
||||
# Schema version of the content. Used by the SDK to apply the corresponding parsing rules.
|
||||
#
|
||||
version: "1.0"
|
||||
|
||||
#
|
||||
# The client section is SDK-specific. The sample below is for the node.js SDK
|
||||
#
|
||||
client:
|
||||
# Which organization does this application instance belong to? The value must be the name of an org
|
||||
# defined under "organizations"
|
||||
organization: Org2
|
||||
|
||||
# Some SDKs support pluggable KV stores, the properties under "credentialStore"
|
||||
# are implementation specific
|
||||
credentialStore:
|
||||
# [Optional]. Specific to FileKeyValueStore.js or similar implementations in other SDKs. Can be others
|
||||
# if using an alternative impl. For instance, CouchDBKeyValueStore.js would require an object
|
||||
# here for properties like url, db name, etc.
|
||||
path: "./fabric-client-kv-org2"
|
||||
|
||||
# [Optional]. Specific to the CryptoSuite implementation. Software-based implementations like
|
||||
# CryptoSuite_ECDSA_AES.js in node SDK requires a key store. PKCS#11 based implementations does
|
||||
# not.
|
||||
cryptoStore:
|
||||
# Specific to the underlying KeyValueStore that backs the crypto key store.
|
||||
path: "/tmp/fabric-client-kv-org2"
|
||||
|
||||
# [Optional]. Specific to Composer environment
|
||||
wallet: wallet-name
|
||||
|
|
@ -2,13 +2,17 @@ var util = require('util');
|
|||
var path = require('path');
|
||||
var hfc = require('fabric-client');
|
||||
|
||||
var file = 'network-config%s.json';
|
||||
var file = 'network-config%s.yaml';
|
||||
|
||||
var env = process.env.TARGET_NETWORK;
|
||||
if (env)
|
||||
file = util.format(file, '-' + env);
|
||||
else
|
||||
file = util.format(file, '');
|
||||
|
||||
hfc.addConfigFile(path.join(__dirname, 'app', file));
|
||||
hfc.addConfigFile(path.join(__dirname, 'config.json'));
|
||||
// indicate to the application where the setup file is located so it able
|
||||
// to have the hfc load it to initalize the fabric client instance
|
||||
hfc.setConfigSetting('network-connection-profile-path',path.join(__dirname, 'app', '../artifacts',file));
|
||||
hfc.setConfigSetting('Org1-connection-profile-path',path.join(__dirname, 'app', '../artifacts','org1.yaml'));
|
||||
hfc.setConfigSetting('Org2-connection-profile-path',path.join(__dirname, 'app', '../artifacts','org2.yaml'));
|
||||
// some other settings the application might need to know
|
||||
hfc.addConfigFile(path.join(__dirname, 'config.json'));
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
"jwt_expiretime": "36000",
|
||||
"channelName":"mychannel",
|
||||
"CC_SRC_PATH":"../artifacts",
|
||||
"keyValueStore":"/tmp/fabric-client-kvs",
|
||||
"eventWaitTime":"30000",
|
||||
"admins":[
|
||||
{
|
||||
|
|
|
|||
2541
balance-transfer/package-lock.json
generated
Normal file
2541
balance-transfer/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -36,8 +36,8 @@ function restartNetwork() {
|
|||
dkcl
|
||||
dkrm
|
||||
|
||||
#Cleanup the material
|
||||
rm -rf /tmp/hfc-test-kvs_peerOrg* $HOME/.hfc-key-store/ /tmp/fabric-client-kvs_peerOrg*
|
||||
#Cleanup the stores
|
||||
rm -rf ./fabric-client-kv-org*
|
||||
|
||||
#Start the network
|
||||
docker-compose up -d
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ echo
|
|||
ORG1_TOKEN=$(curl -s -X POST \
|
||||
http://localhost:4000/users \
|
||||
-H "content-type: application/x-www-form-urlencoded" \
|
||||
-d 'username=Jim&orgName=org1')
|
||||
-d 'username=Jim&orgName=Org1')
|
||||
echo $ORG1_TOKEN
|
||||
ORG1_TOKEN=$(echo $ORG1_TOKEN | jq ".token" | sed "s/\"//g")
|
||||
echo
|
||||
|
|
@ -68,7 +68,7 @@ echo
|
|||
ORG2_TOKEN=$(curl -s -X POST \
|
||||
http://localhost:4000/users \
|
||||
-H "content-type: application/x-www-form-urlencoded" \
|
||||
-d 'username=Barry&orgName=org2')
|
||||
-d 'username=Barry&orgName=Org2')
|
||||
echo $ORG2_TOKEN
|
||||
ORG2_TOKEN=$(echo $ORG2_TOKEN | jq ".token" | sed "s/\"//g")
|
||||
echo
|
||||
|
|
@ -95,7 +95,7 @@ curl -s -X POST \
|
|||
-H "authorization: Bearer $ORG1_TOKEN" \
|
||||
-H "content-type: application/json" \
|
||||
-d '{
|
||||
"peers": ["peer1","peer2"]
|
||||
"peers": ["peer0.org1.example.com","peer1.org1.example.com"]
|
||||
}'
|
||||
echo
|
||||
echo
|
||||
|
|
@ -107,7 +107,7 @@ curl -s -X POST \
|
|||
-H "authorization: Bearer $ORG2_TOKEN" \
|
||||
-H "content-type: application/json" \
|
||||
-d '{
|
||||
"peers": ["peer1","peer2"]
|
||||
"peers": ["peer0.org2.example.com","peer1.org2.example.com"]
|
||||
}'
|
||||
echo
|
||||
echo
|
||||
|
|
@ -119,7 +119,7 @@ curl -s -X POST \
|
|||
-H "authorization: Bearer $ORG1_TOKEN" \
|
||||
-H "content-type: application/json" \
|
||||
-d "{
|
||||
\"peers\": [\"peer1\", \"peer2\"],
|
||||
\"peers\": [\"peer0.org1.example.com\",\"peer1.org1.example.com\"],
|
||||
\"chaincodeName\":\"mycc\",
|
||||
\"chaincodePath\":\"$CC_SRC_PATH\",
|
||||
\"chaincodeType\": \"$LANGUAGE\",
|
||||
|
|
@ -135,7 +135,7 @@ curl -s -X POST \
|
|||
-H "authorization: Bearer $ORG2_TOKEN" \
|
||||
-H "content-type: application/json" \
|
||||
-d "{
|
||||
\"peers\": [\"peer1\",\"peer2\"],
|
||||
\"peers\": [\"peer0.org2.example.com\",\"peer1.org2.example.com\"],
|
||||
\"chaincodeName\":\"mycc\",
|
||||
\"chaincodePath\":\"$CC_SRC_PATH\",
|
||||
\"chaincodeType\": \"$LANGUAGE\",
|
||||
|
|
@ -176,7 +176,7 @@ echo
|
|||
echo "GET query chaincode on peer1 of Org1"
|
||||
echo
|
||||
curl -s -X GET \
|
||||
"http://localhost:4000/channels/mychannel/chaincodes/mycc?peer=peer1&fcn=query&args=%5B%22a%22%5D" \
|
||||
"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
|
||||
|
|
@ -185,7 +185,7 @@ echo
|
|||
echo "GET query Block by blockNumber"
|
||||
echo
|
||||
curl -s -X GET \
|
||||
"http://localhost:4000/channels/mychannel/blocks/1?peer=peer1" \
|
||||
"http://localhost:4000/channels/mychannel/blocks/1?peer=peer0.org1.example.com" \
|
||||
-H "authorization: Bearer $ORG1_TOKEN" \
|
||||
-H "content-type: application/json"
|
||||
echo
|
||||
|
|
@ -193,7 +193,7 @@ echo
|
|||
|
||||
echo "GET query Transaction by TransactionID"
|
||||
echo
|
||||
curl -s -X GET http://localhost:4000/channels/mychannel/transactions/$TRX_ID?peer=peer1 \
|
||||
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"
|
||||
echo
|
||||
|
|
@ -217,7 +217,7 @@ echo
|
|||
echo "GET query ChainInfo"
|
||||
echo
|
||||
curl -s -X GET \
|
||||
"http://localhost:4000/channels/mychannel?peer=peer1" \
|
||||
"http://localhost:4000/channels/mychannel?peer=peer0.org1.example.com" \
|
||||
-H "authorization: Bearer $ORG1_TOKEN" \
|
||||
-H "content-type: application/json"
|
||||
echo
|
||||
|
|
@ -226,7 +226,7 @@ echo
|
|||
echo "GET query Installed chaincodes"
|
||||
echo
|
||||
curl -s -X GET \
|
||||
"http://localhost:4000/chaincodes?peer=peer1&type=installed" \
|
||||
"http://localhost:4000/chaincodes?peer=peer0.org1.example.com" \
|
||||
-H "authorization: Bearer $ORG1_TOKEN" \
|
||||
-H "content-type: application/json"
|
||||
echo
|
||||
|
|
@ -235,7 +235,7 @@ echo
|
|||
echo "GET query Instantiated chaincodes"
|
||||
echo
|
||||
curl -s -X GET \
|
||||
"http://localhost:4000/chaincodes?peer=peer1&type=instantiated" \
|
||||
"http://localhost:4000/channels/mychannel/chaincodes?peer=peer0.org1.example.com" \
|
||||
-H "authorization: Bearer $ORG1_TOKEN" \
|
||||
-H "content-type: application/json"
|
||||
echo
|
||||
|
|
@ -244,7 +244,7 @@ echo
|
|||
echo "GET query Channels"
|
||||
echo
|
||||
curl -s -X GET \
|
||||
"http://localhost:4000/channels?peer=peer1" \
|
||||
"http://localhost:4000/channels?peer=peer0.org1.example.com" \
|
||||
-H "authorization: Bearer $ORG1_TOKEN" \
|
||||
-H "content-type: application/json"
|
||||
echo
|
||||
|
|
|
|||
Loading…
Reference in a new issue