Hyperledger Fabric SDK 示例fabric-samples-《balance-transfer》之三《加入到Channel》

本文已在我的公众号Fabric技术分享原创首发。
转载请标明出处:
https://blog.csdn.net/qq_27818541/article/details/78339763
本文出自:【BigManing的博客】

前言

这篇文章展示如何把peer节点加入到channel中,其中需要两个参数

  • channelName 加入到哪个channel
  • peers 把哪个节点加进去

定义好这两个参数,然后调用相关API 就可以了。

路由

app.js

//加入到channel    Join Channel
app.post('/channels/:channelName/peers', function(req, res) {
    logger.info('<<<<<<<<<<<<<<<<< J O I N  C H A N N E L >>>>>>>>>>>>>>>>>');
    //1 校验必要参数
    var channelName = req.params.channelName;
    var peers = req.body.peers;
    logger.debug('channelName : ' + channelName);
    logger.debug('peers : ' + peers);
    if (!channelName) {
        res.json(getErrorMessage('\'channelName\''));
        return;
    }
    if (!peers || peers.length == 0) {
        res.json(getErrorMessage('\'peers\''));
        return;
    }
    //2 使用封装好js方法 来 具体实现
    join.joinChannel(channelName, peers, req.username, req.orgname)
    .then(function(message) {
        res.send(message);
    });
});

具体实现

join-channel.js

var util = require('util');
var path = require('path');
var fs = require('fs');

var Peer = require('fabric-client/lib/Peer.js');
var EventHub = require('fabric-client/lib/EventHub.js');
var tx_id = null;
var nonce = null;
var config = require('../config.json');
var helper = require('./helper.js');
var logger = helper.getLogger('Join-Channel');
//helper.hfc.addConfigFile(path.join(__dirname, 'network-config.json'));
var ORGS = helper.ORGS;
var allEventhubs = [];

//
//Attempt to send a request to the orderer with the sendCreateChain method

// 在admin user下 获取 channel的 genises.block  然后 指定peers加入channel
//
var joinChannel = function(channelName, peers, username, org) {
    //关闭事件回调连接
    var closeConnections = function(isSuccess) {
        if (isSuccess) {
            logger.debug('\n============ Join Channel is SUCCESS ============\n');
        } else {
            logger.debug('\n!!!!!!!! ERROR: Join Channel FAILED !!!!!!!!\n');
        }
        logger.debug('');
        for (var key in allEventhubs) {
            var eventhub = allEventhubs[key];
            if (eventhub && eventhub.isconnected()) {
                //logger.debug('Disconnecting the event hub');
                eventhub.disconnect();
            }
        }
    };
    //logger.debug('\n============ Join Channel ============\n')
    logger.info(util.format(
        'Calling peers in organization "%s" to join the channel', org));

    var client = helper.getClientForOrg(org);
    var channel = helper.getChannelForOrg(org);
    var eventhubs = [];
    // 1  在管理员环境下 获取原始块(peer想要加入channel  就得需要这个东西)
    return helper.getOrgAdmin(org).then((admin) => {
        logger.info(util.format('received member object for admin of the organization "%s": ', org));
        tx_id = client.newTransactionID();
        let request = {
            txId :  tx_id
        };

        return channel.getGenesisBlock(request);

    }).then((genesis_block) => {
        //  2 封装加入到channel的请求
        tx_id = client.newTransactionID();
        var request = {
            targets: helper.newPeers(peers, org),
            txId: tx_id,
            block: genesis_block
        };
        // 3.1  设置事件监听连接
        eventhubs = helper.newEventHubs(peers, org);
        for (let key in eventhubs) {
            let eh = eventhubs[key];
            eh.connect();
            allEventhubs.push(eh);
        }

        var eventPromises = [];
        eventhubs.forEach((eh) => {
            let txPromise = new Promise((resolve, reject) => {
                //3.2 监听区块信息   并设置超时时间
                let handle = setTimeout(reject, parseInt(config.eventWaitTime));
                eh.registerBlockEvent((block) => {
                    clearTimeout(handle);
                    // in real-world situations, a peer may have more than one channels so
                    // we must check that this block came from the channel we asked the peer to join
                    if (block.data.data.length === 1) {
                        // Config block must only contain one transaction
                        var channel_header = block.data.data[0].payload.header.channel_header;
                        //3.3 属于本channel的信息  就继续执行  否则就拒绝
                        if (channel_header.channel_id === channelName) {
                            resolve();
                        }
                        else {
                            reject();
                        }
                    }
                });
            });
            //3.4 设置 eventPromises集合
            eventPromises.push(txPromise);
        });
        //4  请求加入到channel
        let sendPromise = channel.joinChannel(request);
        // 5   promise流   ( 监听事件  发送事件 )  的 promise   全荣俱荣 一损俱损
        return Promise.all([sendPromise].concat(eventPromises));
    }, (err) => {
        logger.error('Failed to enroll user \'' + username + '\' due to error: ' +
            err.stack ? err.stack : err);
        throw new Error('Failed to enroll user \'' + username +
            '\' due to error: ' + err.stack ? err.stack : err);
    }).then((results) => {
        //7 根据state 判断结果   如果到这里了  说明是sendPromise 返回的结果

        logger.debug(util.format('Join Channel R E S P O N S E : %j', results));
        // 加入成功
        if (results[0] && results[0][0] && results[0][0].response && results[0][0]
            .response.status == 200) {
            logger.info(util.format(
                'Successfully joined peers in organization %s to the channel \'%s\'',
                org, channelName));
            closeConnections(true);
            let response = {
                success: true,
                message: util.format(
                    'Successfully joined peers in organization %s to the channel \'%s\'',
                    org, channelName)
            };
            return response;
        } else {
            //加入失败
            logger.error(' Failed to join channel');
            closeConnections();
            throw new Error('Failed to join channel');
        }
    }, (err) => {
        logger.error('Failed to join channel due to error: ' + err.stack ? err.stack :
            err);
        closeConnections();
        throw new Error('Failed to join channel due to error: ' + err.stack ? err.stack :
            err);
    });
};
exports.joinChannel = joinChannel;

