├── .idea
└── workspace.xml
├── LICENSE
├── README.md
├── app.js
├── app_ca.js
├── app_ca_test.js
├── app_ch11.js
├── app_local.js
├── bcexplorerservice.js
├── bcexplorertest.js
├── bitclient.js
├── bitcoindservice.js
├── bitmain.js
├── config.json
├── cryutil.js
├── db
├── dbtemplement.js
└── mysqlservice.js
├── fabricscf.js
├── fabricservice.js
├── fabricservice4await.js
├── functest.js
├── main.js
├── main1.js
├── mainawait.js
├── mainsy.js
├── network-config.json
├── originservice.js
├── package.json
├── pic
├── 区块链技术实战-fabric.jpeg
└── 区块链技术实战-以太坊.jpeg
└── test.js
/.idea/workspace.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
25 |
26 |
27 |
28 | Admin
29 | caClient
30 | getchannelheight
31 | queryTransaction
32 |
33 |
34 | $PROJECT_DIR$/fabric-client-kvs
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 | true
76 |
77 | true
78 | true
79 |
80 |
81 | true
82 | DEFINITION_ORDER
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 | 1510831165968
207 |
208 |
209 | 1510831165968
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 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 |
509 |
510 |
511 |
512 |
513 |
514 |
515 |
516 |
517 |
518 |
519 |
520 |
521 |
522 |
523 |
524 |
525 |
526 |
527 |
528 |
529 |
530 |
531 |
532 |
533 |
534 |
535 |
536 |
537 |
538 |
539 |
540 |
541 |
542 |
543 |
544 |
545 |
546 |
547 |
548 |
549 |
550 |
551 |
552 |
553 |
554 |
555 |
556 |
557 |
558 |
559 |
560 |
561 |
562 |
563 |
564 |
565 |
566 |
567 |
568 |
569 |
570 |
571 |
572 |
573 |
574 |
575 |
576 |
577 |
578 |
579 |
580 |
581 |
582 |
583 |
584 |
585 |
586 |
587 |
588 |
589 |
590 |
591 |
592 |
593 |
594 |
595 |
596 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction, and
10 | distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by the copyright
13 | owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all other entities
16 | that control, are controlled by, or are under common control with that entity.
17 | For the purposes of this definition, "control" means (i) the power, direct or
18 | indirect, to cause the direction or management of such entity, whether by
19 | contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
20 | outstanding shares, or (iii) beneficial ownership of such entity.
21 |
22 | "You" (or "Your") shall mean an individual or Legal Entity exercising
23 | permissions granted by this License.
24 |
25 | "Source" form shall mean the preferred form for making modifications, including
26 | but not limited to software source code, documentation source, and configuration
27 | files.
28 |
29 | "Object" form shall mean any form resulting from mechanical transformation or
30 | translation of a Source form, including but not limited to compiled object code,
31 | generated documentation, and conversions to other media types.
32 |
33 | "Work" shall mean the work of authorship, whether in Source or Object form, made
34 | available under the License, as indicated by a copyright notice that is included
35 | in or attached to the work (an example is provided in the Appendix below).
36 |
37 | "Derivative Works" shall mean any work, whether in Source or Object form, that
38 | is based on (or derived from) the Work and for which the editorial revisions,
39 | annotations, elaborations, or other modifications represent, as a whole, an
40 | original work of authorship. For the purposes of this License, Derivative Works
41 | shall not include works that remain separable from, or merely link (or bind by
42 | name) to the interfaces of, the Work and Derivative Works thereof.
43 |
44 | "Contribution" shall mean any work of authorship, including the original version
45 | of the Work and any modifications or additions to that Work or Derivative Works
46 | thereof, that is intentionally submitted to Licensor for inclusion in the Work
47 | by the copyright owner or by an individual or Legal Entity authorized to submit
48 | on behalf of the copyright owner. For the purposes of this definition,
49 | "submitted" means any form of electronic, verbal, or written communication sent
50 | to the Licensor or its representatives, including but not limited to
51 | communication on electronic mailing lists, source code control systems, and
52 | issue tracking systems that are managed by, or on behalf of, the Licensor for
53 | the purpose of discussing and improving the Work, but excluding communication
54 | that is conspicuously marked or otherwise designated in writing by the copyright
55 | owner as "Not a Contribution."
56 |
57 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf
58 | of whom a Contribution has been received by Licensor and subsequently
59 | incorporated within the Work.
60 |
61 | 2. Grant of Copyright License.
62 |
63 | Subject to the terms and conditions of this License, each Contributor hereby
64 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
65 | irrevocable copyright license to reproduce, prepare Derivative Works of,
66 | publicly display, publicly perform, sublicense, and distribute the Work and such
67 | Derivative Works in Source or Object form.
68 |
69 | 3. Grant of Patent License.
70 |
71 | Subject to the terms and conditions of this License, each Contributor hereby
72 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
73 | irrevocable (except as stated in this section) patent license to make, have
74 | made, use, offer to sell, sell, import, and otherwise transfer the Work, where
75 | such license applies only to those patent claims licensable by such Contributor
76 | that are necessarily infringed by their Contribution(s) alone or by combination
77 | of their Contribution(s) with the Work to which such Contribution(s) was
78 | submitted. If You institute patent litigation against any entity (including a
79 | cross-claim or counterclaim in a lawsuit) alleging that the Work or a
80 | Contribution incorporated within the Work constitutes direct or contributory
81 | patent infringement, then any patent licenses granted to You under this License
82 | for that Work shall terminate as of the date such litigation is filed.
83 |
84 | 4. Redistribution.
85 |
86 | You may reproduce and distribute copies of the Work or Derivative Works thereof
87 | in any medium, with or without modifications, and in Source or Object form,
88 | provided that You meet the following conditions:
89 |
90 | You must give any other recipients of the Work or Derivative Works a copy of
91 | this License; and
92 | You must cause any modified files to carry prominent notices stating that You
93 | changed the files; and
94 | You must retain, in the Source form of any Derivative Works that You distribute,
95 | all copyright, patent, trademark, and attribution notices from the Source form
96 | of the Work, excluding those notices that do not pertain to any part of the
97 | Derivative Works; and
98 | If the Work includes a "NOTICE" text file as part of its distribution, then any
99 | Derivative Works that You distribute must include a readable copy of the
100 | attribution notices contained within such NOTICE file, excluding those notices
101 | that do not pertain to any part of the Derivative Works, in at least one of the
102 | following places: within a NOTICE text file distributed as part of the
103 | Derivative Works; within the Source form or documentation, if provided along
104 | with the Derivative Works; or, within a display generated by the Derivative
105 | Works, if and wherever such third-party notices normally appear. The contents of
106 | the NOTICE file are for informational purposes only and do not modify the
107 | License. You may add Your own attribution notices within Derivative Works that
108 | You distribute, alongside or as an addendum to the NOTICE text from the Work,
109 | provided that such additional attribution notices cannot be construed as
110 | modifying the License.
111 | You may add Your own copyright statement to Your modifications and may provide
112 | additional or different license terms and conditions for use, reproduction, or
113 | distribution of Your modifications, or for any such Derivative Works as a whole,
114 | provided Your use, reproduction, and distribution of the Work otherwise complies
115 | with the conditions stated in this License.
116 |
117 | 5. Submission of Contributions.
118 |
119 | Unless You explicitly state otherwise, any Contribution intentionally submitted
120 | for inclusion in the Work by You to the Licensor shall be under the terms and
121 | conditions of this License, without any additional terms or conditions.
122 | Notwithstanding the above, nothing herein shall supersede or modify the terms of
123 | any separate license agreement you may have executed with Licensor regarding
124 | such Contributions.
125 |
126 | 6. Trademarks.
127 |
128 | This License does not grant permission to use the trade names, trademarks,
129 | service marks, or product names of the Licensor, except as required for
130 | reasonable and customary use in describing the origin of the Work and
131 | reproducing the content of the NOTICE file.
132 |
133 | 7. Disclaimer of Warranty.
134 |
135 | Unless required by applicable law or agreed to in writing, Licensor provides the
136 | Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
137 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
138 | including, without limitation, any warranties or conditions of TITLE,
139 | NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
140 | solely responsible for determining the appropriateness of using or
141 | redistributing the Work and assume any risks associated with Your exercise of
142 | permissions under this License.
143 |
144 | 8. Limitation of Liability.
145 |
146 | In no event and under no legal theory, whether in tort (including negligence),
147 | contract, or otherwise, unless required by applicable law (such as deliberate
148 | and grossly negligent acts) or agreed to in writing, shall any Contributor be
149 | liable to You for damages, including any direct, indirect, special, incidental,
150 | or consequential damages of any character arising as a result of this License or
151 | out of the use or inability to use the Work (including but not limited to
152 | damages for loss of goodwill, work stoppage, computer failure or malfunction, or
153 | any and all other commercial damages or losses), even if such Contributor has
154 | been advised of the possibility of such damages.
155 |
156 | 9. Accepting Warranty or Additional Liability.
157 |
158 | While redistributing the Work or Derivative Works thereof, You may choose to
159 | offer, and charge a fee for, acceptance of support, warranty, indemnity, or
160 | other liability obligations and/or rights consistent with this License. However,
161 | in accepting such obligations, You may act only on Your own behalf and on Your
162 | sole responsibility, not on behalf of any other Contributor, and only if You
163 | agree to indemnify, defend, and hold each Contributor harmless for any liability
164 | incurred by, or claims asserted against, such Contributor by reason of your
165 | accepting any such warranty or additional liability.
166 |
167 | END OF TERMS AND CONDITIONS
168 |
169 | APPENDIX: How to apply the Apache License to your work
170 |
171 | To apply the Apache License to your work, attach the following boilerplate
172 | notice, with the fields enclosed by brackets "{}" replaced with your own
173 | identifying information. (Don't include the brackets!) The text should be
174 | enclosed in the appropriate comment syntax for the file format. We also
175 | recommend that a file or class name and description of purpose be included on
176 | the same "printed page" as the copyright notice for easier identification within
177 | third-party archives.
178 |
179 | Copyright 2017 冯翔
180 |
181 | Licensed under the Apache License, Version 2.0 (the "License");
182 | you may not use this file except in compliance with the License.
183 | You may obtain a copy of the License at
184 |
185 | http://www.apache.org/licenses/LICENSE-2.0
186 |
187 | Unless required by applicable law or agreed to in writing, software
188 | distributed under the License is distributed on an "AS IS" BASIS,
189 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
190 | See the License for the specific language governing permissions and
191 | limitations under the License.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 项目简介
2 |
3 | 本项目是区块链开发实战丛书 《区块链开发实战 Hyperledger Fabric关键技术与案例分析》 第八章的部分的相关代码
4 |
5 | ## 本书介绍
6 |
7 | 《区块链开发实战 Hyperledger Fabric关键技术与案例分析》
8 |
9 |
10 |
11 |
12 | 如果您觉得本丛书的代码对您有帮助请购买本正版图书,谢谢。
13 |
14 | [购买链接](https://item.jd.com/12380456.html)
15 |
16 | ## 问题反馈,
17 |
18 | 为了帮助读者更好的阅读本书,我们跟中国最大的区块链技术社区区块链兄弟合作,在区块链兄弟上面开设了专栏。如果您在阅读本丛书的过程遇到的问题,可以通过以下连接提交问题
19 |
20 | 点击,提交阅读本书的过程中遇到的问题
21 |
22 |
23 | ## 丛书介绍
24 |
25 | 区块链开发实战系列丛书简介
26 |
--------------------------------------------------------------------------------
/app.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by fengxiang on 2017/9/21.
3 | * QQ 411321681
4 | */
5 |
6 | var co = require('co');
7 |
8 | var path = require('path');
9 | var fs = require('fs');
10 | var util = require('util');
11 | var hfc = require('fabric-client');
12 | var Peer = require('fabric-client/lib/Peer.js');
13 | var EventHub = require('fabric-client/lib/EventHub.js');
14 | var User = require('fabric-client/lib/User.js');
15 | var crypto = require('crypto');
16 | var FabricCAService = require('fabric-ca-client');
17 |
18 | var hfc = require('fabric-client');
19 |
20 |
21 |
22 | var tempdir = "/project/ws_nodejs/fabric_sdk_node_studynew/fabric-client-kvs";
23 |
24 | /*var client
25 | var channel
26 | var caClient
27 | var order
28 | var peer*/
29 |
30 | var client = new hfc();
31 |
32 |
33 | //1、设置相关的环境变量
34 |
35 | //设置用于存储相关文件路径
36 | var cryptoSuite = hfc.newCryptoSuite()
37 | cryptoSuite.setCryptoKeyStore(hfc.newCryptoKeyStore({path:tempdir}))
38 | client.setCryptoSuite(cryptoSuite)
39 |
40 | //创建CA客户端
41 | var caClient = new FabricCAService('http://192.168.23.212:7054',null, '' ,cryptoSuite);
42 |
43 |
44 | //创建账本
45 | var channel = client.newChannel('roberttestchannel12');
46 |
47 | //创建order
48 | var order = client.newOrderer('grpc://192.168.23.212:7050');
49 | channel.addOrderer(order);
50 |
51 | //创建节点
52 | var peer = client.newPeer('grpc://192.168.23.212:7051');
53 | channel.addPeer(peer);
54 |
55 |
56 |
57 | /*getadminuser().then((member)=>{
58 | return channel.queryBlock(2, peer);
59 | },(err)=>{
60 | console.error('Failed to get submitter "' + err.stack + '"')
61 | }).then((reponse)=>{
62 | console.info( reponse )
63 | return reponse
64 | },(err)=>{
65 | console.error(err.stack)
66 | }).catch((err)=>{
67 | console.error(err.stack)
68 | })*/
69 |
70 |
71 |
72 |
73 | co(( function *() {
74 |
75 | let adminmember = yield getadminuser();
76 | //let adminmember = yield getResisteredUser('user88','org1');
77 |
78 | //根据区块链号获取区块信息
79 | let result = yield channel.queryBlock(50, peer,null);
80 |
81 | console.info( JSON.stringify(result ) )
82 |
83 |
84 | /*//let adminuser = yield helper.getAdminUser('org1')
85 | //let adminuser = yield getAdminUser1();
86 |
87 | console.info( adminuser )*/
88 |
89 | //let result = yield startevents();
90 |
91 | }
92 |
93 |
94 | )())
95 |
96 |
97 |
98 |
99 |
100 | //2、设定client order caclient
101 |
102 |
103 | //3、用admin账号登录下
104 |
105 | //
106 |
107 |
108 |
109 |
110 | function startevents() {
111 |
112 |
113 | var users = [
114 | {
115 | "username":"admin",
116 | "secret":"adminpw"
117 | }
118 | ]
119 |
120 | var username = 'admin'
121 | var password = 'adminpw'
122 | var member
123 |
124 | return hfc.newDefaultKeyValueStore( { path:tempdir } )
125 | .then( (store)=>{
126 |
127 | client.setStateStore(store);
128 | client._userContext = null;
129 |
130 | return client.getUserContext(username,true).then( (user)=>{
131 |
132 | if( user && user.isEnrolled() ){
133 |
134 | console.info(` success enrolled admin `)
135 |
136 |
137 | eh = client.newEventHub();
138 | eh.setPeerAddr("grpc://192.168.23.212:7053");
139 |
140 |
141 | try{
142 |
143 |
144 | //区块监听
145 | eh.registerBlockEvent( (block)=>{
146 |
147 | console.info(block)
148 |
149 | } ,
150 |
151 | (err)=>{
152 |
153 | if(err.toString().indexOf('Connect Failed') >= 0) {
154 | console.error( ` find a error on connect failed `+err.stack)
155 | }
156 | else {
157 | console.error('Error function was called but found an unknown error '+err);
158 | }
159 |
160 | }
161 |
162 |
163 |
164 | )
165 |
166 | //监控chaincode
167 | eh.registerChaincodeEvent( 'mycc','myname',( chaincodeevent )=>{
168 | console.info( chaincodeevent )
169 | },(err)=>{
170 | console.error(err)
171 | } )
172 |
173 |
174 | //监控交易,主要是将监控交易是否被记录到区块链,目前还没有正式,估计是可以获取交易
175 | //成功和失败,当交易被发起之后,并没有立即比记录到区块中。
176 |
177 | //eh.registerTxEvent()
178 |
179 | eh.connect();
180 |
181 | }catch(err){
182 |
183 | console.error( ` find a error `+err.stack)
184 | }
185 |
186 |
187 | return user;
188 |
189 | } else{
190 |
191 | return caClient.enroll( {enrollmentID: username, enrollmentSecret: password} ).then(
192 |
193 | (enrollment)=>{
194 |
195 | console.info('Successfully enrolled user \'' + username + '\'');
196 | member = new User(username)
197 | member.setCryptoSuite( client.getCryptoSuite() )
198 |
199 | return member.setEnrollment( enrollment.key,enrollment.certificate,'Org1MSP' )
200 |
201 | }).then( ()=>{
202 |
203 | client.setUserContext(member)
204 |
205 |
206 |
207 |
208 |
209 |
210 | } ).then(()=>{
211 |
212 | return member
213 |
214 | }
215 | ).catch((err)=>{
216 | console.error('enroll admin error'+err.stack)
217 | return null
218 | })
219 |
220 |
221 | }
222 |
223 | } )
224 |
225 |
226 |
227 |
228 | } )
229 |
230 | }
231 |
232 |
233 |
234 |
235 | function getResisteredUser( username , userOrg ) {
236 |
237 | var member;
238 | var enrollmentSecret = null;
239 |
240 | return hfc.newDefaultKeyValueStore({path:tempdir}).then( (store)=>{
241 | client.setStateStore(store);
242 | client._userContext = null;
243 |
244 | return client.getUserContext(username,true).then((user)=>{
245 |
246 | if( user && user.isEnrolled() ){
247 | console.info('Successfully loaded member from persistence');
248 | return user;
249 | }else{
250 |
251 | return getadminuser().then( (adminUser) => {
252 |
253 | member = adminUser;
254 | return caClient.register({ enrollmentID: username, affiliation: userOrg + '.depart1' }, member);
255 |
256 | } ).then( (secret)=>{
257 |
258 | enrollmentSecret = secret;
259 | console.info(username + ' registered successfully');
260 | return caClient.enroll({ enrollmentID: username, enrollmentSecret: secret });
261 |
262 | } ,( err )=> {
263 |
264 | console.error( ' enrool admin err ' + err.stack)
265 | return ''+ err
266 |
267 | }).then( (message)=>{
268 |
269 |
270 | if (message && typeof message === 'string' && message.includes('Error:')) {
271 |
272 | console.error(username + ' enrollment failed');
273 | return message;
274 | }
275 |
276 | console.info(username + ' enrolled successfully');
277 |
278 | member = new User(username);
279 | member._enrollmentSecret = enrollmentSecret;
280 | return member.setEnrollment(message.key, message.certificate, 'Org1MSP' );
281 |
282 | } ).then(()=>{
283 |
284 | client.setUserContext(member);
285 | return member;
286 |
287 | }).catch((err)=>{
288 |
289 | console.error(util.format('%s enroll failed: %s', username, err.stack ? err.stack : err));
290 | return '' + err;
291 |
292 | })
293 |
294 | }
295 |
296 | }).then((user)=>{
297 | return user;
298 | } ,(err)=>{
299 | console.error(''+err.stack)
300 | } ).catch((err)=>{
301 |
302 | console.error(' ' +err.stack)
303 | })
304 |
305 |
306 | } )
307 |
308 | }
309 |
310 |
311 |
312 |
313 |
314 |
315 | function getadminuser() {
316 |
317 |
318 |
319 |
320 | var username = 'user88'
321 | var password = 'peer2wd'
322 | var member
323 |
324 | return hfc.newDefaultKeyValueStore({path:tempdir})
325 | .then( (store)=>{
326 |
327 | client.setStateStore(store);
328 | client._userContext = null;
329 |
330 | return client.getUserContext(username,true).then( (user)=>{
331 |
332 | if( user && user.isEnrolled() ){
333 |
334 | console.info(` success enrolled admin `)
335 | return user;
336 |
337 | } else{
338 |
339 | return caClient.enroll( {enrollmentID: username, enrollmentSecret: password} ).then(
340 |
341 | (enrollment)=>{
342 |
343 | console.info('Successfully enrolled user \'' + username + '\'');
344 | member = new User(username)
345 | member.setCryptoSuite( client.getCryptoSuite() )
346 |
347 | return member.setEnrollment( enrollment.key,enrollment.certificate,'Org1MSP' )
348 |
349 | }).then( ()=>{
350 |
351 | return client.setUserContext(member)
352 |
353 | } ).then(()=>{
354 |
355 | return member
356 |
357 | }
358 | ).catch((err)=>{
359 | console.error('enroll admin error'+err.stack)
360 | return null
361 | })
362 |
363 |
364 | }
365 |
366 | } )
367 |
368 |
369 |
370 |
371 | } )
372 |
373 | }
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 | function getAdminUser1() {
382 | var users = [
383 | {
384 | "username":"admin",
385 | "secret":"adminpw"
386 | }
387 | ]
388 | var username = 'admin';
389 | var password = 'adminpw';
390 | var member;
391 |
392 |
393 | //var client = getClientForOrg(userOrg);
394 |
395 |
396 |
397 | return hfc.newDefaultKeyValueStore({path: tempdir}).then((store) => {
398 | client.setStateStore(store);
399 | // clearing the user context before switching
400 | client._userContext = null;
401 | return client.getUserContext(username, true).then((user) => {
402 | if (user && user.isEnrolled()) {
403 | console.info('Successfully loaded member from persistence');
404 | return user;
405 | } else {
406 | // let caClient = caClients[userOrg];
407 | // need to enroll it with CA server
408 | return caClient.enroll({
409 | enrollmentID: username,
410 | enrollmentSecret: password
411 | }).then((enrollment) => {
412 | console.info('Successfully enrolled user \'' + username + '\'');
413 | member = new User(username);
414 | member.setCryptoSuite(client.getCryptoSuite());
415 | return member.setEnrollment(enrollment.key, enrollment.certificate, "Org1MSP");
416 | }).then(() => {
417 | return client.setUserContext(member);
418 | }).then(() => {
419 | return member;
420 | }).catch((err) => {
421 | console.error('Failed to enroll and persist user. Error: ' + err.stack ? err.stack : err);
422 | return null;
423 | });
424 | }
425 | });
426 | });
427 | };
--------------------------------------------------------------------------------
/app_ca.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by fengxiang on 2017/9/21.
3 | *
4 | * 通过本地的证书文件和配置文件来访问远程的peer
5 | *
6 | */
7 |
8 | var co = require('co');
9 | var path = require('path');
10 | var fs = require('fs');
11 | var util = require('util');
12 | var hfc = require('fabric-client');
13 | var Peer = require('fabric-client/lib/Peer.js');
14 | var EventHub = require('fabric-client/lib/EventHub.js');
15 | var User = require('fabric-client/lib/User.js');
16 | var crypto = require('crypto');
17 | var FabricCAService = require('fabric-ca-client');
18 |
19 | var log4js = require('log4js');
20 | var logger = log4js.getLogger('Helper');
21 | logger.setLevel('DEBUG');
22 |
23 | var tempdir = "/project/ws_nodejs/fabric_sdk_node_studynew/fabric-client-kvs";
24 | //var tempdir = "/project/opt_fabric/fabricconfig/crypto-config/peerOrganizations/org1.robertfabrictest.com/users/Admin@org1.robertfabrictest.com/msp/keystore"
25 |
26 | //var client
27 | // channel
28 | //var caClient
29 | //var order
30 | //var peer
31 |
32 | var client = new hfc();
33 | //1、设置相关的环境变量
34 |
35 | //设置用于存储相关文件路径
36 | var cryptoSuite = hfc.newCryptoSuite()
37 | cryptoSuite.setCryptoKeyStore( hfc.newCryptoKeyStore({ path:tempdir } ) )
38 | client.setCryptoSuite(cryptoSuite)
39 |
40 | //创建CA客户端
41 | var caClient = new FabricCAService('http://192.168.23.212:7054',null, '' ,cryptoSuite);
42 |
43 |
44 | //创建账本
45 | var channel = client.newChannel('roberttestchannel12');
46 |
47 | //创建order
48 | var order = client.newOrderer('grpc://192.168.23.212:7050');
49 | channel.addOrderer(order);
50 | //创建节点
51 |
52 | //创建节点
53 | var peer188 = client.newPeer('grpc://172.16.10.188:7051');
54 | channel.addPeer(peer188);
55 |
56 |
57 | var peer = client.newPeer('grpc://192.168.23.212:7051');
58 | channel.addPeer(peer);
59 |
60 | //创建另外的节点
61 | /*var peer186 = client.newPeer('grpc://172.16.10.186:7051');
62 | channel.addPeer(peer186);*/
63 |
64 |
65 |
66 |
67 |
68 | /*getadminuser().then((member)=>{
69 | return channel.queryBlock(2, peer);
70 | },(err)=>{
71 | console.error('Failed to get submitter "' + err.stack + '"')
72 | }).then((reponse)=>{
73 | console.info( reponse )
74 | return reponse
75 | },(err)=>{
76 | console.error(err.stack)
77 | }).catch((err)=>{
78 | console.error(err.stack)
79 | })*/
80 |
81 |
82 |
83 | console.info("grpc://".indexOf('org'))
84 |
85 |
86 |
87 | co(( function *() {
88 |
89 | //let adminmember = yield getadminuser();
90 | //let adminmember = yield getResisteredUser('admin','org1');
91 | //var a = 1
92 |
93 | /* var username = 'user88'
94 | var password = 'peer2wd'*/
95 | //根据本地证书而不是依赖CA的方式获取管理员账号信息
96 | let member = yield getOrgUser4FabricCa("user88","peer2wd");
97 |
98 |
99 | /// ========= 系统信息查询相关API ==========
100 |
101 |
102 | //获取当前peer服务器的信息
103 | /*let resultpeerinfo = yield channel.queryInfo(peer)
104 | console.info( JSON.stringify(resultpeerinfo ) )*/
105 |
106 | //根据区块编号获取区块信息
107 | /*let blockinfobyNum = yield channel.queryBlock(23, peer,null);
108 | console.info( JSON.stringify( blockinfobyNum ) )*/
109 |
110 |
111 | //根据区块链HASH获取区块详细信息
112 | /*let blockinfobyhash = yield channel.queryBlockByHash(new Buffer("ec298dc1cd1f0e0a3f6d6e25b5796e7b5e4d668aeb6ec3a90b4aa6bb1a7f0c17","hex"),peer)
113 | console.info( JSON.stringify(blockinfobyhash ) )*/
114 |
115 |
116 | //查询Peer节点加入的所有通道
117 | /*let resultchannels = yield client.queryChannels(peer)
118 | console.info( JSON.stringify( resultchannels ) )
119 | */
120 |
121 |
122 | //查询已经install的chaincode
123 |
124 | /*let resultchannels = yield client.queryInstalledChaincodes(peer)
125 | console.info( JSON.stringify( resultchannels ) )*/
126 |
127 |
128 | // 查询已经实例化的Chaincode
129 | /*let chaincodeinstalls = yield channel.queryInstantiatedChaincodes( peer )
130 | console.info( JSON.stringify( chaincodeinstalls ) )*/
131 |
132 |
133 | //根据交易编号获取交易详细信息
134 |
135 | /* let resulttxinfo = yield channel.queryTransaction("56f51f9a54fb4755fd68c6c24931234a59340f7c98308374e9991d276d7d4a96", peer);
136 | console.info( JSON.stringify( resulttxinfo ) )
137 | */
138 |
139 |
140 | //====== 系统管理相关API ============
141 |
142 |
143 |
144 |
145 |
146 |
147 | //// ===== chaincode 类 API ==========
148 |
149 |
150 |
151 |
152 | // 3、调用Chaincode
153 |
154 | //查询 查询方法只要不涉及数据的写入,都是可以调用的
155 |
156 | /*tx_id = client.newTransactionID();
157 | var request = {
158 | chaincodeId: "cc_endorse",
159 | txId: tx_id,
160 | fcn: "invoke",
161 | args: ["GetTxID","akey","333333333 hahaha lst key dddddd this is last version"]
162 | };
163 |
164 | let chiancodequeryresutl = yield channel.queryByChaincode( request , peer );
165 |
166 |
167 | for (let i = 0; i < chiancodequeryresutl.length; i++) {
168 | console.info('Query Response ' + chiancodequeryresutl[i].toString( 'utf8' ) );
169 | //return response_payloads[i].toString('utf8');
170 | }*/
171 |
172 | //console.info( JSON.stringify( chiancodequeryresutl ) )
173 |
174 |
175 |
176 | //发起交易
177 |
178 |
179 | //let targets = {peer};
180 |
181 | /*let tx_id = client.newTransactionID();
182 | var request = {
183 | targets: peer,
184 | chaincodeId: "cc_endorse1",
185 | fcn: "invoke",
186 | args: ["a","b","1"],
187 | chainId: "roberttestchannel",
188 | txId: tx_id
189 | };
190 |
191 | let chaincodeinvokresult = yield channel.sendTransactionProposal(request);
192 |
193 | var proposalResponses = chaincodeinvokresult[0];
194 | var proposal = chaincodeinvokresult[1];
195 | var header = chaincodeinvokresult[2];
196 | var all_good = true;
197 |
198 | for (var i in proposalResponses) {
199 |
200 | let one_good = false;
201 | if (proposalResponses && proposalResponses[0].response &&
202 | proposalResponses[0].response.status === 200) {
203 | one_good = true;
204 | console.info('transaction proposal was good');
205 | } else {
206 | console.error('transaction proposal was bad');
207 | }
208 | all_good = all_good & one_good;
209 | }
210 |
211 | if (all_good) {
212 |
213 | console.info(util.format(
214 |
215 | 'Successfully sent Proposal and received ProposalResponse: Status - %s, message - "%s", metadata - "%s", endorsement signature: %s',
216 | proposalResponses[0].response.status, proposalResponses[0].response.message,
217 | proposalResponses[0].response.payload, proposalResponses[0].endorsement
218 | .signature));
219 |
220 |
221 | var request = {
222 | proposalResponses: proposalResponses,
223 | proposal: proposal,
224 | header: header
225 | };
226 | // set the transaction listener and set a timeout of 30sec
227 | // if the transaction did not get committed within the timeout period,
228 | // fail the test
229 | var transactionID = tx_id.getTransactionID();
230 | var sendPromise = yield channel.sendTransaction(request);
231 |
232 | var eventPromises = [];
233 |
234 | var eh = client.newEventHub();
235 | eh.setPeerAddr("grpc://192.168.23.212:7051")
236 |
237 | eh.connect();
238 |
239 | let txPromise = new Promise((resolve, reject) => {
240 | let handle = setTimeout(() => {
241 | eh.disconnect();
242 | reject();
243 | }, 30000);
244 |
245 | eh.registerTxEvent(transactionID, (tx, code) => {
246 | clearTimeout(handle);
247 | eh.unregisterTxEvent(transactionID);
248 | eh.disconnect();
249 |
250 | if (code !== 'VALID') {
251 | logger.error(
252 | 'The balance transfer transaction was invalid, code = ' + code);
253 | reject();
254 | } else {
255 | logger.info(
256 | 'The balance transfer transaction has been committed on peer ' +
257 | eh._ep._endpoint.addr);
258 | resolve();
259 | }
260 | });
261 | });
262 | eventPromises.push(txPromise);
263 |
264 |
265 |
266 | }
267 |
268 | console.info(all_good)*/
269 |
270 |
271 | //let adminuser = yield helper.getAdminUser('org1')
272 | //let adminuser = yield getAdminUser1();
273 |
274 | //console.info( adminuser )
275 |
276 | // let result = yield startevents();
277 |
278 |
279 | /**
280 | *
281 | * ===== 多方背书 ==============
282 | *
283 | *
284 | * @type {TransactionID}
285 | */
286 |
287 | ///// ===== 多方背书 ==============
288 |
289 | /*var myArray=[];
290 | myArray.push(peer);
291 | myArray.push(peer190);*/
292 |
293 | let tx_id = client.newTransactionID();
294 | var request = {
295 |
296 | chaincodeId: "cc_endfinlshed",
297 | fcn: "invoke",
298 | args: ["a","b","1"],
299 | chainId: "roberttestchannel12",
300 | txId: tx_id
301 | };
302 |
303 | let chaincodeinvokresult = yield channel.sendTransactionProposal(request);
304 |
305 | var proposalResponses = chaincodeinvokresult[0];
306 | var proposal = chaincodeinvokresult[1];
307 | var header = chaincodeinvokresult[2];
308 | var all_good = true;
309 |
310 | for (var i in proposalResponses) {
311 |
312 | let one_good = false;
313 | if (proposalResponses && proposalResponses[0].response &&
314 | proposalResponses[0].response.status === 200) {
315 | one_good = true;
316 | console.info('transaction proposal was good');
317 | } else {
318 | console.error('transaction proposal was bad');
319 | }
320 | all_good = all_good & one_good;
321 | }
322 |
323 | if (all_good) {
324 |
325 | console.info(util.format(
326 |
327 | 'Successfully sent Proposal and received ProposalResponse: Status - %s, message - "%s", metadata - "%s", endorsement signature: %s',
328 | proposalResponses[0].response.status, proposalResponses[0].response.message,
329 | proposalResponses[0].response.payload, proposalResponses[0].endorsement
330 | .signature));
331 |
332 |
333 | var request = {
334 | proposalResponses: proposalResponses,
335 | proposal: proposal,
336 | header: header
337 | };
338 | // set the transaction listener and set a timeout of 30sec
339 | // if the transaction did not get committed within the timeout period,
340 | // fail the test
341 | var transactionID = tx_id.getTransactionID();
342 | var sendPromise = yield channel.sendTransaction(request);
343 |
344 | var eventPromises = [];
345 |
346 | var eh = client.newEventHub();
347 | eh.setPeerAddr("grpc://192.168.23.212:7051")
348 |
349 | eh.connect();
350 |
351 | let txPromise = new Promise((resolve, reject) => {
352 | let handle = setTimeout(() => {
353 | eh.disconnect();
354 | reject();
355 | }, 30000);
356 |
357 | eh.registerTxEvent(transactionID, (tx, code) => {
358 | clearTimeout(handle);
359 | eh.unregisterTxEvent(transactionID);
360 | eh.disconnect();
361 |
362 | if (code !== 'VALID') {
363 | logger.error(
364 | 'The balance transfer transaction was invalid, code = ' + code);
365 | reject();
366 | } else {
367 | logger.info(
368 | 'The balance transfer transaction has been committed on peer ' +
369 | eh._ep._endpoint.addr);
370 | resolve();
371 | }
372 | });
373 | });
374 | eventPromises.push(txPromise);
375 |
376 |
377 | }
378 |
379 | console.info(all_good)
380 |
381 |
382 | }
383 |
384 |
385 |
386 | )())
387 |
388 |
389 |
390 |
391 |
392 | //2、设定client order caclient
393 |
394 |
395 | //3、用admin账号登录下
396 |
397 | //
398 |
399 |
400 | /**
401 | *
402 | * 通过CA获取当前用户的证书信息
403 | *
404 | * @param username
405 | * @param password
406 | * @returns {Promise.}
407 | *
408 | */
409 | function getOrgUser4FabricCa(username,password) {
410 |
411 |
412 | var member
413 |
414 | return hfc.newDefaultKeyValueStore({path:tempdir})
415 | .then( (store)=>{
416 |
417 | client.setStateStore(store);
418 | client._userContext = null;
419 |
420 | return client.getUserContext(username,true).then( (user)=>{
421 |
422 | if( user && user.isEnrolled() ){
423 |
424 | console.info(` success enrolled admin `)
425 | return user;
426 |
427 | } else{
428 |
429 | return caClient.enroll( {enrollmentID: username, enrollmentSecret: password} ).then(
430 |
431 | (enrollment)=>{
432 |
433 | console.info('Successfully enrolled user \'' + username + '\'');
434 | member = new User(username)
435 | member.setCryptoSuite( client.getCryptoSuite() )
436 |
437 | return member.setEnrollment( enrollment.key,enrollment.certificate,'Org1MSP' )
438 |
439 | }).then( ()=>{
440 |
441 | return client.setUserContext(member)
442 |
443 | } ).then(()=>{
444 |
445 | return member
446 |
447 | }
448 | ).catch((err)=>{
449 | console.error('enroll admin error'+err.stack)
450 | return null
451 | })
452 |
453 |
454 | }
455 |
456 | } )
457 |
458 | } )
459 |
460 | }
461 |
462 |
463 | //通过证书
464 | function getOrgAdmin4Local() {
465 |
466 |
467 |
468 |
469 | /* var keyPath = "/project/opt_fabric/fabricconfig/crypto-config/peerOrganizations/org1.robertfabrictest.com/users/Admin@org1.robertfabrictest.com/msp/keystore";
470 | var keyPEM = Buffer.from(readAllFiles(keyPath)[0]).toString();
471 | var certPath = "/project/opt_fabric/fabricconfig/crypto-config/peerOrganizations/org1.robertfabrictest.com/users/Admin@org1.robertfabrictest.com/msp/signcerts";
472 | var certPEM = readAllFiles(certPath)[0].toString();
473 |
474 |
475 |
476 | return hfc.newDefaultKeyValueStore({
477 |
478 | path:tempdir
479 |
480 | }).then((store) => {
481 | client.setStateStore(store);
482 |
483 | return client.createUser({
484 | username: 'Admin',
485 | mspid: 'Org1MSP',
486 | cryptoContent: {
487 | privateKeyPEM: keyPEM,
488 | signedCertPEM: certPEM
489 | }
490 | });
491 | });
492 |
493 | */
494 |
495 | //测试通过CA命令行生成的证书依旧可以成功的发起交易
496 | var keyPath = "/project/fabric_resart/config_demo/org1/186/fabric-user/msp/keystore";
497 | var keyPEM = Buffer.from(readAllFiles(keyPath)[0]).toString();
498 | var certPath = "/project/fabric_resart/config_demo/org1/186/fabric-user/msp//signcerts";
499 | var certPEM = readAllFiles(certPath)[0].toString();
500 |
501 |
502 |
503 | return hfc.newDefaultKeyValueStore({
504 |
505 | path:tempdir
506 |
507 | }).then((store) => {
508 | client.setStateStore(store);
509 |
510 | return client.createUser({
511 | username: 'Admin',
512 | mspid: 'Org1MSP',
513 | cryptoContent: {
514 | privateKeyPEM: keyPEM,
515 | signedCertPEM: certPEM
516 | }
517 | });
518 | });
519 |
520 |
521 | };
522 |
523 |
524 |
525 | function readAllFiles(dir) {
526 | var files = fs.readdirSync(dir);
527 | var certs = [];
528 | files.forEach((file_name) => {
529 | let file_path = path.join(dir,file_name);
530 | let data = fs.readFileSync(file_path);
531 | certs.push(data);
532 | });
533 | return certs;
534 | }
535 |
536 |
537 |
538 | //// 备份的代码块
539 |
540 | /***
541 | channel.queryInstantiatedChaincodes(peer).then((response)=>{
542 |
543 |
544 | var details = [];
545 | for (let i = 0; i < response.chaincodes.length; i++) {
546 | let detail={}
547 | logger.info('name: ' + response.chaincodes[i].name + ', version: ' +
548 | response.chaincodes[i].version + ', path: ' + response.chaincodes[i].path
549 | );
550 | detail.name=response.chaincodes[i].name
551 | detail.version=response.chaincodes[i].version
552 | detail.path=response.chaincodes[i].path
553 | details.push(detail);
554 | }
555 |
556 | })
557 |
558 | */
--------------------------------------------------------------------------------
/app_ca_test.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by fengxiang on 2017/9/21.
3 | *
4 | * 通过本地的证书文件和配置文件来访问远程的peer
5 | *
6 | */
7 |
8 | var co = require('co');
9 | var path = require('path');
10 | var fs = require('fs');
11 | var util = require('util');
12 | var hfc = require('fabric-client');
13 | var Peer = require('fabric-client/lib/Peer.js');
14 | var EventHub = require('fabric-client/lib/EventHub.js');
15 | var User = require('fabric-client/lib/User.js');
16 | var crypto = require('crypto');
17 | var FabricCAService = require('fabric-ca-client');
18 |
19 | var log4js = require('log4js');
20 | var logger = log4js.getLogger('Helper');
21 | logger.setLevel('DEBUG');
22 |
23 | var tempdir = "/project/ws_nodejs/fabric_sdk_node_studynew/fabric-client-kvs";
24 | //var tempdir = "/project/opt_fabric/fabricconfig/crypto-config/peerOrganizations/org1.robertfabrictest.com/users/Admin@org1.robertfabrictest.com/msp/keystore"
25 |
26 | //var client
27 | // channel
28 | //var caClient
29 | //var order
30 | //var peer
31 |
32 | var client = new hfc();
33 | //1、设置相关的环境变量
34 |
35 | //设置用于存储相关文件路径
36 | var cryptoSuite = hfc.newCryptoSuite()
37 | cryptoSuite.setCryptoKeyStore( hfc.newCryptoKeyStore({ path:tempdir } ) )
38 | client.setCryptoSuite(cryptoSuite)
39 |
40 | //创建CA客户端
41 | var caClient = new FabricCAService('http://192.168.23.212:7054',null, '' ,cryptoSuite);
42 |
43 |
44 | //创建账本
45 | var channel = client.newChannel('roberttestchannel12');
46 |
47 | //创建order
48 | var order = client.newOrderer('grpc://192.168.23.212:7050');
49 | channel.addOrderer(order);
50 | //创建节点
51 |
52 | //创建节点
53 | var peer188 = client.newPeer('grpc://172.16.10.188:7051');
54 | channel.addPeer(peer188);
55 |
56 |
57 | var peer = client.newPeer('grpc://192.168.23.212:7051');
58 | channel.addPeer(peer);
59 |
60 | //创建另外的节点
61 | /*var peer186 = client.newPeer('grpc://172.16.10.186:7051');
62 | channel.addPeer(peer186);*/
63 |
64 |
65 |
66 |
67 |
68 | /*getadminuser().then((member)=>{
69 | return channel.queryBlock(2, peer);
70 | },(err)=>{
71 | console.error('Failed to get submitter "' + err.stack + '"')
72 | }).then((reponse)=>{
73 | console.info( reponse )
74 | return reponse
75 | },(err)=>{
76 | console.error(err.stack)
77 | }).catch((err)=>{
78 | console.error(err.stack)
79 | })*/
80 |
81 |
82 |
83 |
84 | co(( function *() {
85 |
86 | //let adminmember = yield getadminuser();
87 | //let adminmember = yield getResisteredUser('admin','org1');
88 | //var a = 1
89 |
90 | /* var username = 'user88'
91 | var password = 'peer2wd'*/
92 | //根据本地证书而不是依赖CA的方式获取管理员账号信息
93 | let member = yield getOrgUser4FabricCa("user88","peer2wd");
94 |
95 |
96 | /// ========= 系统信息查询相关API ==========
97 |
98 |
99 | //获取当前peer服务器的信息
100 | /*let resultpeerinfo = yield channel.queryInfo(peer)
101 | console.info( JSON.stringify(resultpeerinfo ) )*/
102 |
103 |
104 |
105 | }
106 |
107 |
108 | )())
109 |
110 |
111 |
112 |
113 |
114 | //2、设定client order caclient
115 |
116 |
117 | //3、用admin账号登录下
118 |
119 | //
120 |
121 |
122 | /**
123 | *
124 | * 通过CA获取当前用户的证书信息
125 | *
126 | * @param username
127 | * @param password
128 | * @returns {Promise.}
129 | *
130 | */
131 | function getOrgUser4FabricCa(username,password) {
132 |
133 |
134 | var member
135 |
136 | return hfc.newDefaultKeyValueStore({path:tempdir})
137 | .then( (store)=>{
138 |
139 | client.setStateStore(store);
140 | client._userContext = null;
141 |
142 | return client.getUserContext(username,true).then( (user)=>{
143 |
144 | if( user && user.isEnrolled() ){
145 |
146 | console.info(` success enrolled admin `)
147 | return user;
148 |
149 | } else{
150 |
151 | return caClient.enroll( {enrollmentID: username, enrollmentSecret: password} ).then(
152 |
153 | (enrollment)=>{
154 |
155 | console.info('Successfully enrolled user \'' + username + '\'');
156 | member = new User(username)
157 | member.setCryptoSuite( client.getCryptoSuite() )
158 |
159 | return member.setEnrollment( enrollment.key,enrollment.certificate,'Org1MSP' )
160 |
161 | }).then( ()=>{
162 |
163 | return client.setUserContext(member)
164 |
165 | } ).then(()=>{
166 |
167 | return member
168 |
169 | }
170 | ).catch((err)=>{
171 | console.error('enroll admin error'+err.stack)
172 | return null
173 | })
174 |
175 |
176 | }
177 |
178 | } )
179 |
180 | } )
181 |
182 | }
183 |
184 |
185 | //通过证书
186 | function getOrgAdmin4Local() {
187 |
188 |
189 |
190 |
191 | /* var keyPath = "/project/opt_fabric/fabricconfig/crypto-config/peerOrganizations/org1.robertfabrictest.com/users/Admin@org1.robertfabrictest.com/msp/keystore";
192 | var keyPEM = Buffer.from(readAllFiles(keyPath)[0]).toString();
193 | var certPath = "/project/opt_fabric/fabricconfig/crypto-config/peerOrganizations/org1.robertfabrictest.com/users/Admin@org1.robertfabrictest.com/msp/signcerts";
194 | var certPEM = readAllFiles(certPath)[0].toString();
195 |
196 |
197 |
198 | return hfc.newDefaultKeyValueStore({
199 |
200 | path:tempdir
201 |
202 | }).then((store) => {
203 | client.setStateStore(store);
204 |
205 | return client.createUser({
206 | username: 'Admin',
207 | mspid: 'Org1MSP',
208 | cryptoContent: {
209 | privateKeyPEM: keyPEM,
210 | signedCertPEM: certPEM
211 | }
212 | });
213 | });
214 |
215 | */
216 |
217 | //测试通过CA命令行生成的证书依旧可以成功的发起交易
218 | var keyPath = "/project/fabric_resart/config_demo/org1/186/fabric-user/msp/keystore";
219 | var keyPEM = Buffer.from(readAllFiles(keyPath)[0]).toString();
220 | var certPath = "/project/fabric_resart/config_demo/org1/186/fabric-user/msp//signcerts";
221 | var certPEM = readAllFiles(certPath)[0].toString();
222 |
223 |
224 |
225 | return hfc.newDefaultKeyValueStore({
226 |
227 | path:tempdir
228 |
229 | }).then((store) => {
230 | client.setStateStore(store);
231 |
232 | return client.createUser({
233 | username: 'Admin',
234 | mspid: 'Org1MSP',
235 | cryptoContent: {
236 | privateKeyPEM: keyPEM,
237 | signedCertPEM: certPEM
238 | }
239 | });
240 | });
241 |
242 |
243 | };
244 |
245 |
246 |
247 | function readAllFiles(dir) {
248 | var files = fs.readdirSync(dir);
249 | var certs = [];
250 | files.forEach((file_name) => {
251 | let file_path = path.join(dir,file_name);
252 | let data = fs.readFileSync(file_path);
253 | certs.push(data);
254 | });
255 | return certs;
256 | }
257 |
258 |
259 |
260 | //// 备份的代码块
261 |
262 | /***
263 | channel.queryInstantiatedChaincodes(peer).then((response)=>{
264 |
265 |
266 | var details = [];
267 | for (let i = 0; i < response.chaincodes.length; i++) {
268 | let detail={}
269 | logger.info('name: ' + response.chaincodes[i].name + ', version: ' +
270 | response.chaincodes[i].version + ', path: ' + response.chaincodes[i].path
271 | );
272 | detail.name=response.chaincodes[i].name
273 | detail.version=response.chaincodes[i].version
274 | detail.path=response.chaincodes[i].path
275 | details.push(detail);
276 | }
277 |
278 | })
279 |
280 | */
--------------------------------------------------------------------------------
/app_ch11.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by fengxiang on 2017/9/21.
3 | *
4 | * 通过本地的证书文件和配置文件来访问远程的peer
5 | *
6 | */
7 |
8 | var co = require('co');
9 | var path = require('path');
10 | var fs = require('fs');
11 | var util = require('util');
12 | var hfc = require('fabric-client');
13 | var Peer = require('fabric-client/lib/Peer.js');
14 | var EventHub = require('fabric-client/lib/EventHub.js');
15 | var User = require('fabric-client/lib/User.js');
16 | var crypto = require('crypto');
17 | var FabricCAService = require('fabric-ca-client');
18 |
19 | var log4js = require('log4js');
20 | var logger = log4js.getLogger('Helper');
21 | logger.setLevel('DEBUG');
22 |
23 | var tempdir = "/project/ws_nodejs/fabric_sdk_node_studynew/fabric-client-kvs";
24 | //var tempdir = "/project/opt_fabric/fabricconfig/crypto-config/peerOrganizations/org1.robertfabrictest.com/users/Admin@org1.robertfabrictest.com/msp/keystore"
25 |
26 | //var client
27 | // channel
28 | //var caClient
29 | //var order
30 | //var peer
31 |
32 | var client = new hfc();
33 | //1、设置相关的环境变量
34 |
35 | //设置用于存储相关文件路径
36 | var cryptoSuite = hfc.newCryptoSuite()
37 | cryptoSuite.setCryptoKeyStore( hfc.newCryptoKeyStore({ path:tempdir } ) )
38 | client.setCryptoSuite(cryptoSuite)
39 |
40 | //创建CA客户端
41 | var caClient = new FabricCAService('http://192.168.23.212:7054',null, '' ,cryptoSuite);
42 |
43 |
44 | //创建账本
45 | var channel = client.newChannel('roberttestchannel12');
46 |
47 | //创建order
48 | var order = client.newOrderer('grpc://192.168.23.212:7050');
49 | channel.addOrderer(order);
50 | //创建节点
51 |
52 | //创建节点
53 | var peer188 = client.newPeer('grpc://172.16.10.188:7051');
54 | channel.addPeer(peer188);
55 |
56 |
57 | var peer = client.newPeer('grpc://192.168.23.212:7051');
58 | channel.addPeer(peer);
59 |
60 | //创建另外的节点
61 | /*var peer186 = client.newPeer('grpc://172.16.10.186:7051');
62 | channel.addPeer(peer186);*/
63 |
64 |
65 |
66 |
67 |
68 | /*getadminuser().then((member)=>{
69 | return channel.queryBlock(2, peer);
70 | },(err)=>{
71 | console.error('Failed to get submitter "' + err.stack + '"')
72 | }).then((reponse)=>{
73 | console.info( reponse )
74 | return reponse
75 | },(err)=>{
76 | console.error(err.stack)
77 | }).catch((err)=>{
78 | console.error(err.stack)
79 | })*/
80 |
81 |
82 |
83 |
84 | co(( function *() {
85 |
86 | //let adminmember = yield getadminuser();
87 | //let adminmember = yield getResisteredUser('admin','org1');
88 | //var a = 1
89 |
90 | /* var username = 'user88'
91 | var password = 'peer2wd'*/
92 | //根据本地证书而不是依赖CA的方式获取管理员账号信息
93 | let member = yield getOrgUser4FabricCa("user88","peer2wd");
94 |
95 |
96 | /// ========= 系统信息查询相关API ==========
97 |
98 |
99 | //获取当前peer服务器的信息
100 | /*let resultpeerinfo = yield channel.queryInfo(peer)
101 | console.info( JSON.stringify(resultpeerinfo ) )*/
102 |
103 |
104 |
105 | }
106 |
107 |
108 | )())
109 |
110 |
111 |
112 |
113 |
114 | //2、设定client order caclient
115 |
116 |
117 | //3、用admin账号登录下
118 |
119 | //
120 |
121 |
122 | /**
123 | *
124 | * 通过CA获取当前用户的证书信息
125 | *
126 | * @param username
127 | * @param password
128 | * @returns {Promise.}
129 | *
130 | */
131 | function getOrgUser4FabricCa(username,password) {
132 |
133 |
134 | var member
135 |
136 | return hfc.newDefaultKeyValueStore({path:tempdir})
137 | .then( (store)=>{
138 |
139 | client.setStateStore(store);
140 | client._userContext = null;
141 |
142 | return client.getUserContext(username,true).then( (user)=>{
143 |
144 | if( user && user.isEnrolled() ){
145 |
146 | console.info(` success enrolled admin `)
147 | return user;
148 |
149 | } else{
150 |
151 | return caClient.enroll( {enrollmentID: username, enrollmentSecret: password} ).then(
152 |
153 | (enrollment)=>{
154 |
155 | console.info('Successfully enrolled user \'' + username + '\'');
156 | member = new User(username)
157 | member.setCryptoSuite( client.getCryptoSuite() )
158 |
159 | return member.setEnrollment( enrollment.key,enrollment.certificate,'Org1MSP' )
160 |
161 | }).then( ()=>{
162 |
163 | return client.setUserContext(member)
164 |
165 | } ).then(()=>{
166 |
167 | return member
168 |
169 | }
170 | ).catch((err)=>{
171 | console.error('enroll admin error'+err.stack)
172 | return null
173 | })
174 |
175 |
176 | }
177 |
178 | } )
179 |
180 | } )
181 |
182 | }
183 |
184 |
185 | //通过证书
186 | function getOrgAdmin4Local() {
187 |
188 |
189 |
190 |
191 | /* var keyPath = "/project/opt_fabric/fabricconfig/crypto-config/peerOrganizations/org1.robertfabrictest.com/users/Admin@org1.robertfabrictest.com/msp/keystore";
192 | var keyPEM = Buffer.from(readAllFiles(keyPath)[0]).toString();
193 | var certPath = "/project/opt_fabric/fabricconfig/crypto-config/peerOrganizations/org1.robertfabrictest.com/users/Admin@org1.robertfabrictest.com/msp/signcerts";
194 | var certPEM = readAllFiles(certPath)[0].toString();
195 |
196 |
197 |
198 | return hfc.newDefaultKeyValueStore({
199 |
200 | path:tempdir
201 |
202 | }).then((store) => {
203 | client.setStateStore(store);
204 |
205 | return client.createUser({
206 | username: 'Admin',
207 | mspid: 'Org1MSP',
208 | cryptoContent: {
209 | privateKeyPEM: keyPEM,
210 | signedCertPEM: certPEM
211 | }
212 | });
213 | });
214 |
215 | */
216 |
217 | //测试通过CA命令行生成的证书依旧可以成功的发起交易
218 | var keyPath = "/project/fabric_resart/config_demo/org1/186/fabric-user/msp/keystore";
219 | var keyPEM = Buffer.from(readAllFiles(keyPath)[0]).toString();
220 | var certPath = "/project/fabric_resart/config_demo/org1/186/fabric-user/msp//signcerts";
221 | var certPEM = readAllFiles(certPath)[0].toString();
222 |
223 |
224 |
225 | return hfc.newDefaultKeyValueStore({
226 |
227 | path:tempdir
228 |
229 | }).then((store) => {
230 | client.setStateStore(store);
231 |
232 | return client.createUser({
233 | username: 'Admin',
234 | mspid: 'Org1MSP',
235 | cryptoContent: {
236 | privateKeyPEM: keyPEM,
237 | signedCertPEM: certPEM
238 | }
239 | });
240 | });
241 |
242 |
243 | };
244 |
245 |
246 |
247 | function readAllFiles(dir) {
248 | var files = fs.readdirSync(dir);
249 | var certs = [];
250 | files.forEach((file_name) => {
251 | let file_path = path.join(dir,file_name);
252 | let data = fs.readFileSync(file_path);
253 | certs.push(data);
254 | });
255 | return certs;
256 | }
257 |
258 |
259 |
260 | //// 备份的代码块
261 |
262 | /***
263 | channel.queryInstantiatedChaincodes(peer).then((response)=>{
264 |
265 |
266 | var details = [];
267 | for (let i = 0; i < response.chaincodes.length; i++) {
268 | let detail={}
269 | logger.info('name: ' + response.chaincodes[i].name + ', version: ' +
270 | response.chaincodes[i].version + ', path: ' + response.chaincodes[i].path
271 | );
272 | detail.name=response.chaincodes[i].name
273 | detail.version=response.chaincodes[i].version
274 | detail.path=response.chaincodes[i].path
275 | details.push(detail);
276 | }
277 |
278 | })
279 |
280 | */
--------------------------------------------------------------------------------
/app_local.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by fengxiang on 2017/9/21.
3 | *
4 | * 通过本地的证书文件和配置文件来访问远程的peer
5 | *
6 | */
7 |
8 | var co = require('co');
9 | var http = require('http');
10 | var path = require('path');
11 | var fs = require('fs');
12 | var util = require('util');
13 | var hfc = require('fabric-client');
14 | var Peer = require('fabric-client/lib/Peer.js');
15 | var EventHub = require('fabric-client/lib/EventHub.js');
16 | var User = require('fabric-client/lib/User.js');
17 | var crypto = require('crypto');
18 | var FabricCAService = require('fabric-ca-client');
19 |
20 | var hfc = require('fabric-client');
21 |
22 | var log4js = require('log4js');
23 | var logger = log4js.getLogger('Helper');
24 | logger.setLevel('DEBUG');
25 |
26 | var tempdir = "/project/ws_nodejs/fabric_sdk_node_studynew/fabric-client-kvs";
27 | //var tempdir = "/project/opt_fabric/fabricconfig/crypto-config/peerOrganizations/org1.robertfabrictest.com/users/Admin@org1.robertfabrictest.com/msp/keystore"
28 |
29 | var client
30 | // channel
31 | var caClient
32 | //var order
33 | //var peer
34 |
35 | var client = new hfc();
36 | var superagent = require('superagent');
37 |
38 | //1、设置相关的环境变量
39 |
40 | //设置用于存储相关文件路径
41 | /*var cryptoSuite = hfc.newCryptoSuite()
42 | cryptoSuite.setCryptoKeyStore( hfc.newCryptoKeyStore({path:tempdir} ) )
43 |
44 |
45 | client.setCryptoSuite(cryptoSuite)*/
46 |
47 | //创建CA客户端
48 | //var caClient = new FabricCAService('http://192.168.23.212:7054',null, '' ,cryptoSuite);
49 |
50 |
51 | //创建账本
52 | var channel = client.newChannel('roberttestchannel');
53 |
54 | //创建order
55 | var order = client.newOrderer('grpc://192.168.23.212:7050');
56 | channel.addOrderer(order);
57 | //创建节点
58 |
59 | //创建节点
60 | /*var peer188 = client.newPeer('grpc://172.16.10.188:7051');
61 | channel.addPeer(peer188);*/
62 |
63 | var peer = client.newPeer('grpc://192.168.23.212:7051');
64 | channel.addPeer(peer);
65 |
66 | //创建另外的节点
67 | /*var peer186 = client.newPeer('grpc://172.16.10.186:7051');
68 | channel.addPeer(peer186);*/
69 |
70 |
71 |
72 | /*getadminuser().then((member)=>{
73 | return channel.queryBlock(2, peer);
74 | },(err)=>{
75 | console.error('Failed to get submitter "' + err.stack + '"')
76 | }).then((reponse)=>{
77 | console.info( reponse )
78 | return reponse
79 | },(err)=>{
80 | console.error(err.stack)
81 | }).catch((err)=>{
82 | console.error(err.stack)
83 | })*/
84 |
85 |
86 |
87 |
88 | co(( function *() {
89 |
90 | //let adminmember = yield getadminuser();
91 | //let adminmember = yield getResisteredUser('admin','org1');
92 | var a = 1
93 |
94 | //根据本地证书而不是依赖CA的方式获取管理员账号信息
95 | let member = yield getOrgUser4Local();
96 |
97 | /// ========= 系统信息查询相关API ==========
98 |
99 | //获取当前peer服务器的信息
100 | /*let resultpeerinfo = yield channel.queryInfo(peer)
101 | console.info( JSON.stringify(resultpeerinfo ) )*/
102 |
103 | //根据区块编号获取区块信息
104 | /*let blockinfobyNum = yield channel.queryBlock(178, peer,null);
105 | console.info( JSON.stringify( blockinfobyNum ) )
106 | */
107 |
108 | //根据区块链HASH获取区块详细信息
109 | /*let blockinfobyhash = yield channel.queryBlockByHash(new Buffer("ec298dc1cd1f0e0a3f6d6e25b5796e7b5e4d668aeb6ec3a90b4aa6bb1a7f0c17","hex"),peer)
110 | console.info( JSON.stringify(blockinfobyhash ) )*/
111 |
112 |
113 | //查询Peer节点加入的所有通道
114 | /*let resultchannels = yield client.queryChannels(peer)
115 | console.info( JSON.stringify( resultchannels ) )*//*let resultchannels = yield client.queryChannels(peer)
116 | console.info( JSON.stringify( resultchannels ) )*/
117 |
118 | //查询已经install的chaincode
119 |
120 | /*let resultchannels = yield client.queryInstalledChaincodes(peer)
121 | console.info( JSON.stringify( resultchannels ) )*/
122 |
123 |
124 | // 查询已经实例化的Chaincode
125 | /* let chaincodeinstalls = yield channel.queryInstantiatedChaincodes( peer )
126 | console.info( JSON.stringify( chaincodeinstalls ) )*/
127 |
128 |
129 | //根据交易编号获取交易详细信息
130 |
131 | /* let resulttxinfo = yield channel.queryTransaction("56f51f9a54fb4755fd68c6c24931234a59340f7c98308374e9991d276d7d4a96", peer);
132 | console.info( JSON.stringify( resulttxinfo ) )*/
133 |
134 |
135 |
136 | //获取通道的配置信息
137 |
138 | tx_id = client.newTransactionID();
139 | let g_request = {
140 | txId : tx_id
141 | };
142 |
143 | let r2 = yield channel.getChannelConfig();
144 |
145 | let channeljoinorgs = r2['config']['channel_group']['groups']['map']['Application']['value']['groups']['map'];
146 | let join_groups = [];
147 |
148 | for( orgkey in channeljoinorgs ){
149 | join_groups.push(orgkey);
150 | }
151 |
152 |
153 | console.info( join_groups );
154 |
155 | let r1 = yield channel.getGenesisBlock(g_request);
156 | let data = r1['data']['data'][0]['buffer'].toString('utf-8');
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 | /*console.info( r1['header']['data_hash'] )
165 | console.info( r1['data']['data'][0] )*/
166 | //console.info( data );
167 |
168 | /* var response = superagent.post("http://127.0.0.1:8188/protolator/decode/common.Block", r1['data']['data'][0]['buffer'])
169 | .buffer()
170 | .end((err, res) => {
171 |
172 | if(err) {
173 | logger.error(err);
174 | return;
175 | }
176 |
177 | config_proto = res.body;
178 | });
179 | */
180 |
181 |
182 | //====== 系统管理相关API ============
183 |
184 |
185 |
186 |
187 |
188 |
189 | //// ===== chaincode 类 API ==========
190 |
191 |
192 |
193 |
194 | // 3、调用Chaincode
195 |
196 | //查询 查询方法只要不涉及数据的写入,都是可以调用的
197 |
198 | /*tx_id = client.newTransactionID();
199 | var request = {
200 | chaincodeId: "cc_endorse",
201 | txId: tx_id,
202 | fcn: "invoke",
203 | args: ["GetTxID","akey","333333333 hahaha lst key dddddd this is last version"]
204 | };
205 |
206 | let chiancodequeryresutl = yield channel.queryByChaincode( request , peer );
207 |
208 |
209 | for (let i = 0; i < chiancodequeryresutl.length; i++) {
210 | console.info('Query Response ' + chiancodequeryresutl[i].toString( 'utf8' ) );
211 | //return response_payloads[i].toString('utf8');
212 | }*/
213 |
214 | //console.info( JSON.stringify( chiancodequeryresutl ) )
215 |
216 |
217 |
218 | //发起交易
219 |
220 |
221 | //let targets = {peer};
222 |
223 | /*let tx_id = client.newTransactionID();
224 | var request = {
225 | targets: peer,
226 | chaincodeId: "cc_endorse1",
227 | fcn: "invoke",
228 | args: ["a","b","1"],
229 | chainId: "roberttestchannel",
230 | txId: tx_id
231 | };
232 |
233 | let chaincodeinvokresult = yield channel.sendTransactionProposal(request);
234 |
235 | var proposalResponses = chaincodeinvokresult[0];
236 | var proposal = chaincodeinvokresult[1];
237 | var header = chaincodeinvokresult[2];
238 | var all_good = true;
239 |
240 | for (var i in proposalResponses) {
241 |
242 | let one_good = false;
243 | if (proposalResponses && proposalResponses[0].response &&
244 | proposalResponses[0].response.status === 200) {
245 | one_good = true;
246 | console.info('transaction proposal was good');
247 | } else {
248 | console.error('transaction proposal was bad');
249 | }
250 | all_good = all_good & one_good;
251 | }
252 |
253 | if (all_good) {
254 |
255 | console.info(util.format(
256 |
257 | 'Successfully sent Proposal and received ProposalResponse: Status - %s, message - "%s", metadata - "%s", endorsement signature: %s',
258 | proposalResponses[0].response.status, proposalResponses[0].response.message,
259 | proposalResponses[0].response.payload, proposalResponses[0].endorsement
260 | .signature));
261 |
262 |
263 | var request = {
264 | proposalResponses: proposalResponses,
265 | proposal: proposal,
266 | header: header
267 | };
268 | // set the transaction listener and set a timeout of 30sec
269 | // if the transaction did not get committed within the timeout period,
270 | // fail the test
271 | var transactionID = tx_id.getTransactionID();
272 | var sendPromise = yield channel.sendTransaction(request);
273 |
274 | var eventPromises = [];
275 |
276 | var eh = client.newEventHub();
277 | eh.setPeerAddr("grpc://192.168.23.212:7051")
278 |
279 | eh.connect();
280 |
281 | let txPromise = new Promise((resolve, reject) => {
282 | let handle = setTimeout(() => {
283 | eh.disconnect();
284 | reject();
285 | }, 30000);
286 |
287 | eh.registerTxEvent(transactionID, (tx, code) => {
288 | clearTimeout(handle);
289 | eh.unregisterTxEvent(transactionID);
290 | eh.disconnect();
291 |
292 | if (code !== 'VALID') {
293 | logger.error(
294 | 'The balance transfer transaction was invalid, code = ' + code);
295 | reject();
296 | } else {
297 | logger.info(
298 | 'The balance transfer transaction has been committed on peer ' +
299 | eh._ep._endpoint.addr);
300 | resolve();
301 | }
302 | });
303 | });
304 | eventPromises.push(txPromise);
305 |
306 |
307 |
308 | }
309 |
310 | console.info(all_good)*/
311 |
312 |
313 | //let adminuser = yield helper.getAdminUser('org1')
314 | //let adminuser = yield getAdminUser1();
315 |
316 | //console.info( adminuser )
317 |
318 | // let result = yield startevents();
319 |
320 |
321 | /**
322 | *
323 | * ===== 多方背书 ==============
324 | *
325 | *
326 | * @type {TransactionID}
327 | */
328 |
329 | ///// ===== 多方背书 ==============
330 |
331 | /*var myArray=[];
332 | myArray.push(peer);
333 | myArray.push(peer190);*/
334 |
335 | /*let tx_id = client.newTransactionID();
336 | var request = {
337 |
338 | chaincodeId: "cc_endfinlshed",
339 | fcn: "invoke",
340 | args: ["a","b","1"],
341 | chainId: "roberttestchannel12",
342 | txId: tx_id
343 | };
344 |
345 | let chaincodeinvokresult = yield channel.sendTransactionProposal(request);
346 |
347 | var proposalResponses = chaincodeinvokresult[0];
348 | var proposal = chaincodeinvokresult[1];
349 | var header = chaincodeinvokresult[2];
350 | var all_good = true;
351 |
352 | for (var i in proposalResponses) {
353 |
354 | let one_good = false;
355 | if (proposalResponses && proposalResponses[0].response &&
356 | proposalResponses[0].response.status === 200) {
357 | one_good = true;
358 | console.info('transaction proposal was good');
359 | } else {
360 | console.error('transaction proposal was bad');
361 | }
362 | all_good = all_good & one_good;
363 | }
364 |
365 | if (all_good) {
366 |
367 | console.info(util.format(
368 |
369 | 'Successfully sent Proposal and received ProposalResponse: Status - %s, message - "%s", metadata - "%s", endorsement signature: %s',
370 | proposalResponses[0].response.status, proposalResponses[0].response.message,
371 | proposalResponses[0].response.payload, proposalResponses[0].endorsement
372 | .signature));
373 |
374 |
375 | var request = {
376 | proposalResponses: proposalResponses,
377 | proposal: proposal,
378 | header: header
379 | };
380 | // set the transaction listener and set a timeout of 30sec
381 | // if the transaction did not get committed within the timeout period,
382 | // fail the test
383 | var transactionID = tx_id.getTransactionID();
384 | var sendPromise = yield channel.sendTransaction(request);
385 |
386 | var eventPromises = [];
387 |
388 | var eh = client.newEventHub();
389 | eh.setPeerAddr("grpc://192.168.23.212:7051")
390 |
391 | eh.connect();
392 |
393 | let txPromise = new Promise((resolve, reject) => {
394 | let handle = setTimeout(() => {
395 | eh.disconnect();
396 | reject();
397 | }, 30000);
398 |
399 | eh.registerTxEvent(transactionID, (tx, code) => {
400 | clearTimeout(handle);
401 | eh.unregisterTxEvent(transactionID);
402 | eh.disconnect();
403 |
404 | if (code !== 'VALID') {
405 | logger.error(
406 | 'The balance transfer transaction was invalid, code = ' + code);
407 | reject();
408 | } else {
409 | logger.info(
410 | 'The balance transfer transaction has been committed on peer ' +
411 | eh._ep._endpoint.addr);
412 | resolve();
413 | }
414 | });
415 | });
416 | eventPromises.push(txPromise);
417 |
418 |
419 | }
420 |
421 | console.info(all_good)*/
422 |
423 | }
424 |
425 |
426 | )())
427 |
428 |
429 |
430 |
431 | //2、设定client order caclient
432 |
433 | //3、用admin账号登录下
434 |
435 | //
436 |
437 |
438 | /**
439 | *
440 | * 根据cryptogen模块生成的账号通过Fabric接口进行相关的操作
441 | *
442 | * @returns {Promise.}
443 | *
444 | */
445 | function getOrgUser4Local() {
446 |
447 |
448 | var keyPath = "/project/opt_fabric/fabricconfig/crypto-config/peerOrganizations/org1.robertfabrictest.com/users/Admin@org1.robertfabrictest.com/msp/keystore";
449 | var keyPEM = Buffer.from(readAllFiles(keyPath)[0]).toString();
450 | var certPath = "/project/opt_fabric/fabricconfig/crypto-config/peerOrganizations/org1.robertfabrictest.com/users/Admin@org1.robertfabrictest.com/msp/signcerts";
451 | var certPEM = readAllFiles(certPath)[0].toString();
452 |
453 |
454 |
455 | return hfc.newDefaultKeyValueStore({
456 |
457 | path:tempdir
458 |
459 | }).then((store) => {
460 | client.setStateStore(store);
461 |
462 | return client.createUser({
463 | username: 'Admin',
464 | mspid: 'Org1MSP',
465 | cryptoContent: {
466 | privateKeyPEM: keyPEM,
467 | signedCertPEM: certPEM
468 | }
469 | });
470 | });
471 |
472 | //测试通过CA命令行生成的证书依旧可以成功的发起交易
473 | /*var keyPath = "/project/fabric_resart/config_demo/org1/186/fabric-user/msp/keystore";
474 | var keyPEM = Buffer.from(readAllFiles(keyPath)[0]).toString();
475 | var certPath = "/project/fabric_resart/config_demo/org1/186/fabric-user/msp//signcerts";
476 | var certPEM = readAllFiles(certPath)[0].toString();
477 |
478 |
479 | return hfc.newDefaultKeyValueStore({
480 |
481 | path:tempdir
482 |
483 | }).then((store) => {
484 | client.setStateStore(store);
485 |
486 | return client.createUser({
487 | username: 'user87',
488 | mspid: 'Org1MSP',
489 | cryptoContent: {
490 | privateKeyPEM: keyPEM,
491 | signedCertPEM: certPEM
492 | }
493 | });
494 | });*/
495 | };
496 |
497 |
498 |
499 |
500 | function readAllFiles(dir) {
501 | var files = fs.readdirSync(dir);
502 | var certs = [];
503 | files.forEach((file_name) => {
504 | let file_path = path.join(dir,file_name);
505 | let data = fs.readFileSync(file_path);
506 | certs.push(data);
507 | });
508 | return certs;
509 | }
510 |
511 |
512 |
513 | //// 备份的代码块
514 |
515 | /***
516 | channel.queryInstantiatedChaincodes(peer).then((response)=>{
517 |
518 |
519 | var details = [];
520 | for (let i = 0; i < response.chaincodes.length; i++) {
521 | let detail={}
522 | logger.info('name: ' + response.chaincodes[i].name + ', version: ' +
523 | response.chaincodes[i].version + ', path: ' + response.chaincodes[i].path
524 | );
525 | detail.name=response.chaincodes[i].name
526 | detail.version=response.chaincodes[i].version
527 | detail.path=response.chaincodes[i].path
528 | details.push(detail);
529 | }
530 |
531 | })
532 |
533 | */
534 |
535 |
536 | process.on('unhandledRejection', function (err) {
537 | console.error(err.stack);
538 | });
539 |
540 | process.on(`uncaughtException`, console.error);
541 |
542 |
--------------------------------------------------------------------------------
/bcexplorerservice.js:
--------------------------------------------------------------------------------
1 | var bcconfig = require('./config.json');
2 | var fabricservice = require('./fabricservice');
3 | var sql=require('./db/mysqlservice.js')
4 |
5 | var orgnamemap = initConfig(0);
6 | var orgmspidmap = initConfig(1);
7 |
8 |
9 | function initConfig (types) {
10 |
11 | let orgs = bcconfig['orgs'];
12 | var orgnamemap = {};
13 | var peers = {};
14 | var peermap = {};
15 |
16 | for ( let ind = 0 ; ind{
98 |
99 |
100 | let actions = transaction['payload']['data']['actions'];
101 |
102 | if( actions != null && actions[0]['payload'] != null ){
103 |
104 | let ns_rwset = transaction['payload']['data']['actions'][0]['payload']['action']['proposal_response_payload']['extension']['results']['ns_rwset'];
105 |
106 | //console.info(JSON.stringify(blockinfo['data']['data'][0]['payload']['data']['actions'][0]['payload']['action']['proposal_response_payload']['extension']['results']['ns_rwset'][1]['rwset']['writes']));
107 |
108 |
109 | let keyset = {}
110 |
111 | for( let ind = 0 ; ind {
139 |
140 | let org = orgnamemap[orgname];
141 | let tempdir = bcconfig['keyValueStore'];
142 | let adminkey = org['admin']['key'];
143 | let admincert = org['admin']['cert'];
144 |
145 | fabricservice.inits(tempdir, adminkey, admincert);
146 |
147 | /*let blockchaininfo = await fabricservice.getBlockChainInfo('roberttestchannel', 'grpc://192.168.23.212:7051');
148 | console.info(JSON.stringify(blockchaininfo));
149 | */
150 |
151 | //for (let ind = 30; ind < 179; ind++) {
152 |
153 |
154 | let blockinfo = await fabricservice.getblockInfobyNum('roberttestchannel', 'grpc://192.168.23.212:7051', 94 );
155 |
156 | console.info(JSON.stringify(blockinfo['data']['data'][0]['payload']['header']['channel_header']['tx_id']));
157 | console.info(JSON.stringify(blockinfo['data']['data'][0]['payload']['header']['channel_header']['timestamp']));
158 | console.info(JSON.stringify(blockinfo['data']['data'][0]['payload']['data']['actions'][0]['payload']['action']['proposal_response_payload']['extension']));
159 |
160 |
161 | console.info((JSON.stringify(getkeyset4Transaction(blockinfo['data']['data'][0]))));
162 |
163 |
164 |
165 | //}
166 | //let peerchannels = await fabricservice.getPeerChannel('grpc://192.168.23.212:7051');
167 | //let peerchannels = await fabricservice.getPeerChannel('grpc://172.16.10.186:7051');
168 | /*let peerchannels = await fabricservice.getPeerChannel('grpc://172.16.10.187:7051');
169 | console.info( JSON.stringify( peerchannels) );*/
170 | //{"channels":[{"channel_id":"roberttestchannel"},{"channel_id":"roberttestchannelnew"}]}
171 |
172 |
173 |
174 |
175 | //let installcc = await fabricservice.getPeerInstallCc('grpc://192.168.23.212:7051')
176 | //let instancecc = await fabricservice.getPeerInstantiatedCc('roberttestchannel12','grpc://192.168.23.212:7051');
177 |
178 |
179 | //let transinfo = await fabricservice.getTransaction('roberttestchannel','grpc://192.168.23.212:7051','56f51f9a54fb4755fd68c6c24931234a59340f7c98308374e9991d276d7d4a96')
180 |
181 | //获取被调用chaincode 和 keyset 的代码
182 | //console.info( JSON.stringify( transinfo['transactionEnvelope']['payload']['data']['actions'][0]['payload']['action']['proposal_response_payload']['extension']['results']['ns_rwset']) );
183 |
184 | //获取被调用chaincode背书节点的信息
185 | //console.info( JSON.stringify( transinfo['transactionEnvelope']['payload']['data']['actions'][0]['payload']['action']['endorsements']) );
186 |
187 |
188 | //测试数据库
189 |
190 | /*let testsqlresult = await sql.saveRow('block',{
191 | 'channelid':'roberttestchannel',
192 | 'blocknum':
193 | 'datahash':'ddddddddddd',
194 | 'perhash':'dddddddd',
195 | 'txcount':13,
196 | 'remark':'ddd',
197 | });
198 |
199 |
200 | console.info( JSON.stringify( testsqlresult) );*/
201 |
202 |
203 | let channels = sql.getRowByPkOne( ` select id from channel where channelid = 'dddd' `)
204 | console.info( JSON.stringify( channels) );
205 |
206 | sql.closeconnection();
207 |
208 | }
209 |
210 |
211 |
212 | var parserOrg = async ( orgname )=>{
213 |
214 |
215 | let org = orgnamemap[orgname];
216 | let peers = org['peers'];
217 | let channelpeermap = {};
218 | let peerjoinchannels = [];
219 |
220 | let tempdir = bcconfig['keyValueStore'];
221 | let adminkey = org['admin']['key'];
222 | let admincert = org['admin']['cert'];
223 |
224 | fabricservice.inits(tempdir,adminkey,admincert);
225 |
226 |
227 | for( let ind = 0 ; ind < peers.length ; ind++ ){
228 |
229 | let peer = peers[ind];
230 | let peerrequest = getPeerRequest(peer['requests']);
231 | let peerchannel = await fabricservice.getPeerChannel(peerrequest);
232 |
233 | //console.info( JSON.stringify( peerchannels) );
234 | let peerchannels = peerchannel['channels'];
235 |
236 | peer['channels'] = peerchannels;
237 |
238 |
239 | peerjoinchannels.push(peer);
240 |
241 |
242 | for( let cind = 0 ; cind{
276 |
277 |
278 | for( let ind = 0 ; ind{
309 |
310 |
311 | let channels = await sql.getRowByPkOne( ` select id from channel where channelid = '${channel_id}' `)
312 |
313 | if( channels == null ){
314 |
315 | let channel = {
316 | 'channelid':channel_id,
317 | 'blocks':0,
318 | 'trans':0,
319 | 'remark':'',
320 | };
321 |
322 | await sql.saveRow('channel',channel);
323 | }
324 |
325 |
326 | }
327 |
328 |
329 | var save_peer_ref_channel = async ( channel_id , peer_name) =>{
330 |
331 |
332 | let peerrefchannels = await sql.getRowByPkOne( ` select id from peer_ref_channel where peer_name = '${peer_name}' and channel_id = '${channel_id}' `)
333 |
334 | if( peerrefchannels == null ){
335 |
336 | let peer_ref_channel = {
337 |
338 | 'peer_name':peer_name,
339 | 'channel_id':channel_id,
340 |
341 | };
342 |
343 |
344 | await sql.saveRow( 'peer_ref_channel' , peer_ref_channel );
345 |
346 | }
347 |
348 |
349 | }
350 |
351 |
352 |
353 | var modify_channels = async ( channelpeermap,fabricservice )=>{
354 |
355 |
356 |
357 | for( let key in channelpeermap ){
358 |
359 | let channel_id = key ;
360 | let peer = channelpeermap[channel_id];
361 |
362 | await modify_channel_block( channel_id,peer,fabricservice);
363 |
364 |
365 | }
366 |
367 |
368 |
369 |
370 | }
371 |
372 |
373 |
374 | var modify_channel = async ( channels ) =>{
375 |
376 |
377 |
378 | }
379 |
380 |
381 |
382 | var modify_channel_block = async ( channel_id,peer,fabricservice )=>{
383 |
384 |
385 | let peer_request = getPeerRequest(peer['requests']);
386 | let blockchaininfo = await fabricservice.getBlockChainInfo(channel_id,peer_request);
387 |
388 | let channel = await sql.getRowByPkOne(` select * from channel where channelid = '${channel_id}' `);
389 | //let channel = channels[0];
390 |
391 | let channelid = channel['id'];
392 |
393 | let blockheight = blockchaininfo['height']['low'];
394 |
395 | let updageresult = await sql.updateBySql(` update channel set blocks = ${blockheight} where id = ${channelid} `);
396 | console.info( JSON.stringify( blockchaininfo['height']['low']) );
397 |
398 |
399 | let countblocks = channel['countblocks'];
400 |
401 |
402 | while( blockheight > countblocks ){
403 |
404 |
405 | let blockinfo = await fabricservice.getblockInfobyNum( channel_id , peer_request , countblocks-1 );
406 |
407 | let blocknum = blockinfo['header']['number']['low'];
408 | let datahash = blockinfo['header']['data_hash'];
409 | let perhash = blockinfo['header']['previous_hash'];
410 |
411 | let txcount = 0;
412 |
413 | let trans = blockinfo['data']['data'];
414 |
415 | if( trans != null ){
416 | txcount = trans.length;
417 | }
418 |
419 |
420 | let block = {
421 | 'channelid':channel_id,
422 | 'blocknum':blocknum,
423 | 'datahash':datahash,
424 | 'perhash':perhash,
425 | 'txcount':txcount,
426 | 'remark':'',
427 | };
428 |
429 |
430 | await sql.saveRow('block',block);
431 |
432 | await modify_channel_block_trans( channel_id , peer , blockinfo , fabricservice )
433 |
434 | countblocks++;
435 | let updageresult = await sql.updateBySql(` update channel set countblocks = countblocks+1 where id = ${channelid} `);
436 |
437 |
438 |
439 |
440 |
441 |
442 | }
443 |
444 |
445 |
446 |
447 |
448 | }
449 |
450 |
451 | var modify_channel_block_trans = async (channel_id,peer,blockinfo,fabricservice)=>{
452 |
453 |
454 | let trans = blockinfo['data']['data'];
455 |
456 | if( trans != null ){
457 |
458 |
459 | let blocknum = blockinfo['header']['number']['low'];
460 | let blockhash = blockinfo['header']['data_hash'];
461 | //let perhash = blockinfo['header']['previous_hash'];
462 |
463 |
464 |
465 | for ( let ind = 0 ; ind{
553 |
554 |
555 |
556 | }
557 |
558 |
559 |
560 |
561 | var modify_peer_chaincode = async ( peers )=>{
562 |
563 |
564 | }
565 |
566 |
567 |
568 |
569 |
570 |
571 |
572 |
573 |
574 |
575 |
576 | exports.testfunc = testfunc;
577 | exports.getPeers4Org = getPeers4Org;
578 | exports.getPeer=getPeer;
579 | exports.ORGNAMEMAP = orgnamemap;
580 | exports.parserOrg = parserOrg;
--------------------------------------------------------------------------------
/bcexplorertest.js:
--------------------------------------------------------------------------------
1 | var bcexplorerservice = require('./bcexplorerservice');
2 |
3 |
4 | /*
5 | var orgnamemap = bcexplorerservice.ORGNAMEMAP;
6 |
7 | console.info( JSON.stringify( orgnamemap ) );*/
8 |
9 |
10 | //bcexplorerservice.testfunc('org1');
11 |
12 | bcexplorerservice.parserOrg('org1');
13 |
14 |
15 |
16 | //注册异常处理器
17 | process.on('unhandledRejection', function (err) {
18 | console.error(err.stack);
19 | });
20 |
21 | process.on(`uncaughtException`, console.error);
--------------------------------------------------------------------------------
/bitclient.js:
--------------------------------------------------------------------------------
1 | var co = require('co');
2 | var httpclient = require('./bitcoindservice');
3 |
4 |
5 |
6 | /*(co( function * () {
7 |
8 | let content = yield httpclient.httpget("http://www.hao123.com");
9 | console.info(content);
10 |
11 | }
12 |
13 | ));*/
14 |
15 |
16 | /*co((function * () {
17 |
18 | let content = yield httpclient.httpget("http://www.hao123.com");
19 | console.info(content);
20 |
21 | })())*/
22 |
23 |
24 | /*(co( function * () {
25 |
26 | let content = yield httpclient.httppostsimple("http://localhost/eshowcm1/index.php/m/nodeposttest",{a:'aaaa',b:'bbbbbbb'})
27 | console.info(content);
28 |
29 | }
30 |
31 | ));*/
32 |
33 |
34 |
35 | (co( function * () {
36 |
37 | let content = yield httpclient.bithttppost("http://192.168.23.212", 33133 , {"jsonrpc": "1.0", "id":"curltest", "method": "getblockchaininfo", "params": [] },'root','111111' )
38 | console.info(content);
39 |
40 | }
41 |
42 | ));
43 |
44 |
45 | //注册异常处理器
46 | process.on('unhandledRejection', function (err) {
47 | console.error(err.stack);
48 | });
49 |
50 | process.on(`uncaughtException`, console.error);
--------------------------------------------------------------------------------
/bitcoindservice.js:
--------------------------------------------------------------------------------
1 | var http=require('http');
2 | var querystring=require('querystring');
3 | var url = require('url')
4 |
5 |
6 | var bithttppost = function (posturl,port,postData,username,passwd) {
7 |
8 |
9 | var postDatastr=JSON.stringify(postData);
10 |
11 | var urlObj = url.parse(posturl)
12 |
13 | var loginstring = username + ":" + passwd;
14 |
15 | var loginstringbuf = new Buffer( loginstring );
16 | var cred = loginstringbuf.toString('base64');
17 |
18 |
19 | var options={
20 | hostname:urlObj.hostname,
21 | port:port,
22 | path: urlObj.pathname,
23 | method:'POST',
24 | headers:{
25 |
26 | 'Content-Type':'text/plain',
27 | 'Content-Length':Buffer.byteLength(postDatastr),
28 | 'Authorization': `Basic ${cred}`
29 | }
30 | }
31 |
32 | return httppost(options,postDatastr);
33 |
34 | }
35 |
36 |
37 | var httppost = function (options,postData) {
38 |
39 | return new Promise(( resolve,reject)=>{
40 |
41 |
42 | var buffers = [];
43 | var req=http.request(options, function(res) {
44 |
45 |
46 | res.on('data',function(reposebuffer){
47 |
48 | buffers.push(reposebuffer);
49 | });
50 | res.on('end',function(){
51 | //console.log('No more data in response.********');
52 | var wholeData = Buffer.concat(buffers);
53 | var dataStr = wholeData.toString('utf8');
54 | resolve(dataStr)
55 | });
56 |
57 | res.on('error',function(err){
58 | reject(err);
59 | });
60 |
61 | });
62 |
63 | req.write(postData);
64 | req.end();
65 |
66 | })
67 |
68 |
69 | }
70 |
71 |
72 | exports.httppost =httppost;
73 | exports.bithttppost = bithttppost;
74 |
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/bitmain.js:
--------------------------------------------------------------------------------
1 | var co = require('co');
2 | var bitcoindservice = require('./bitcoindservice')
3 | var express = require('express');
4 |
5 |
6 | var app = express();
7 |
8 |
9 | var bitcoind_host = "http://192.168.23.212";
10 | var bitcoind_port = 33133;
11 | var bitcoind_username = "root";
12 | var bitcoind_passwd = "111111";
13 |
14 | //获取当前比特币系统的区块信息
15 |
16 | app.get('/getblockchaininfo', function (req, res) {
17 |
18 | co( function * () {
19 |
20 | var bitcommand = {"jsonrpc": "1.0", "id":"curltest", "method": "getblockchaininfo", "params": [] };
21 | let content = yield bitcoindservice.bithttppost(bitcoind_host, bitcoind_port , bitcommand ,bitcoind_username,bitcoind_passwd);
22 | res.send( content );
23 |
24 |
25 | }).catch((err) => {
26 | res.send(err);
27 | })
28 |
29 | });
30 |
31 |
32 | //获取当前比特币系统的网络信息
33 | app.get('/getnetworkinfo', function (req, res) {
34 |
35 | co( function * () {
36 |
37 | var bitcommand = {"jsonrpc": "1.0", "id":"curltest", "method": "getnetworkinfo", "params": [] };
38 | let content = yield bitcoindservice.bithttppost(bitcoind_host, bitcoind_port , bitcommand ,bitcoind_username,bitcoind_passwd);
39 | res.send( content );
40 |
41 |
42 | }).catch((err) => {
43 | res.send(err);
44 | })
45 |
46 |
47 | });
48 |
49 |
50 | //获取当前钱包信息
51 | app.get('/getwalletinfo', function (req, res) {
52 |
53 | co( function * () {
54 |
55 | var bitcommand = {"jsonrpc": "1.0", "id":"curltest", "method": "getwalletinfo", "params": [] };
56 | let content = yield bitcoindservice.bithttppost(bitcoind_host, bitcoind_port , bitcommand ,bitcoind_username,bitcoind_passwd);
57 | res.send( content );
58 |
59 |
60 | }).catch((err) => {
61 | res.send(err);
62 | })
63 |
64 |
65 | });
66 |
67 |
68 | //根据区块的高度获取区块链的hash值
69 | app.get('/getblockhash', function (req, res) {
70 |
71 | co( function * () {
72 |
73 | var bitcommand = {"jsonrpc": "1.0", "id":"curltest", "method": "getblockhash", "params": [0] };
74 | let content = yield bitcoindservice.bithttppost(bitcoind_host, bitcoind_port , bitcommand ,bitcoind_username,bitcoind_passwd);
75 | res.send( content );
76 |
77 |
78 | }).catch((err) => {
79 | res.send(err);
80 | })
81 |
82 |
83 | });
84 |
85 |
86 | //根据区块的hash值,获取区块链的详细信息
87 | app.get('/getblock', function (req, res) {
88 |
89 | co( function * () {
90 |
91 | var bitcommand = {"jsonrpc": "1.0", "id":"curltest", "method": "getblock", "params": ["000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"] };
92 | let content = yield bitcoindservice.bithttppost(bitcoind_host, bitcoind_port , bitcommand ,bitcoind_username,bitcoind_passwd);
93 | res.send( content );
94 |
95 |
96 | }).catch((err) => {
97 | res.send(err);
98 | })
99 |
100 |
101 | });
102 |
103 |
104 | //模拟发起一笔交易
105 |
106 |
107 | app.get('/sendTransaction', function (req, res) {
108 |
109 | co( function * () {
110 |
111 |
112 |
113 | }).catch((err) => {
114 | res.send(err);
115 | })
116 |
117 |
118 | });
119 |
120 |
121 |
122 |
123 | //启动http服务
124 | var server = app.listen(3000, function () {
125 | var host = server.address().address;
126 | var port = server.address().port;
127 |
128 | console.log('Example app listening at http://%s:%s', host, port);
129 | });
130 |
131 |
132 | //注册异常处理器
133 | process.on('unhandledRejection', function (err) {
134 | console.error(err.stack);
135 | });
136 |
137 | process.on(`uncaughtException`, console.error);
--------------------------------------------------------------------------------
/config.json:
--------------------------------------------------------------------------------
1 | {
2 |
3 | "orgs": [{
4 | "name": "org1",
5 | "mspid": "Org1MSP",
6 | "peers": [
7 | {
8 | "name": "peer1",
9 | "requests": "192.168.23.212:7051",
10 | "events": "192.168.23.212:7053",
11 | "server-hostname": "peer0.org1.robertfabrictest.com",
12 | "tls_cacerts": "/first-network/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt"
13 | },
14 | {
15 | "name": "peer2",
16 | "requests": "172.16.10.186:7051",
17 | "events": "172.16.10.186:7053",
18 | "server-hostname": "peer1.org1.robertfabrictest.com",
19 | "tls_cacerts": "/first-network/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt"
20 | },
21 | {
22 | "name": "peer3",
23 | "requests": "172.16.10.187:7051",
24 | "events": "172.16.10.187:7053",
25 | "server-hostname": "peer2.org1.robertfabrictest.com",
26 | "tls_cacerts": "/first-network/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt"
27 | }
28 |
29 | ],
30 | "admin": {
31 | "key": "/project/opt_fabric/fabricconfig/crypto-config/peerOrganizations/org1.robertfabrictest.com/users/Admin@org1.robertfabrictest.com/msp/keystore",
32 | "cert": "/project/opt_fabric/fabricconfig/crypto-config/peerOrganizations/org1.robertfabrictest.com/users/Admin@org1.robertfabrictest.com/msp/signcerts"
33 | }
34 | }],
35 |
36 | "host": "localhost",
37 | "port": "8080",
38 | "keyValueStore": "/project/ws_nodejs/fabric_sdk_node_studynew/fabric-client-kvs",
39 | "eventWaitTime": "30000",
40 | "enableTls":false,
41 | "mysql": {
42 | "host": "localhost",
43 | "port": "3306",
44 | "database": "blockchainexplorer",
45 | "username": "root",
46 | "passwd": "123456"
47 | }
48 | }
--------------------------------------------------------------------------------
/cryutil.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by shouhewu on 6/11/17.
3 | */
4 | var util=require('fabric-ca-client/lib/utils')
5 | var fs=require('fs')
6 |
7 |
8 | var cryptoSuit=util.newCryptoSuite({algorithm:'ec',hash:'sha2'})
9 | var cryptoKeyStore=util.newCryptoKeyStore({path: '/tmp/app-state-store'})
10 | cryptoSuit.setCryptoKeyStore(cryptoKeyStore)
11 |
12 | /*cryptoSuit.generateKey().then(key => {
13 | //generate csr
14 | var csr =key.generateCSR('CN=gcc2ge')
15 | console.info(csr)
16 |
17 | }).catch(err => {
18 | console.info(err)
19 | });*/
20 |
21 |
22 | //get private key by ski
23 | //create private key
24 | cryptoSuit.getKey('8a4ed8278fd021fddcad61d3691f086da70dc19c40d243a7da4029c88cdd9ae9').then(key=>{
25 | console.info( key._key.prvKeyHex )
26 | // console.info(key.getSKI())
27 | var pkey=key.getPublicKey()
28 | console.info( pkey._key.pubKeyHex )
29 | }).catch(err =>{
30 | console.info( err )
31 | })
32 |
33 |
34 | //import private key
35 | /*
36 | var key=fs.readFileSync(__dirname+"/artifacts/users/User1@org1.example.com/msp/keystore/9f333d17a7770b9bac7fec965a203a50f04080b11e3cf336b474719b6fc2f863_sk")
37 | cryptoSuit.importKey(key).then(key =>{
38 | console.info(key)
39 | })
40 | */
--------------------------------------------------------------------------------
/db/dbtemplement.js:
--------------------------------------------------------------------------------
1 | var blocks = {
2 | 'channelname':channelname,
3 | 'blocknum':blocknum,
4 | 'datahash':datahash,
5 | 'perhash':perhash,
6 | 'txcount':txcount,
7 | 'createdt':createdt,
8 | 'remark':remark,
9 | };
10 | var ca = {
11 | 'org_name':org_name,
12 | 'ca_name':ca_name,
13 | 'ca_request':ca_request,
14 | 'ca_config_path':ca_config_path,
15 | 'createdt':createdt,
16 | 'remark':remark,
17 | };
18 | var chaincodes = {
19 | 'peerid':peerid,
20 | 'channelname':channelname,
21 | 'name':name,
22 | 'version':version,
23 | 'path':path,
24 | 'escc':escc,
25 | 'vscc':vscc,
26 | 'txcount':txcount,
27 | 'ccstatus':ccstatus,
28 | 'createdt':createdt,
29 | 'remark':remark,
30 | };
31 | var channel = {
32 | 'channelname':channelname,
33 | 'blocks':blocks,
34 | 'countblocks':countblocks,
35 | 'trans':trans,
36 | 'createdt':createdt,
37 | 'remark':remark,
38 | };
39 | var keyset = {
40 | 'channelname':channelname,
41 | 'blocknum':blocknum,
42 | 'blockhash':blockhash,
43 | 'transactionhash':transactionhash,
44 | 'keyname':keyname,
45 | 'isdelete':isdelete,
46 | 'chaincode':chaincode,
47 | 'transnums':transnums,
48 | 'createdt':createdt,
49 | 'remark':remark,
50 | };
51 | var orderer = {
52 | 'blocknum':blocknum,
53 | 'datahash':datahash,
54 | 'orderer_config':orderer_config,
55 | 'createdt':createdt,
56 | 'remark':remark,
57 | };
58 | var org = {
59 | 'name':name,
60 | 'mspid':mspid,
61 | 'adminkey':adminkey,
62 | 'admincert':admincert,
63 | 'createdt':createdt,
64 | 'remark':remark,
65 | };
66 | var org_ref_channel = {
67 | 'name':name,
68 | 'channelid':channelid,
69 | };
70 | var peer = {
71 | 'mspid':mspid,
72 | 'name':name,
73 | 'requests':requests,
74 | 'events':events,
75 | 'peer_config':peer_config,
76 | 'createdt':createdt,
77 | 'remark':remark,
78 | };
79 | var peer_ref_channel = {
80 | 'peer_name':peer_name,
81 | 'channelname':channelname,
82 | };
83 | var transaction = {
84 | 'channelname':channelname,
85 | 'blocknum':blocknum,
86 | 'blockhash':blockhash,
87 | 'txhash':txhash,
88 | 'txcreatedt':txcreatedt,
89 | 'chaincodename':chaincodename,
90 | 'createdt':createdt,
91 | 'remark':remark,
92 | };
93 | var write_lock = {
94 | 'write_lock':write_lock,
95 | };
96 |
97 |
98 | var keyset_history = {
99 | 'channelname':channelname,
100 | 'blocknum':blocknum,
101 | 'blockhash':blockhash,
102 | 'transactionhash':transactionhash,
103 | 'keyname':keyname,
104 | 'values':values,
105 | 'trandtstr':trandtstr,
106 | 'remark':remark,
107 | };
108 |
109 | var keyset = {
110 | 'channelname':channelname,
111 | 'blocknum':blocknum,
112 | 'blockhash':blockhash,
113 | 'transactionhash':transactionhash,
114 | 'keyname':keyname,
115 | 'isdelete':isdelete,
116 | 'values':values,
117 | 'chaincode':chaincode,
118 | 'trandtstr':trandtstr,
119 | 'transnums':transnums,
120 | 'createdt':createdt,
121 | 'remark':remark,
122 | };
123 |
124 |
125 |
126 |
127 | /*"mysql": {
128 | "host": "172.16.10.86",
129 | "port": "3306",
130 | "database": "blockchainexplorer",
131 | "username": "root",
132 | "passwd": "q1w2e3r4t%"
133 | },*/
--------------------------------------------------------------------------------
/db/mysqlservice.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright ONECHAIN 2017 All Rights Reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | var mysql = require('mysql');
18 | var config = require('../config.json');
19 | var mysqlconfig=config.mysql;
20 |
21 | var log4js = require('log4js');
22 | var logger = log4js.getLogger('mysqlservice');
23 | logger.setLevel('INFO');
24 |
25 |
26 |
27 | var connection
28 |
29 |
30 |
31 | function handleDisconnect() {
32 |
33 | var port = mysql.port?mysql.port:"3306";
34 |
35 | // Recreate the connection, since
36 | // the old one cannot be reused.
37 | connection = mysql.createConnection({
38 | host: mysqlconfig.host,
39 | port: port,
40 | user: mysqlconfig.username,
41 | password: mysqlconfig.passwd,
42 | database:mysqlconfig.database
43 | });
44 |
45 | connection.connect(function(err) {
46 | // The server is either down
47 | // or restarting
48 | if(err) {
49 | // We introduce a delay before attempting to reconnect,
50 | // to avoid a hot loop, and to allow our node script to
51 | // process asynchronous requests in the meantime.
52 | console.log('error when connecting to db:', err);
53 | setTimeout(handleDisconnect, 2000);
54 | }
55 | });
56 | connection.on('error', function(err) {
57 | console.log('db error', err);
58 | if(err.code === 'PROTOCOL_CONNECTION_LOST') {
59 | handleDisconnect();
60 | }else{
61 | throw err;
62 | }
63 | });
64 | }
65 |
66 | handleDisconnect()
67 |
68 | //open connection
69 | function openconnection() {
70 | connection.connect()
71 | }
72 |
73 | //close connection
74 | function closeconnection() {
75 | connection.end()
76 | }
77 |
78 | /**
79 | *
80 | * Save the value to db.
81 | *
82 | * @param String tablename the table name.
83 | * @param String array ColumnValues the table column and value Map.
84 | *
85 | * @author robertfeng
86 | *
87 | */
88 | function saveRow( tablename , columnValues ){
89 |
90 |
91 | return new Promise(function (resolve,reject){
92 |
93 | var addSqlParams = []
94 | var updatesqlcolumn = []
95 | var updatesqlflag = []
96 |
97 | Object.keys(columnValues).forEach((k)=>{
98 |
99 | let v = columnValues[k]
100 |
101 | addSqlParams.push(v)
102 | updatesqlcolumn.push(k)
103 | updatesqlflag.push('?')
104 |
105 | })
106 |
107 | var updatesqlparmstr = updatesqlcolumn.join(',')
108 | var updatesqlflagstr = updatesqlflag.join(',')
109 |
110 |
111 | var addSql = `INSERT INTO ${tablename} ( ${updatesqlparmstr} ) VALUES( ${updatesqlflagstr} )`;
112 |
113 | logger.debug(`Insert sql is ${addSql}`)
114 |
115 | connection.query(addSql,addSqlParams,function (err, result) {
116 |
117 | if(err){
118 | logger.error('[INSERT ERROR] - ',err.message);
119 | reject(err)
120 | }
121 |
122 | logger.debug('--------------------------INSERT----------------------------');
123 | logger.debug('INSERT ID:',result.insertId);
124 | logger.debug('-----------------------------------------------------------------\n\n');
125 |
126 | resolve(result.insertId)
127 | });
128 | })
129 |
130 |
131 |
132 |
133 | }
134 |
135 |
136 | /**
137 | * Update table
138 | *
139 | * @param String tablename the table name.
140 | * @param String array columnAndValue the table column and value Map.
141 | * @param String pkName the primary key name.
142 | * @param String pkValue the primary key value.
143 | *
144 | * @author robertfeng
145 | *
146 | *
147 | */
148 | function updateRowByPk(tablename,columnAndValue,pkName,pkValue){
149 |
150 | return new Promise(function (resolve,reject){
151 |
152 | var addSqlParams = []
153 | var updateParms = []
154 |
155 | var updateparm = " set 1=1 "
156 |
157 | Object.keys(columnAndValue).forEach((k)=>{
158 |
159 | let v = columnAndValue[k]
160 |
161 | addSqlParams.push(v)
162 | //updateparm = updateparm + ` ,${k}=? `
163 | updateParms.push(`${k} = ?`)
164 |
165 | })
166 |
167 | var updatewhereparm = " (1=1) "
168 | var searchparm = {pkName:pkValue}
169 |
170 | Object.keys(searchparm).forEach((k)=>{
171 |
172 | let v = searchparm[k]
173 |
174 | addSqlParams.push(v)
175 | updatewhereparm = updatewhereparm+` and ${k}=? `
176 |
177 | })
178 |
179 | var updateParmsStr = updateParms.join(',')
180 |
181 | var addSql = ` UPDATE ${tablename} set ${updateParmsStr} WHERE ${pkName} = ${pkValue} `;
182 |
183 | logger.debug(`update sql is ${addSql}`)
184 |
185 | connection.query(addSql,addSqlParams,function (err, result) {
186 |
187 | if(err){
188 | logger.error('[INSERT ERROR] - ',err.message);
189 | reject(err)
190 | }
191 |
192 | logger.debug('--------------------------UPDATE----------------------------');
193 | logger.debug(' update result :',result.affectedRows );
194 | logger.debug('-----------------------------------------------------------------\n\n');
195 |
196 | resolve(result.affectedRows)
197 | });
198 | })
199 |
200 |
201 |
202 | }
203 |
204 |
205 | /**
206 | * Update table
207 | *
208 | * @param String tablename the table name.
209 | * @param String array columnAndValue the table column and value Map.
210 | * @param String array condition the primary key name.
211 | * @param db ojbect DB the sqllite private database visit object
212 | *
213 | * @author robertfeng
214 | *
215 | *
216 | */
217 | function updateRow(tablename,columnAndValue,condition){
218 |
219 |
220 | return new Promise(function (resolve,reject){
221 |
222 | var addSqlParams = []
223 | var updateParms = []
224 |
225 | var updateparm = " set 1=1 "
226 |
227 |
228 | Object.keys(columnAndValue).forEach((k)=>{
229 |
230 | let v = columnAndValue[k]
231 |
232 | addSqlParams.push(v)
233 | //updateparm = updateparm + ` ,${k}=? `
234 | updateParms.push(`${k} = ?`)
235 |
236 | })
237 |
238 | var updatewhereparm = " (1=1) "
239 |
240 |
241 | Object.keys(condition).forEach((k)=>{
242 |
243 | let v = condition[k]
244 |
245 | addSqlParams.push(v)
246 | updatewhereparm = updatewhereparm+` and ${k}=? `
247 |
248 | })
249 |
250 |
251 | var updateParmsStr = updateParms.join(',')
252 |
253 | var addSql = ` UPDATE ${tablename} set ${updateParmsStr} WHERE ${updatewhereparm} `;
254 |
255 | logger.debug(`update sql is ${addSql}`)
256 |
257 | connection.query(addSql,addSqlParams,function (err, result) {
258 |
259 | if(err){
260 | logger.error('[INSERT ERROR] - ',err.message);
261 | reject(err)
262 | }
263 |
264 | logger.debug('--------------------------UPDATE----------------------------');
265 | logger.debug(' update result :',result.affectedRows );
266 | logger.debug('-----------------------------------------------------------------\n\n');
267 |
268 | resolve(result.affectedRows)
269 | });
270 | })
271 |
272 | }
273 |
274 |
275 | /**
276 | * excute update or delete sql.
277 | * @param string updateSql the excute sql
278 | */
279 | function updateBySql(updateSql){
280 |
281 | return new Promise(function (resolve,reject){
282 |
283 |
284 | logger.debug(`update sql is : ${updateSql}`)
285 |
286 | connection.query(updateSql,[],function (err, result) {
287 |
288 | if(err){
289 | logger.error('[INSERT ERROR] - ',err.message);
290 | reject(err)
291 | }
292 |
293 | logger.debug('--------------------------UPDATE----------------------------');
294 | logger.debug(' update result :',result.affectedRows );
295 | logger.debug('-----------------------------------------------------------------\n\n');
296 |
297 | resolve(result.affectedRows)
298 | });
299 | })
300 |
301 |
302 | }
303 |
304 |
305 | /**
306 | * get row by primary key
307 | * @param String tablename the table name.
308 | * @param String column the filed of search result.
309 | * @param String pkColumn the primary key column name.
310 | * @param String value the primary key value.
311 | *
312 | *
313 | */
314 | function getRowByPk(tablename,column,pkColumn,value){
315 |
316 |
317 | return new Promise(function (resolve,reject){
318 |
319 | if( column == '' )
320 | column = '*'
321 |
322 | var sql = ` select ${column} from ${tablename} where ${pkColumn} = ${value} `
323 |
324 | connection.query(sql, function(err, rows, fields ) {
325 |
326 | if (err){
327 | reject(err)
328 | }
329 |
330 | // console.log( `The solution is: ${rows.length } ` );
331 | logger.debug(' the getRowByPk ')
332 |
333 | if( !rows || rows.length == 0 )
334 | resolve(null)
335 | else
336 | resolve(rows[0])
337 | });
338 | })
339 |
340 |
341 | }
342 |
343 | /**
344 | *
345 | *
346 | * @param unknown_type sql
347 | * @param unknown_type DB
348 | * @return unknown
349 | */
350 | function getRowByPkOne(sql){
351 |
352 | return new Promise(function (resolve,reject){
353 |
354 | //var sql = ` select ${column} from ${tablename} where ${pkColumn} = ${value} `
355 |
356 | connection.query(sql, function(err, rows, fields ) {
357 |
358 | if (err){
359 | reject(err)
360 | }
361 |
362 | // console.log( `The solution is: ${rows.length } ` );
363 | logger.debug(` the getRowByPkOne sql ${sql}`)
364 |
365 |
366 | if( !rows || rows.length == 0 )
367 | resolve(null)
368 | else
369 | resolve(rows[0])
370 |
371 |
372 | });
373 | })
374 |
375 | }
376 |
377 |
378 | /**
379 | * search table
380 | * @param String tablename the table name
381 | * @param String columns the field of seach result
382 | * @param String ondtion the search condition,it is sotre by array. exp condition = array("id"=>"1");
383 | * @param String orderBy the order desc.
384 | * @param String limit the pagedtion.
385 | *
386 | */
387 | function getRowsByCondition(tablename,column ,condtion,orderBy,limit){
388 |
389 |
390 | return new Promise(function (resolve,reject){
391 |
392 | if( column == '' )
393 | column = '*'
394 |
395 | var updatewhereparm = " (1=1) "
396 | var searchparm = {pkName:pkValue}
397 | var addSqlParams = []
398 |
399 | Object.keys( condtion ).forEach((k)=>{
400 |
401 | let v = condtion[k]
402 |
403 | addSqlParams.push(v)
404 | updatewhereparm = updatewhereparm+` and ${k}=? `
405 |
406 | })
407 |
408 |
409 |
410 | var sql = ` select ${column} from ${tablename} where ${updatewhereparm} ${orderBy} ${limit}`
411 |
412 | logger.debug(` the search sql is : ${sql} `)
413 |
414 |
415 |
416 | connection.query(sql, function(err, rows, fields ) {
417 |
418 | if (err){
419 | reject(err)
420 | }
421 |
422 | // console.log( `The solution is: ${rows.length } ` );
423 | logger.debug(' the getRowsByCondition ')
424 |
425 | resolve(rows)
426 |
427 |
428 |
429 | });
430 | })
431 |
432 | }
433 |
434 |
435 | /**
436 | * search table by sql
437 | * @param datatype sqlchareter the table name
438 | * @param datatype ondtion the search condition,it is sotre by array. exp condition = array("id"=>"1");
439 | * @param datatype limit the pagedtion.
440 | *
441 | */
442 | function getRowsBySQl(sqlchareter,condition,limit){
443 |
444 | return new Promise(function (resolve,reject){
445 |
446 |
447 | var updatewhereparm = " (1=1) "
448 | var addSqlParams = []
449 |
450 | Object.keys( condition ).forEach((k)=>{
451 |
452 | let v = condition[k]
453 |
454 | addSqlParams.push(v)
455 | updatewhereparm = updatewhereparm + ` and ${k}=? `
456 |
457 | })
458 |
459 |
460 | var sql = ` ${sqlchareter} where ${updatewhereparm} ${limit}`
461 |
462 | logger.debug(` the search sql is : ${sql} `)
463 |
464 |
465 | connection.query(sql, addSqlParams ,function(err, rows, fields ) {
466 |
467 | if (err){
468 | reject(err)
469 | }
470 |
471 | console.log( ` The solution is: ${rows.length } ` );
472 | logger.debug( ' The getRowsBySQl ')
473 |
474 | resolve(rows)
475 |
476 | });
477 | })
478 |
479 |
480 | }
481 |
482 |
483 |
484 | /**
485 | * search table by sql and it's not condtion
486 | *
487 | * @param datatype sqlchareter the table name
488 | * @param datatype ondtion the search condition,it is sotre by array. exp condition = array("id"=>"1");
489 | * @param datatype limit the pagedtion.
490 | *
491 | */
492 | function getRowsBySQlNoCondtion(sqlchareter,limit){
493 |
494 | return new Promise(function (resolve,reject){
495 |
496 |
497 | var sql = `${sqlchareter} ${limit}`
498 |
499 | connection.query(sqlchareter, function(err, rows, fields ) {
500 |
501 | if (err){
502 | reject(err)
503 | }
504 |
505 | // console.log( `The solution is: ${rows.length } ` );
506 | logger.debug(` the getRowsBySQlNoCondtion ${sql}`)
507 |
508 |
509 | resolve(rows)
510 |
511 | });
512 | })
513 |
514 |
515 | }
516 |
517 | /**
518 | * 自动橱窗日志查找/评价历史记录查找
519 | * @param unknown_type sql
520 | * @param unknown_type DB
521 | * @return unknown
522 | */
523 | function getRowsBySQlCase(sql){
524 |
525 | return new Promise(function (resolve,reject){
526 |
527 |
528 |
529 | connection.query(sql, function(err, rows, fields ) {
530 |
531 | if (err){
532 | reject(err)
533 | }
534 |
535 | // console.log( `The solution is: ${rows.length } ` );
536 | logger.debug(` the getRowsBySQlCase ${sql}`)
537 |
538 | if( !rows || rows.length == 0 )
539 | resolve(null)
540 | else
541 | resolve(rows[0])
542 |
543 |
544 | });
545 | })
546 | }
547 |
548 |
549 | /**
550 | *
551 | * @param sql
552 | * @param key
553 | * @returns {Promise}
554 | *
555 | */
556 | function getSQL2Map(sql,key){
557 |
558 | return new Promise(function (resolve,reject){
559 |
560 | connection.query(sql, function(err, rows, fields ) {
561 |
562 | if (err){
563 | reject(err)
564 | }
565 |
566 | logger.debug( `The solution is: ${rows.length } ` );
567 |
568 |
569 | var keymap = new Map();
570 |
571 | for( var ind = 0 ; ind}
61 | */
62 | var getBlockChainInfo = function( channelid , peerRequest ){
63 |
64 | let channel = getchannel(channelid);
65 | let peer = getpeer(peerRequest);
66 |
67 | setupchannel(channel,peer,channelid,peerRequest);
68 |
69 | return getOrgUser4Local().then((user)=>{
70 |
71 | return channel.queryInfo(peer);
72 |
73 | } ,(err)=>{
74 |
75 | console.log( 'error' , err );
76 | } )
77 |
78 | }
79 |
80 | /**
81 | * 根据区块链的编号获取区块的详细信息
82 | *
83 | * @param blocknum
84 | * @returns {Promise.}
85 | *
86 | */
87 | var getblockInfobyNum = function (channelid , peerRequest ,blocknum) {
88 |
89 | let channel = getchannel(channelid);
90 | let peer = getpeer(peerRequest);
91 |
92 |
93 | setupchannel(channel,peer,channelid,peerRequest);
94 |
95 |
96 | return getOrgUser4Local().then((user)=>{
97 |
98 | return channel.queryBlock(blocknum, peer,null);
99 |
100 | } ,(err)=>{
101 | console.log( 'error' , err);
102 | } )
103 |
104 | }
105 |
106 | /**
107 | * 根据区块链的哈希值获取区块的详细信息
108 | *
109 | * @param blocknum
110 | * @returns {Promise.}
111 | *
112 | */
113 | var getblockInfobyHash = function ( channelid , peerRequest , blockHash ) {
114 |
115 | let channel = getchannel(channelid);
116 | let peer = getpeer(peerRequest);
117 | setupchannel(channel,peer,channelid,peerRequest);
118 |
119 | return getOrgUser4Local().then(( user )=>{
120 |
121 | return channel.queryBlockByHash(new Buffer(blockHash,"hex"),peer)
122 |
123 | } ,(err)=>{
124 |
125 | console.log('error', err);
126 |
127 | } )
128 |
129 | }
130 |
131 |
132 |
133 | /**
134 | *
135 | * 获取当前Peer节点加入的通道信息
136 | *
137 | * @param blocknum
138 | * @returns {Promise.}
139 | *
140 | */
141 | var getPeerChannel = function ( peerRequest ) {
142 |
143 |
144 | let peer = getpeer(peerRequest);
145 |
146 | return getOrgUser4Local().then(( user )=>{
147 |
148 | return client.queryChannels(peer)
149 |
150 | } ,(err)=>{
151 |
152 | console.log('error', err);
153 | } )
154 |
155 | }
156 |
157 | /**
158 | *
159 | * 查询指定peer节点已经install的chaincode
160 | *
161 | * @param blocknum
162 | * @returns {Promise.}
163 | *
164 | */
165 | var getPeerInstallCc = function ( peerRequest ) {
166 |
167 | let peer = getpeer(peerRequest);
168 |
169 | return getOrgUser4Local().then(( user )=>{
170 |
171 | return client.queryInstalledChaincodes(peer)
172 |
173 | } ,(err)=>{
174 |
175 | console.log('error', err);
176 | } )
177 |
178 | }
179 |
180 |
181 |
182 | /**
183 | *
184 | * 查询指定channel中已经实例化的Chaincode
185 | *
186 | * @param blocknum
187 | * @returns {Promise.}
188 | *
189 | */
190 | var getPeerInstantiatedCc = function ( channelid , peerRequest ) {
191 |
192 | let channel = getchannel(channelid);
193 | let peer = getpeer(peerRequest);
194 | setupchannel(channel,peer,channelid,peerRequest);
195 |
196 | return getOrgUser4Local().then(( user )=>{
197 |
198 | return channel.queryInstantiatedChaincodes( peer )
199 |
200 | } ,(err)=>{
201 |
202 | console.log('error', err);
203 |
204 | } )
205 |
206 | }
207 |
208 |
209 | var getTransaction = function (channelid , peerRequest ,transhash) {
210 |
211 | let channel = getchannel(channelid);
212 | let peer = getpeer(peerRequest);
213 | setupchannel(channel,peer,channelid,peerRequest);
214 |
215 | return getOrgUser4Local().then( (user)=>{
216 |
217 | return channel.queryTransaction(transhash, peer);
218 |
219 | },(err)=>{
220 | console.log('error',err);
221 | })
222 |
223 | }
224 |
225 |
226 | /**
227 | * 查询交易
228 | * @param chaincodeid
229 | * @param func
230 | * @param chaincode_args
231 | * @returns {Promise}
232 | */
233 | var queryCc = function (chaincodeid , func , chaincode_args ) {
234 |
235 |
236 | return getOrgUser4Local().then(( user )=>{
237 |
238 |
239 |
240 | tx_id = client.newTransactionID();
241 | var request = {
242 | chaincodeId: chaincodeid,
243 | txId: tx_id,
244 | fcn: func,
245 | args: chaincode_args
246 | };
247 |
248 | return channel.queryByChaincode( request , peer );
249 |
250 | } ,(err)=>{
251 |
252 | console.log('error', err);
253 |
254 | } ).then(( sendtransresult )=>{
255 |
256 | return sendtransresult;
257 |
258 | },(err)=>{
259 | console.log('error', err);
260 | });
261 |
262 |
263 | }
264 |
265 |
266 | /**
267 | * 发起一笔交易
268 | *
269 | * @returns {Promise.}
270 | */
271 | var sendTransaction = function ( chaincodeid , func , chaincode_args ) {
272 |
273 |
274 | var tx_id = null;
275 |
276 | return getOrgUser4Local().then((user)=>{
277 |
278 | tx_id = client.newTransactionID();
279 | var request = {
280 |
281 | chaincodeId: chaincodeid,
282 | fcn: func,
283 | args: chaincode_args,
284 | chainId: channelid,
285 | txId: tx_id
286 | };
287 |
288 |
289 | return channel.sendTransactionProposal(request);
290 |
291 | } ,(err)=>{
292 |
293 | console.log('error', err);
294 |
295 | } ).then((chaincodeinvokresult )=>{
296 |
297 |
298 | var proposalResponses = chaincodeinvokresult[0];
299 | var proposal = chaincodeinvokresult[1];
300 | var header = chaincodeinvokresult[2];
301 | var all_good = true;
302 |
303 |
304 | for (var i in proposalResponses) {
305 |
306 | let one_good = false;
307 | if (proposalResponses && proposalResponses[0].response &&
308 | proposalResponses[0].response.status === 200) {
309 | one_good = true;
310 | console.info('transaction proposal was good');
311 | } else {
312 | console.error('transaction proposal was bad');
313 | }
314 | all_good = all_good & one_good;
315 | }
316 |
317 |
318 | if (all_good) {
319 |
320 | console.info(util.format(
321 |
322 | 'Successfully sent Proposal and received ProposalResponse: Status - %s, message - "%s", metadata - "%s", endorsement signature: %s',
323 | proposalResponses[0].response.status, proposalResponses[0].response.message,
324 | proposalResponses[0].response.payload, proposalResponses[0].endorsement
325 | .signature));
326 |
327 |
328 | var request = {
329 | proposalResponses: proposalResponses,
330 | proposal: proposal,
331 | header: header
332 | };
333 | // set the transaction listener and set a timeout of 30sec
334 | // if the transaction did not get committed within the timeout period,
335 | // fail the test
336 | var transactionID = tx_id.getTransactionID();
337 |
338 | return channel.sendTransaction(request);
339 |
340 |
341 | }
342 |
343 |
344 |
345 | },(err)=>{
346 |
347 | console.log('error', err);
348 | }).then(( sendtransresult )=>{
349 |
350 | return sendtransresult;
351 |
352 | },(err)=>{
353 | console.log('error', err);
354 | });
355 |
356 | }
357 |
358 |
359 | /**
360 | *
361 | * 根据cryptogen模块生成的账号通过Fabric接口进行相关的操作
362 | *
363 | * @returns {Promise.}
364 | *
365 | */
366 | function getOrgUser4Local() {
367 |
368 | //测试通过CA命令行生成的证书依旧可以成功的发起交易
369 | /*let keyPath = "/project/opt_fabric/fabricconfig/crypto-config/peerOrganizations/org1.robertfabrictest.com/users/Admin@org1.robertfabrictest.com/msp/keystore";
370 | let keyPEM = Buffer.from(readAllFiles(keyPath)[0]).toString();
371 | let certPath = "/project/opt_fabric/fabricconfig/crypto-config/peerOrganizations/org1.robertfabrictest.com/users/Admin@org1.robertfabrictest.com/msp/signcerts";
372 | let certPEM = readAllFiles(certPath)[0].toString();
373 | */
374 | let keyPath = admin_key;
375 | let keyPEM = Buffer.from(readAllFiles(keyPath)[0]).toString();
376 | let certPath = admin_sert;
377 | let certPEM = readAllFiles(certPath)[0].toString();
378 |
379 | return hfc.newDefaultKeyValueStore({
380 |
381 | path:tempdir
382 |
383 | }).then((store) => {
384 | client.setStateStore(store);
385 |
386 | return client.createUser({
387 | username: 'Admin',
388 | mspid: 'Org1MSP',
389 | cryptoContent: {
390 | privateKeyPEM: keyPEM,
391 | signedCertPEM: certPEM
392 | }
393 | });
394 | });
395 | };
396 |
397 |
398 |
399 | function readAllFiles(dir) {
400 | var files = fs.readdirSync(dir);
401 | var certs = [];
402 | files.forEach((file_name) => {
403 | let file_path = path.join(dir,file_name);
404 | let data = fs.readFileSync(file_path);
405 | certs.push(data);
406 | });
407 | return certs;
408 | }
409 |
410 |
411 |
412 | function getchannel( channel_id ) {
413 |
414 |
415 | if( channelmap[channel_id] == null){
416 | let channel = client.newChannel(channel_id);
417 | channelmap[channel_id]=channel;
418 | }
419 |
420 | return channelmap[channel_id];
421 | }
422 |
423 |
424 | function getpeer(peerRequest) {
425 |
426 | if( peermap[peerRequest] == null){
427 | let peer = client.newPeer(peerRequest);
428 | peermap[peerRequest]=peer;
429 | }
430 |
431 | return peermap[peerRequest];
432 |
433 | }
434 |
435 |
436 | function setupchannel( channel1, peer ,channel_id , peer_request) {
437 |
438 | let pkey = channel_id + peer_request;
439 |
440 | if( channelpeer[pkey] == null ){
441 | channel1.addPeer(peer);
442 | channelpeer[pkey] = peer;
443 | }
444 |
445 |
446 | }
447 |
448 |
449 |
450 | exports.inits = inits;
451 | exports.getBlockChainInfo = getBlockChainInfo;
452 | exports.getblockInfobyNum = getblockInfobyNum;
453 | exports.getblockInfobyHash = getblockInfobyHash;
454 | exports.getPeerChannel = getPeerChannel;
455 | exports.getPeerInstallCc = getPeerInstallCc;
456 | exports.getPeerInstantiatedCc = getPeerInstantiatedCc;
457 | exports.getTransaction = getTransaction;
458 | exports.sendTransaction = sendTransaction;
459 | exports.queryCc = queryCc;
--------------------------------------------------------------------------------
/fabricservice4await.js:
--------------------------------------------------------------------------------
1 | var path = require('path');
2 | var fs = require('fs');
3 | var util = require('util');
4 | var hfc = require('fabric-client');
5 | var Peer = require('fabric-client/lib/Peer.js');
6 | var EventHub = require('fabric-client/lib/EventHub.js');
7 | var User = require('fabric-client/lib/User.js');
8 | var crypto = require('crypto');
9 | var FabricCAService = require('fabric-ca-client');
10 |
11 | var hfc = require('fabric-client');
12 | var log4js = require('log4js');
13 | var logger = log4js.getLogger('Helper');
14 | logger.setLevel('DEBUG');
15 |
16 |
17 | var tempdir = "/project/ws_nodejs/fabric_sdk_node_studynew/fabric-client-kvs";
18 |
19 |
20 | let client = new hfc();
21 | var channel = client.newChannel('roberttestchannel12');
22 | var order = client.newOrderer('grpc://192.168.23.212:7050');
23 | //channel.addOrderer(order);
24 | /*var peer188 = client.newPeer('grpc://172.16.10.188:7051');
25 | channel.addPeer(peer188);*/
26 | var peer = client.newPeer('grpc://192.168.23.212:7051');
27 | channel.addPeer(peer);
28 |
29 |
30 | /**
31 | *
32 | * 获取channel的区块链信息
33 | * @returns {Promise.}
34 | *
35 | */
36 | var getBlockChainInfo = async function() {
37 |
38 |
39 |
40 | return await getOrgUser4Local().then((user)=>{
41 |
42 | return channel.queryInfo(peer);
43 |
44 | } ,(err)=>{
45 |
46 | console.log('error', e);
47 | } )
48 |
49 |
50 | }
51 |
52 |
53 | /**
54 | * 获取当前区块的
55 | *
56 | * @param blocknum
57 | * @returns {Promise.}
58 | *
59 | */
60 | var getblockInfobyBlockNum = function (blocknum) {
61 |
62 | return getOrgUser4Local().then((user)=>{
63 |
64 | return channel.queryBlock(blocknum, peer,null);
65 |
66 | } ,(err)=>{
67 |
68 | console.log('error', e);
69 | } )
70 |
71 | }
72 |
73 |
74 | /**
75 | * 发起invoker查询
76 | *
77 | * @returns {Promise.}
78 | */
79 | var sendTransaction = function ( chaincodeid , func , chaincode_args , channel ) {
80 |
81 |
82 | var tx_id = null;
83 |
84 | return getOrgUser4Local().then((user)=>{
85 |
86 | tx_id = client.newTransactionID();
87 | var request = {
88 |
89 | chaincodeId: "cc_endfinlshed",
90 | fcn: "invoke",
91 | args: ["a","b","1"],
92 | chainId: "roberttestchannel12",
93 | txId: tx_id
94 | };
95 |
96 |
97 | return channel.sendTransactionProposal(request);
98 |
99 | } ,(err)=>{
100 |
101 | console.log('error', e);
102 | } ).then((chaincodeinvokresult )=>{
103 |
104 |
105 | var proposalResponses = chaincodeinvokresult[0];
106 | var proposal = chaincodeinvokresult[1];
107 | var header = chaincodeinvokresult[2];
108 | var all_good = true;
109 |
110 |
111 | for (var i in proposalResponses) {
112 |
113 | let one_good = false;
114 | if (proposalResponses && proposalResponses[0].response &&
115 | proposalResponses[0].response.status === 200) {
116 | one_good = true;
117 | console.info('transaction proposal was good');
118 | } else {
119 | console.error('transaction proposal was bad');
120 | }
121 | all_good = all_good & one_good;
122 | }
123 |
124 |
125 | if (all_good) {
126 |
127 | console.info(util.format(
128 |
129 | 'Successfully sent Proposal and received ProposalResponse: Status - %s, message - "%s", metadata - "%s", endorsement signature: %s',
130 | proposalResponses[0].response.status, proposalResponses[0].response.message,
131 | proposalResponses[0].response.payload, proposalResponses[0].endorsement
132 | .signature));
133 |
134 |
135 | var request = {
136 | proposalResponses: proposalResponses,
137 | proposal: proposal,
138 | header: header
139 | };
140 | // set the transaction listener and set a timeout of 30sec
141 | // if the transaction did not get committed within the timeout period,
142 | // fail the test
143 | var transactionID = tx_id.getTransactionID();
144 |
145 | return channel.sendTransaction(request);
146 |
147 |
148 |
149 | }
150 |
151 |
152 |
153 | },(err)=>{
154 |
155 | logger.error(err);
156 | }).then(( sendtransresult )=>{
157 |
158 | return sendtransresult;
159 |
160 | },(err)=>{
161 | logger.error(err);
162 | });
163 |
164 | }
165 |
166 |
167 | /**
168 | *
169 | * 根据cryptogen模块生成的账号通过Fabric接口进行相关的操作
170 | *
171 | * @returns {Promise.}
172 | *
173 | */
174 | function getOrgUser4Local() {
175 |
176 | //测试通过CA命令行生成的证书依旧可以成功的发起交易
177 | var keyPath = "/project/fabric_resart/config_demo/org1/186/fabric-user/msp/keystore";
178 | var keyPEM = Buffer.from(readAllFiles(keyPath)[0]).toString();
179 | var certPath = "/project/fabric_resart/config_demo/org1/186/fabric-user/msp//signcerts";
180 | var certPEM = readAllFiles(certPath)[0].toString();
181 |
182 |
183 | return hfc.newDefaultKeyValueStore({
184 |
185 | path:tempdir
186 |
187 | }).then((store) => {
188 | client.setStateStore(store);
189 |
190 | return client.createUser({
191 | username: 'Admin',
192 | mspid: 'Org1MSP',
193 | cryptoContent: {
194 | privateKeyPEM: keyPEM,
195 | signedCertPEM: certPEM
196 | }
197 | });
198 | });
199 | };
200 |
201 |
202 |
203 | function readAllFiles(dir) {
204 | var files = fs.readdirSync(dir);
205 | var certs = [];
206 | files.forEach((file_name) => {
207 | let file_path = path.join(dir,file_name);
208 | let data = fs.readFileSync(file_path);
209 | certs.push(data);
210 | });
211 | return certs;
212 | }
213 |
214 |
215 | exports.getBlockChainInfo = getBlockChainInfo;
216 |
217 | exports.sendTransaction = sendTransaction;
--------------------------------------------------------------------------------
/functest.js:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | function testfunc() {
5 | return 1;
6 | }
7 |
8 |
9 |
10 | exports.testfunc = testfunc;
--------------------------------------------------------------------------------
/main.js:
--------------------------------------------------------------------------------
1 | var co = require('co');
2 | var fabricservice = require('./fabricservice.js')
3 | var express = require('express');
4 |
5 |
6 | var app = express();
7 |
8 |
9 | //获取当前通道的高度
10 | app.get('/getchannelheight', function (req, res) {
11 |
12 | co( function * () {
13 |
14 | var blockchaininfo = yield fabricservice.getBlockChainInfo();
15 | res.send( blockchaininfo.height.toString() );
16 |
17 | }).catch((err) => {
18 | res.send(err);
19 | })
20 |
21 | });
22 |
23 |
24 | //根据区块的编号获取区块的信息
25 | app.get('/getblockInfobyNum', function (req, res) {
26 |
27 | co( function * () {
28 |
29 | var blockinfo = yield fabricservice.getblockInfobyNum(10);
30 | res.send( JSON.stringify( blockinfo ) );
31 | }).catch((err) => {
32 | res.send(err);
33 | })
34 |
35 | });
36 |
37 |
38 |
39 | //根据区块的Hahs值来获取区块的信息
40 | app.get('/getblockInfobyHash', function (req, res) {
41 |
42 | co( function * () {
43 | var blockinfo = yield fabricservice.getblockInfobyHash("967400886bc2eca81168582211649be91fa8c0db905f301d214fefbd192000d2");
44 | res.send( JSON.stringify( blockinfo ) );
45 | }).catch((err) => {
46 | res.send(err);
47 | })
48 |
49 | });
50 |
51 |
52 |
53 | //
54 | app.get('/getPeerChannel', function (req, res) {
55 |
56 | co( function * () {
57 |
58 | var peerJoinchannels = yield fabricservice.getPeerChannel();
59 | res.send( JSON.stringify( peerJoinchannels ) );
60 | })
61 |
62 | });
63 |
64 |
65 | app.get('/sendTransaction', function (req, res) {
66 |
67 | co( function * () {
68 |
69 | var blockinfo = yield fabricservice.sendTransaction("cc_endfinlshed","invoke",["a","b","1"],"roberttestchannel12");
70 | res.send( "success" );
71 |
72 | })
73 |
74 |
75 | });
76 |
77 |
78 |
79 | //启动http服务
80 | var server = app.listen(3000, function () {
81 | var host = server.address().address;
82 | var port = server.address().port;
83 |
84 | console.log('Example app listening at http://%s:%s', host, port);
85 | });
86 |
87 |
88 | //注册异常处理器
89 | process.on('unhandledRejection', function (err) {
90 | console.error(err.stack);
91 | });
92 |
93 | process.on(`uncaughtException`, console.error);
--------------------------------------------------------------------------------
/main1.js:
--------------------------------------------------------------------------------
1 | var co = require('co');
2 | var fabricservice = require('./fabricservice4await')
3 | var testfun = require('./functest.js')
4 | var express = require('express');
5 |
6 |
7 | var app = express();
8 |
9 | app.get('/getchannelheight', function (req, res) {
10 |
11 |
12 | var blockinfo = fabricservice.getBlockChainInfo();
13 |
14 | blockinfo.then((data)=>{
15 | res.send( JSON.stringify(data ) );
16 | });
17 |
18 |
19 | });
20 |
21 |
22 | app.get('/sendtrans', function (req, res) {
23 |
24 | co( function * () {
25 |
26 | var blockinfo = yield fabricservice.sendTransaction();
27 | res.send( "success" );
28 | })
29 |
30 |
31 | });
32 |
33 |
34 |
35 |
36 |
37 | //启动http服务
38 | var server = app.listen(3000, function () {
39 | var host = server.address().address;
40 | var port = server.address().port;
41 |
42 | console.log('Example app listening at http://%s:%s', host, port);
43 | });
44 |
45 |
46 | //注册异常处理器
47 | process.on('unhandledRejection', function (err) {
48 | console.error(err.stack);
49 | });
50 |
51 | process.on(`uncaughtException`, console.error);
--------------------------------------------------------------------------------
/mainawait.js:
--------------------------------------------------------------------------------
1 |
2 | var fabricservice = require('./fabricservice.js')
3 |
4 | /*
5 | var start = async function () {
6 |
7 |
8 |
9 | try {
10 |
11 | var blockchaininfo = await fabricservice.getBlockChainInfo();
12 | console.info( JSON.stringify(blockchaininfo ) )
13 |
14 |
15 |
16 |
17 | } catch (err) {
18 | console.log(err); // 这里捕捉到错误 `error`
19 | }
20 |
21 |
22 | };
23 |
24 | start();
25 | */
26 |
27 |
28 | /*var blockchaininfo = fabricservice.getBlockChainInfo();
29 | console.info( JSON.stringify(blockchaininfo ) )*/
30 |
31 |
32 | (async ()=> {
33 |
34 | let blockchaininfo = await fabricservice.getBlockChainInfo();
35 | console.info( JSON.stringify(blockchaininfo ) )
36 |
37 |
38 |
39 | })();
40 |
41 |
--------------------------------------------------------------------------------
/mainsy.js:
--------------------------------------------------------------------------------
1 | var co = require('co');
2 | var fabricservice = require('./fabricservice.js')
3 | var express = require('express');
4 |
5 |
6 | var app = express();
7 |
8 | var cowid = "cow_001";
9 | var machiningid = "machining_001";
10 | var milk_bottle = "milk_bottle_001";
11 |
12 |
13 | var cow_cc_name = "cc_dairyfarm";
14 | var machining_cc_name = "cc_machining";
15 | var milkbottle_cc_name = "cc_salesterminal";
16 |
17 | var channelid = "";
18 |
19 |
20 | app.get('/init', function (req, res) {
21 |
22 | co( function * () {
23 |
24 | var dairyfarminitresult = yield fabricservice.sendTransaction(cow_cc_name,"invoke",["putvalue",cowid,"food"]);
25 | var machinginginitresult = yield fabricservice.sendTransaction(cow_cc_name,"invoke",["putvalue",machiningid,cowid]);
26 | var salesterminalinitresult = yield fabricservice.sendTransaction(cow_cc_name,"invoke",["putvalue",milk_bottle,machiningid]);
27 |
28 |
29 | for (let i = 0; i < chiancodequeryresutl.length; i++) {
30 |
31 | res.send( dairyfarminitresult[i].toString( 'utf8' ) );
32 |
33 | }
34 |
35 | }).catch((err) => {
36 | res.send(err);
37 | })
38 |
39 | });
40 |
41 | //奶牛场的相关操作
42 | app.get('/dairyfarm', function (req, res) {
43 |
44 |
45 | co( function * () {
46 |
47 | var parm = req.query.parms;
48 |
49 | var chiancodequeryresutl = yield fabricservice.sendTransaction(cow_cc_name,"invoke",[ "putvalue" , cowid , parm ]);
50 |
51 | for (let i = 0; i < chiancodequeryresutl.length; i++) {
52 |
53 | res.send( chiancodequeryresutl[i].toString( 'utf8' ) );
54 |
55 | }
56 |
57 | }).catch((err) => {
58 | res.send(err);
59 | })
60 |
61 | });
62 |
63 |
64 | //加工车间的操作
65 | app.get('/machining', function (req, res) {
66 |
67 | co( function * () {
68 |
69 |
70 | var parm = req.query.parms;
71 |
72 | var chiancodequeryresutl = yield fabricservice.sendTransaction(machining_cc_name,"invoke",["putvalue",machiningid,parm]);
73 |
74 | for (let i = 0; i < chiancodequeryresutl.length; i++) {
75 |
76 | res.send( chiancodequeryresutl[i].toString( 'utf8' ) );
77 |
78 | }
79 |
80 |
81 |
82 |
83 | }).catch((err) => {
84 | res.send(err);
85 | })
86 |
87 | });
88 |
89 |
90 |
91 | //销售终端的操作
92 | app.get('/salesterminal', function (req, res) {
93 |
94 | co( function * () {
95 |
96 |
97 | var parm = req.query.parms;
98 |
99 | var chiancodequeryresutl = yield fabricservice.sendTransaction(milkbottle_cc_name,"invoke",["putvalue",milk_bottle,parm]);
100 |
101 | for (let i = 0; i < chiancodequeryresutl.length; i++) {
102 |
103 | res.send( chiancodequeryresutl[i].toString( 'utf8' ) );
104 |
105 | }
106 |
107 |
108 | }).catch((err) => {
109 | res.send(err);
110 | })
111 |
112 | });
113 |
114 |
115 | //客户端查询牛奶的历史
116 | app.get('/getmilhistory', function (req, res) {
117 |
118 | co( function * () {
119 |
120 |
121 | var chiancodequeryresutl = yield fabricservice.queryCc(milkbottle_cc_name,"invoke",["getmilkhistory",milk_bottle,"a"],)
122 |
123 | for (let i = 0; i < chiancodequeryresutl.length; i++) {
124 |
125 | res.send( chiancodequeryresutl[i].toString( 'utf8' ) );
126 |
127 | }
128 |
129 |
130 | }).catch((err) => {
131 | res.send(err);
132 | })
133 |
134 | });
135 |
136 |
137 | //启动http服务
138 | var server = app.listen(3000, function () {
139 | var host = server.address().address;
140 | var port = server.address().port;
141 |
142 | console.log('Example app listening at http://%s:%s', host, port);
143 | });
144 |
145 |
146 | //注册异常处理器
147 | process.on('unhandledRejection', function (err) {
148 | console.error(err.stack);
149 | });
150 |
151 | process.on(`uncaughtException`, console.error);
--------------------------------------------------------------------------------
/network-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "network-config": {
3 | "orderer": [{
4 | "url": "grpc://127.0.0.1:7050",
5 | "server-hostname": "orderer0.example.com"
6 | },{
7 | "url": "grpc://127.0.0.1:8050",
8 | "server-hostname": "orderer1.example.com"
9 | },{
10 | "url": "grpc://127.0.0.1:9050",
11 | "server-hostname": "orderer2.example.com"
12 | }],
13 | "org1": {
14 | "name": "peerOrg1",
15 | "mspid": "Org1MSP",
16 | "ca": "http://127.0.0.1:7054",
17 | "peer1": {
18 | "requests": "grpc://127.0.0.1:7051",
19 | "events": "grpc://127.0.0.1:7053",
20 | "server-hostname": "peer0.org1.example.com"
21 | },
22 | "peer2": {
23 | "requests": "grpc://127.0.0.1:8051",
24 | "events": "grpc://127.0.0.1:8053",
25 | "server-hostname": "peer1.org1.example.com"
26 | },
27 | "admin": {
28 | "key": "/artifacts/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore",
29 | "cert": "/artifacts/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/signcerts"
30 | }
31 | },
32 | "org2": {
33 | "name": "peerOrg2",
34 | "mspid": "Org2MSP",
35 | "ca": "http://127.0.0.1:8054",
36 | "peer1": {
37 | "requests": "grpc://127.0.0.1:9051",
38 | "events": "grpc://127.0.0.1:9053",
39 | "server-hostname": "peer0.org2.example.com"
40 | },
41 | "peer2": {
42 | "requests": "grpc://127.0.0.1:10051",
43 | "events": "grpc://127.0.0.1:10053",
44 | "server-hostname": "peer1.org2.example.com"
45 | },
46 | "admin": {
47 | "key": "/artifacts/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp/keystore",
48 | "cert": "/artifacts/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp/signcerts"
49 | }
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/originservice.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/blockchain-technical-practice/fabric_sdk_node_study/ca343ecd47de36a2a74670c87ba53e147c2ed8d6/originservice.js
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fabric-explorer",
3 | "version": "0.0.1",
4 | "description": "fabric-explorer",
5 | "main": "main.js",
6 | "keywords": [
7 | "fabric-client sample app",
8 | "v1.0 fabric nodesdk sample",
9 | "alpha based nodesdk sample app"
10 | ],
11 | "engines": {
12 | "node": ">=6.9.5",
13 | "npm": ">=3.10.10"
14 | },
15 | "dependencies": {
16 | "body-parser": "^1.17.2",
17 | "co": "^4.6.0",
18 | "ejs": "^2.5.6",
19 | "express": "^4.15.3",
20 | "fabric-ca-client": "^1.0.0",
21 | "fabric-client": "^1.0.0",
22 | "fast-stats": "0.0.3",
23 | "log4js": "^0.6.38",
24 | "mysql": "^2.13.0",
25 | "prettyjson": "^1.2.1",
26 | "socket.io": "^2.0.3",
27 | "stomp-broker-js": "^0.1.3",
28 | "stompjs": "^2.3.3",
29 | "superagent": "^3.8.2",
30 | "winston": "^2.2.0"
31 | },
32 | "license": "Apache-2.0"
33 | }
34 |
--------------------------------------------------------------------------------
/pic/区块链技术实战-fabric.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/blockchain-technical-practice/fabric_sdk_node_study/ca343ecd47de36a2a74670c87ba53e147c2ed8d6/pic/区块链技术实战-fabric.jpeg
--------------------------------------------------------------------------------
/pic/区块链技术实战-以太坊.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/blockchain-technical-practice/fabric_sdk_node_study/ca343ecd47de36a2a74670c87ba53e147c2ed8d6/pic/区块链技术实战-以太坊.jpeg
--------------------------------------------------------------------------------
/test.js:
--------------------------------------------------------------------------------
1 | var testfun = require('./functest.js')
2 |
3 |
4 | testfun.testfunc();
--------------------------------------------------------------------------------