3、fabric node sdk1.4.8更新锚节点(通道文件的形式)

声明使用的版本

  • fabric版本如下:1.4.8
  • node-sdk版本:1.4.8
  • node版本:v8.11.1
  • ubuntu版本:16.04

关于锚节点你需要知道的

锚节点的概念

某一个组织,当只有使用了锚节点,组织内的消息才能与另外的组织进行交互,简单来说锚节点就是组织的网关

为什么需要使用锚节点

Fabric中,每个组织可以指定Anchor Peer,其他组织的节点就可以将Gossip消息发送到这个Anchor Peer上,进而Anchor Peer将获得整个网络信息,区块广播到本组织内。

SDK添加锚节点的思路

  • 1、从创世块中配置某个组织的锚节点
  • 2、用工具生成锚节点的.tx文件
  • 3、读取这个.tx到二进制流中
  • 4、用对应组织的admin权限,更新到通道中

开始用代码实现

本文暂时只是通过使用通道文件的形式来更新锚节点,后面还可以使用直接更新通道配置的形式来更新

按照上面的说法,我们来用代码实现

// 更新锚节点
const updateAnchorPeers = async function (orgName, orgAdminName, ordererName, configUpdatePath, channelName) {
	let error_message = ""
	try {
		const ccpPath = path.resolve(__dirname, "connect-sdk.json");
		const ccp = JSON.parse(fs.readFileSync(ccpPath, 'utf8'));
		const walletPath = path.join(process.cwd(), 'wallet');
		const wallet = new FileSystemWallet(walletPath);
		console.log(`Wallet path: ${walletPath}`);
		let checkUserResult = await checkUser(wallet, orgAdminName)
		if(!checkUserResult) {
			// 从crypto-config文件夹中导出org admin的身份,保存到钱包中
			await getAdminIdentify(wallet, orgAdminName, ccp.organizations[orgName].adminPrivateKey.path, ccp.organizations[orgName].signedCert.path, ccp.organizations[orgName].mspid)
		}
		const gateway = new Gateway();
        await gateway.connect(ccp, { wallet, identity: orgAdminName, discovery: { enabled: true, asLocalhost: false } });
        // // first read in the file, this gives us a binary config envelope
		// let adminKey = fs.readFileSync(path.join(__dirname, adminOrgKeyPath));
		// // let adminCert = fs.readFileSync(path.join(__dirname, './crypto-config/peerOrganizations/org1.zeng.com/users/Admin@org1.zeng.com/msp/cacerts/ca.org1.zeng.com-cert.pem'));
		// let adminCert = fs.readFileSync(path.join(__dirname, adminOrgCertPath));
		var client = gateway.getClient()
		// client.setAdminSigningIdentity(adminKey.toString(),adminCert.toString(), orgName)
		let channel = client.newChannel(channelName);
		if(!channel) {
			let message = util.format('Channel %s was not defined in the connection profile', channelName);
			// logger.error(message);
			console.log(message)
			throw new Error(message);
		}

		// read in the envelope for the channel config raw bytes
		var envelope = fs.readFileSync(path.join(__dirname, configUpdatePath));
		// extract the channel config bytes from the envelope to be signed
		var channelConfig = client.extractChannelConfig(envelope); // 提取通道的配置文件
		// Acting as a client in the given organization provided with "orgName" param
		// sign the channel config bytes as "endorsement", this is required by
		// the orderer's channel creation policy
		// this will use the admin identity assigned to the client when the connection profile was loaded
		let signature = client.signChannelConfig(channelConfig); // 对提取的通道配置文件进行签名,client目前的身份是admin
		let request = {
			config: channelConfig,
			signatures: [signature],
			name: channelName,
			txId: client.newTransactionID(true) // get an admin based transactionID
		};

		var promises = [];
		let event_hubs = channel.getChannelEventHubsForOrg(); // 注册通道的针对当前org的事件,原文如下: Gets a list of ChannelEventHubs based on an organization. If the organization name is omitted then the current organization of the current user is used.
		logger.debug('found %s eventhubs for this organization %s',event_hubs.length, orgName);
		event_hubs.forEach((eh) => {
			let anchorUpdateEventPromise = new Promise((resolve, reject) => {
				logger.debug('anchorUpdateEventPromise - setting up event');
				const event_timeout = setTimeout(() => {
					let message = 'REQUEST_TIMEOUT:' + eh.getPeerAddr();
					logger.error(message);
					eh.disconnect();
				}, 60000);
				eh.registerBlockEvent((block) => { // To register for block events.
					logger.info('The config update has been committed on peer %s',eh.getPeerAddr());
					clearTimeout(event_timeout);
					resolve();
				}, (err) => {
					clearTimeout(event_timeout);
					logger.error(err);
					reject(err);
				},
					// the default for 'unregister' is true for block listeners
					// so no real need to set here, however for 'disconnect'
					// the default is false as most event hubs are long running
					// in this use case we are using it only once
					{unregister: true, disconnect: true}
				);
				eh.connect();
			});
			promises.push(anchorUpdateEventPromise);
		});
		var orderer=client.getOrderer(ordererName) 
		channel.addOrderer(orderer)
		var sendPromise = client.updateChannel(request);
		// put the send to the orderer last so that the events get registered and
		// are ready for the orderering and committing
		promises.push(sendPromise);
		let results = await Promise.all(promises);
		logger.debug(util.format('------->>> R E S P O N S E : %j', results));
		let response = results.pop(); //  orderer results are last in the results
		if (response) {
			if (response.status === 'SUCCESS') {
				logger.info('Successfully update anchor peers to the channel %s', channelName);
			} else {
				error_message = util.format('Failed to update anchor peers to the channel %s with status: %s reason: %s', channelName, response.status, response.info);
				logger.error(error_message);
			}
		} else {
			error_message = util.format('Failed to update anchor peers to the channel %s', channelName);
			logger.error(error_message);
		}
	} catch (error) {
		logger.error('Failed to update anchor peers due to error: ' + error.stack ? error.stack :	error);
		error_message = error.toString();
	}

	if (!error_message) {
		let message = util.format(
			'Successfully update anchor peers in organization %s to the channel \'%s\'',
			orgName, channelName);
		logger.info(message);
		const response = {
			success: true,
			message: message
		};
		return response;
	} else {
		let message = util.format('Failed to update anchor peers. cause:%s',error_message);
		logger.error(message);
		const response = {
			success: false,
			message: message
		};
		return response;
	}
}