基本流程

Created with Raphaël 2.1.2 Start 仅仅是为了分叉 获取admin 组装request 发送request 获得sendPromise 组装并执行allPromise 处理结果 End 获取相关peer的eventhubs 遍历集合,注册区块事件监听 获得eventPromises yes no

API访问

指定org1的两个peer加入到channel,在具体实现第2点里,helper.js会根据orgpeer获取到peer对应的grpc地址,然后封装成一个完整的request

echo "POST request Join channel on Org1"
echo
curl -s -X POST \
  http://localhost:4000/channels/mychannel/peers \
  -H "authorization: Bearer $ORG1_TOKEN" \
  -H "content-type: application/json" \
  -d '{
    "peers": ["peer1","peer2"]
}'
echo
echo

控制台打印:

POST request Join channel on Org1

{"success":true,"message":"Successfully joined peers in organization org1 to the channel 'mychannel'"}

后台打印:

[2017-10-16 11:07:11.584] [DEBUG] SampleWebApp - Decoded from JWT token: username - Jim, orgname - org1
[2017-10-16 11:07:11.584] [INFO] SampleWebApp - <<<<<<<<<<<<<<<<< J O I N  C H A N N E L >>>>>>>>>>>>>>>>>

// 获取到的参数
[2017-10-16 11:07:11.585] [DEBUG] SampleWebApp - channelName : mychannel
[2017-10-16 11:07:11.585] [DEBUG] SampleWebApp - peers : peer1,peer2

[2017-10-16 11:07:11.585] [INFO] Join-Channel - Calling peers in organization "org1" to join the channel
[2017-10-16 11:07:11.586] [DEBUG] Helper - [crypto_ecdsa_aes]: constructor, keySize: 256
[2017-10-16 11:07:11.586] [DEBUG] Helper - [crypto_ecdsa_aes]: Hash algorithm: SHA2, hash output size: 256
[2017-10-16 11:07:11.587] [DEBUG] Helper - [utils.CryptoKeyStore]: CryptoKeyStore, constructor - start

