forked from IBM-Blockchain-Archive/SDK-Demo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
helloblockchain.js
275 lines (239 loc) · 9.28 KB
/
helloblockchain.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
process.env.GOPATH = __dirname;
var hfc = require('hfc');
var util = require('util');
var fs = require('fs');
const https = require('https');
var config;
var chain;
var network;
var certPath;
var peers;
var users;
var userObj;
var newUserName;
var chaincodeID;
var certFile = 'us.blockchain.ibm.com.cert';
var chaincodeIDPath = __dirname + "/chaincodeID";
var caUrl;
var peerUrls = [];
var EventUrls = [];
init();
function init() {
try {
config = JSON.parse(fs.readFileSync(__dirname + '/config.json', 'utf8'));
} catch (err) {
console.log("config.json is missing or invalid file, Rerun the program with right file")
process.exit();
}
// Create a client blockchin.
chain = hfc.newChain(config.chainName);
//path to copy the certificate
certPath = __dirname + "/src/" + config.deployRequest.chaincodePath + "/certificate.pem";
// Read and process the credentials.json
try {
network = JSON.parse(fs.readFileSync(__dirname + '/ServiceCredentials.json', 'utf8'));
if (network.credentials) network = network.credentials;
} catch (err) {
console.log("ServiceCredentials.json is missing or invalid file, Rerun the program with right file")
process.exit();
}
peers = network.peers;
users = network.users;
setup();
printNetworkDetails();
//Check if chaincode is already deployed
//TODO: Deploy failures aswell returns chaincodeID, How to address such issue?
if (fileExists(chaincodeIDPath)) {
// Read chaincodeID and use this for sub sequent Invokes/Queries
chaincodeID = fs.readFileSync(chaincodeIDPath, 'utf8');
chain.getUser(newUserName, function(err, user) {
if (err) throw Error(" Failed to register and enroll " + deployerName + ": " + err);
userObj = user;
invoke();
});
} else {
enrollAndRegisterUsers();
}
}
function setup() {
// Determining if we are running on a startup or HSBN network based on the url
// of the discovery host name. The HSBN will contain the string zone.
var isHSBN = peers[0].discovery_host.indexOf('secure') >= 0 ? true : false;
var network_id = Object.keys(network.ca);
caUrl = "grpcs://" + network.ca[network_id].discovery_host + ":" + network.ca[network_id].discovery_port;
// Configure the KeyValStore which is used to store sensitive keys.
// This data needs to be located or accessible any time the users enrollmentID
// perform any functions on the blockchain. The users are not usable without
// This data.
var uuid = network_id[0].substring(0, 8);
chain.setKeyValStore(hfc.newFileKeyValStore(__dirname + '/keyValStore-' + uuid));
if (isHSBN) {
certFile = '0.secure.blockchain.ibm.com.cert';
}
fs.createReadStream(certFile).pipe(fs.createWriteStream(certPath));
var cert = fs.readFileSync(certFile);
chain.setMemberServicesUrl(caUrl, {
pem: cert
});
peerUrls = [];
eventUrls = [];
// Adding all the peers to blockchain
// this adds high availability for the client
for (var i = 0; i < peers.length; i++) {
// Peers on Bluemix require secured connections, hence 'grpcs://'
peerUrls.push("grpcs://" + peers[i].discovery_host + ":" + peers[i].discovery_port);
chain.addPeer(peerUrls[i], {
pem: cert
});
eventUrls.push("grpcs://" + peers[i].event_host + ":" + peers[i].event_port);
chain.eventHubConnect(eventUrls[0], {
pem: cert
});
}
newUserName = config.user.username;
// Make sure disconnect the eventhub on exit
process.on('exit', function() {
chain.eventHubDisconnect();
});
}
function printNetworkDetails() {
console.log("\n------------- ca-server, peers and event URL:PORT information: -------------");
console.log("\nCA server Url : %s\n", caUrl);
for (var i = 0; i < peerUrls.length; i++) {
console.log("Validating Peer%d : %s", i, peerUrls[i]);
}
console.log("");
for (var i = 0; i < eventUrls.length; i++) {
console.log("Event Url on Peer%d : %s", i, eventUrls[i]);
}
console.log("");
console.log('-----------------------------------------------------------\n');
}
function enrollAndRegisterUsers() {
// Enroll a 'admin' who is already registered because it is
// listed in fabric/membersrvc/membersrvc.yaml with it's one time password.
chain.enroll(users[0].enrollId, users[0].enrollSecret, function(err, admin) {
if (err) throw Error("\nERROR: failed to enroll admin : " + err);
console.log("\nEnrolled admin sucecssfully");
// Set this user as the chain's registrar which is authorized to register other users.
chain.setRegistrar(admin);
//creating a new user
var registrationRequest = {
enrollmentID: newUserName,
affiliation: config.user.affiliation
};
chain.registerAndEnroll(registrationRequest, function(err, user) {
if (err) throw Error(" Failed to register and enroll " + newUserName + ": " + err);
console.log("\nEnrolled and registered " + newUserName + " successfully");
userObj = user;
//setting timers for fabric waits
chain.setDeployWaitTime(config.deployWaitTime);
console.log("\nDeploying chaincode ...");
deployChaincode();
});
});
}
function deployChaincode() {
var args = getArgs(config.deployRequest);
// Construct the deploy request
var deployRequest = {
// Function to trigger
fcn: config.deployRequest.functionName,
// Arguments to the initializing function
args: args,
chaincodePath: config.deployRequest.chaincodePath,
// the location where the startup and HSBN store the certificates
certificatePath: network.cert_path
};
// Trigger the deploy transaction
var deployTx = userObj.deploy(deployRequest);
// Print the deploy results
deployTx.on('complete', function(results) {
// Deploy request completed successfully
chaincodeID = results.chaincodeID;
console.log("\nChaincode ID : " + chaincodeID);
console.log(util.format("\nSuccessfully deployed chaincode: request=%j, response=%j", deployRequest, results));
// Save the chaincodeID
fs.writeFileSync(chaincodeIDPath, chaincodeID);
invoke();
});
deployTx.on('error', function(err) {
// Deploy request failed
console.log(util.format("\nFailed to deploy chaincode: request=%j, error=%j", deployRequest, err));
process.exit(1);
});
}
function invoke() {
var args = getArgs(config.invokeRequest);
var eh = chain.getEventHub();
// Construct the invoke request
var invokeRequest = {
// Name (hash) required for invoke
chaincodeID: chaincodeID,
// Function to trigger
fcn: config.invokeRequest.functionName,
// Parameters for the invoke function
args: args
};
// Trigger the invoke transaction
var invokeTx = userObj.invoke(invokeRequest);
// Print the invoke results
invokeTx.on('submitted', function(results) {
// Invoke transaction submitted successfully
console.log(util.format("\nSuccessfully submitted chaincode invoke transaction: request=%j, response=%j", invokeRequest, results));
});
invokeTx.on('complete', function(results) {
// Invoke transaction completed successfully
console.log(util.format("\nSuccessfully completed chaincode invoke transaction: request=%j, response=%j", invokeRequest, results));
query();
});
invokeTx.on('error', function(err) {
// Invoke transaction submission failed
console.log(util.format("\nFailed to submit chaincode invoke transaction: request=%j, error=%j", invokeRequest, err));
process.exit(1);
});
//Listen to custom events
var regid = eh.registerChaincodeEvent(chaincodeID, "evtsender", function(event) {
console.log(util.format("Custom event received, payload: %j\n", event.payload.toString()));
eh.unregisterChaincodeEvent(regid);
});
}
function query() {
var args = getArgs(config.queryRequest);
// Construct the query request
var queryRequest = {
// Name (hash) required for query
chaincodeID: chaincodeID,
// Function to trigger
fcn: config.queryRequest.functionName,
// Existing state variable to retrieve
args: args
};
// Trigger the query transaction
var queryTx = userObj.query(queryRequest);
// Print the query results
queryTx.on('complete', function(results) {
// Query completed successfully
console.log("\nSuccessfully queried chaincode function: request=%j, value=%s", queryRequest, results.result.toString());
process.exit(0);
});
queryTx.on('error', function(err) {
// Query failed
console.log("\nFailed to query chaincode, function: request=%j, error=%j", queryRequest, err);
process.exit(1);
});
}
function getArgs(request) {
var args = [];
for (var i = 0; i < request.args.length; i++) {
args.push(request.args[i]);
}
return args;
}
function fileExists(filePath) {
try {
return fs.statSync(filePath).isFile();
} catch (err) {
return false;
}
}