头文件部分如下

'use strict';

const { FileSystemWallet, Gateway, X509WalletMixin } = require('fabric-network');
const Client = require('fabric-client');
const utils = require('fabric-client/lib/utils.js');
const fs = require('fs');
const path = require('path');
const util = require('util');

const {incHashString, getConfig, loadWallet} = require('./utils');
var log4js = require('log4js');
var getLogger = function(moduleName) {
	var logger = log4js.getLogger(moduleName);
	// logger.setLevel('DEBUG');
	logger.level = 'DEBUG';
	return logger;
};
const logger = getLogger('test');

调用代码部分如下

let ordererName = "orderer.zeng.com"
let channelName = "mychannel"
// let orgName = "Org1"
// let orgAdminName = "admin1"
// let configUpdatePath = "Org1MSPanchors.tx"
let orgName = "Org2"
let orgAdminName = "admin2"
let configUpdatePath = "Org2MSPanchors.tx"
updateAnchorPeers(orgName, orgAdminName, ordererName, configUpdatePath, channelName)

调用成功后显示信息如下

[2021-04-13T10:07:11.677] [DEBUG] test - found 0 eventhubs for this organization Org1
[2021-04-13T10:07:11.737] [DEBUG] test - ------->>> R E S P O N S E : [{"status":"SUCCESS","info":""}]
[2021-04-13T10:07:11.738] [INFO] test - Successfully update anchor peers to the channel mychannel
[2021-04-13T10:07:11.738] [INFO] test - Successfully update anchor peers in organization Org1 to the channel 'mychannel'

参考网站

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值