// 获取admin
[2017-10-16 11:07:11.587] [DEBUG] Helper - [utils.CryptoKeyStore]: constructor, no super class specified, using config: fabric-client/lib/impl/FileKeyValueStore.js
[2017-10-16 11:07:11.587] [DEBUG] Helper - [FileKeyValueStore.js]: FileKeyValueStore.js - constructor
[2017-10-16 11:07:11.588] [DEBUG] Helper - Msp ID : Org1MSP
[2017-10-16 11:07:11.588] [DEBUG] Helper - [crypto_ecdsa_aes]: importKey - start
[2017-10-16 11:07:11.590] [DEBUG] Helper - [crypto_ecdsa_aes]: importKey - have the key [Circular]
[2017-10-16 11:07:11.591] [DEBUG] Helper - [utils.CryptoKeyStore]: This class requires a CryptoKeyStore to save keys, using the store: {"opts":{"path":"/tmp/fabric-client-kvs_peerOrg1"}}
[2017-10-16 11:07:11.591] [DEBUG] Helper - [FileKeyValueStore.js]: FileKeyValueStore.js - constructor
[2017-10-16 11:07:11.591] [DEBUG] Helper - [utils.CryptoKeyStore]: _getKeyStore returning ks
[2017-10-16 11:07:11.591] [DEBUG] Helper - [ecdsa/key.js]: ECDSA curve param X: 0a66f3503a3322b2ca8e9dce03322d486ee6ec5970efaad3f153bc13aa2d942c
[2017-10-16 11:07:11.591] [DEBUG] Helper - [ecdsa/key.js]: ECDSA curve param Y: 312ad05190fa592fb9e8ac2dcdb23c84df7f49e4ee295c2aa1200a50c9146c46
[2017-10-16 11:07:11.592] [DEBUG] Helper - [FileKeyValueStore.js]: FileKeyValueStore -- setValue
[2017-10-16 11:07:11.593] [DEBUG] Helper - [crypto_ecdsa_aes]: importKey - start
[2017-10-16 11:07:11.593] [DEBUG] Helper - [crypto_ecdsa_aes]: importKey - have the key [Circular]
[2017-10-16 11:07:11.593] [DEBUG] Helper - [utils.CryptoKeyStore]: _getKeyStore resolving store
[2017-10-16 11:07:11.594] [DEBUG] Helper - [ecdsa/key.js]: ECDSA curve param X: 0a66f3503a3322b2ca8e9dce03322d486ee6ec5970efaad3f153bc13aa2d942c
[2017-10-16 11:07:11.594] [DEBUG] Helper - [ecdsa/key.js]: ECDSA curve param Y: 312ad05190fa592fb9e8ac2dcdb23c84df7f49e4ee295c2aa1200a50c9146c46
[2017-10-16 11:07:11.594] [DEBUG] Helper - [FileKeyValueStore.js]: FileKeyValueStore -- setValue
[2017-10-16 11:07:11.596] [DEBUG] Helper - [ecdsa/key.js]: ECDSA curve param X: 0a66f3503a3322b2ca8e9dce03322d486ee6ec5970efaad3f153bc13aa2d942c
[2017-10-16 11:07:11.596] [DEBUG] Helper - [ecdsa/key.js]: ECDSA curve param Y: 312ad05190fa592fb9e8ac2dcdb23c84df7f49e4ee295c2aa1200a50c9146c46
[2017-10-16 11:07:11.596] [DEBUG] Helper - [ecdsa/key.js]: ECDSA curve param X: 0a66f3503a3322b2ca8e9dce03322d486ee6ec5970efaad3f153bc13aa2d942c
[2017-10-16 11:07:11.596] [DEBUG] Helper - [ecdsa/key.js]: ECDSA curve param Y: 312ad05190fa592fb9e8ac2dcdb23c84df7f49e4ee295c2aa1200a50c9146c46
[2017-10-16 11:07:11.597] [DEBUG] Helper - [ecdsa/key.js]: ECDSA curve param X: 0a66f3503a3322b2ca8e9dce03322d486ee6ec5970efaad3f153bc13aa2d942c
[2017-10-16 11:07:11.597] [DEBUG] Helper - [ecdsa/key.js]: ECDSA curve param Y: 312ad05190fa592fb9e8ac2dcdb23c84df7f49e4ee295c2aa1200a50c9146c46
[2017-10-16 11:07:11.597] [DEBUG] Helper - [FileKeyValueStore.js]: FileKeyValueStore -- setValue
[2017-10-16 11:07:11.600] [INFO] Join-Channel - received member object for admin of the organization "org1": 
[2017-10-16 11:07:11.604] [DEBUG] Helper - [crypto_ecdsa_aes]: ecdsa signature:  Signature {
  r: <BN: 7d10c289f1015a3597b929ec079652692dd9104fa2bda7326f8320281e33123d>,
  s: <BN: 50167788c3fc57609ab56e14ca8397bc47fffc2469fd683ddc5a51fae5190958>,
  recoveryParam: 0 }

// 设置监听事件
info: [EventHub.js]: _connect - options {"grpc.ssl_target_name_override":"peer0.org1.example.com","grpc.default_authority":"peer0.org1.example.com"}
[2017-10-16 11:07:11.634] [DEBUG] Helper - [crypto_ecdsa_aes]: ecdsa signature:  Signature {
  r: <BN: e1cdeef11d37de28810bed04d525abf4ed4959899f64e7129483110b07d9ef50>,
  s: <BN: 65720ba0dfcdb959cce0a3d69b016097c7895aab1891172ded659aece90d467e>,
  recoveryParam: 1 }
info: [EventHub.js]: _connect - options {"grpc.ssl_target_name_override":"peer1.org1.example.com","grpc.default_authority":"peer1.org1.example.com"}
[2017-10-16 11:07:11.643] [DEBUG] Helper - [crypto_ecdsa_aes]: ecdsa signature:  Signature {
  r: <BN: e1cdeef11d37de28810bed04d525abf4ed4959899f64e7129483110b07d9ef50>,
  s: <BN: 65720ba0dfcdb959cce0a3d69b016097c7895aab1891172ded659aece90d467e>,
  recoveryParam: 1 }
[2017-10-16 11:07:11.652] [DEBUG] Helper - [crypto_ecdsa_aes]: ecdsa signature:  Signature {
  r: <BN: ba3afad71ae6cd1889974364672ed04f15ed3ef6d5c6801ce59ce78bffe27a93>,
  s: <BN: 66b904b771bd6dda916e329e1fc8e5d25b2bae369948bde8e3d12ac3848ac8aa>,
  recoveryParam: 1 }

// 发送请求后的相应
[2017-10-16 11:07:11.957] [DEBUG] Join-Channel - Join Channel R E S P O N S E : [[{"version":0,"timestamp":null,"response":{"status":200,"message":"","payload":{"type":"Buffer","data":[]}},"payload":{"type":"Buffer","data":[]},"endorsement":null},{"version":0,"timestamp":null,"response":{"status":200,"message":"","payload":{"type":"Buffer","data":[]}},"payload":{"type":"Buffer","data":[]},"endorsement":null}],null,null]
[2017-10-16 11:07:11.957] [INFO] Join-Channel - Successfully joined peers in organization org1 to the channel 'mychannel'
[2017-10-16 11:07:11.957] [DEBUG] Join-Channel - 

//
============ Join Channel is SUCCESS ============

[2017-10-16 11:07:11.957] [DEBUG] Join-Channel - 
[2017-10-16 11:07:11.964] [DEBUG] Helper - [crypto_ecdsa_aes]: ecdsa signature:  Signature {
  r: <BN: ab6a1ea9d36c8cabc53cad8cfdf545dc0f7e7751bf43979552bb980f7fcb4b7e>,
  s: <BN: 1839adef53808d6e3ffba1f40495827cc6b4fa047d2c03dfe9ab76933581d35b>,
  recoveryParam: 1 }
[2017-10-16 11:07:11.969] [DEBUG] Helper - [crypto_ecdsa_aes]: ecdsa signature:  Signature {
  r: <BN: ab6a1ea9d36c8cabc53cad8cfdf545dc0f7e7751bf43979552bb980f7fcb4b7e>,
  s: <BN: 1839adef53808d6e3ffba1f40495827cc6b4fa047d2c03dfe9ab76933581d35b>,
  recoveryParam: 1 }

猜你喜欢

转载自blog.csdn.net/qq_27818541/article/details/78339763