Skip to content

Instantly share code, notes, and snippets.

@AkshayCHD
Last active June 1, 2019 14:32
Show Gist options
  • Save AkshayCHD/19bb02d61a88403e82886b98864b5a33 to your computer and use it in GitHub Desktop.
Save AkshayCHD/19bb02d61a88403e82886b98864b5a33 to your computer and use it in GitHub Desktop.

Adding Org to the Balance Transfer network

I was trying to add a new org to my existing network using the Hyperledger Fabric node sdk. I turorial that i refrenced was https://fabric-sdk-node.github.io/tutorial-channel-create.html. Although the tutorial is for adding a new channel to a network, I assumed that the approach for updating the channel configs would be somewhat similar to creating a new channel configuration.

The api that I created using the tutorial and referencing the existing apis in the project is as follows.

/**
 * Copyright 2017 IBM All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an 'AS IS' BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
var fs = require('fs');
var path = require('path');
var superagent = require('superagent');
var helper = require('./helper.js');
var logger = helper.getLogger('Create-Channel');
//Attempt to send a request to the orderer with the sendTransaction method
var fetchConfigBlock = async function(channel_name, peers, username, org_name) {
    try {
		logger.info('Calling peers in organization "%s" to join the channel', org_name);
		// first setup the client for this org
		var client = await helper.getClientForOrg(org_name, username);
		logger.debug('Successfully got the fabric client for the organization "%s"', org_name);
		var channel = client.getChannel(channel_name);
		var channel_config = fs.readFileSync(path.join(__dirname, '../artifacts/channel/mychannel.json'));
		channel_config = JSON.parse(channel_config);
		console.log(channel_config.payload.data.config_update);
		var config_proto;
		var response = await superagent.post('http://127.0.0.1:7059/protolator/encode/common.ConfigUpdate',
			channel_config.payload.data.config_update)
			.buffer()
			.end((err, res) => {
				if(err) {
					logger.error(err);
					return;
				}
				config_proto = res.body;
				console.log("*******************************")
				var signatures = [];
				var signature = client.signChannelConfig(config_proto);
				console.log("*******************************")
				signatures.push(signature);
				var orderer = channel.getOrderer("orderer.example.com");
				
				let tx_id =  client.newTransactionID();
				//return config_proto
				request = {
					config: config_proto, //the binary config
					signatures : signatures, // the collected signatures
					name : 'mychannel', // the channel name
					orderer : orderer, //the orderer from above
					txId  : tx_id //the generated transaction id
				};
				var response = client.updateChannel(request);
				logger.debug(' response ::%j', response);
				if (response && response.status === 'SUCCESS') {
					logger.debug('Successfully update the channel.');
					let response = {
						success: true,
						message: 'Channel created Successfully'
					};
					return response;
				} else {
					logger.error('\n!!!!!!!!! Failed to update the channel!!!!!!!!!\n\n');
					//throw new Error('Failed to create the channel');
				}
		});
	} catch(error) {
		logger.error('Failed to join channel due to error: ' + error.stack ? error.stack : error);
		error_message = error.toString();
	}
};

exports.fetchConfigBlock = fetchConfigBlock;

Procedure

  1. In the above api, the file that I am reading using the filesystem(fs) module has been generated by using the configtxlator tool as mentioned in the tutorial.
  2. I changed some of the attributes of the config_update section of the file so that instead of adding a new channel it updates the configuration of the existing channel. The configuration file is as follows
{
	"payload": {
		"data": {
			"config_update": {
				"channel_id": "mychannel",
				"isolated_data": {},
				"read_set": {
					"groups": {
						"Application": {
							"groups": {
								"Org1MSP": {
									"groups": {},
									"mod_policy": "",
									"policies": {},
									"values": {},
									"version": "0"
								},
								"Org2MSP": {
									"groups": {},
									"mod_policy": "",
									"policies": {},
									"values": {},
									"version": "0"
								}
							},
							"mod_policy": "",
							"policies": {},
							"values": {},
							"version": "0"
						}
					},
					"mod_policy": "",
					"policies": {},
					"values": {
						"Consortium": {
							"mod_policy": "",
							"value": null,
							"version": "0"
						}
					},
					"version": "0"
				},
				"write_set": {
					"groups": {
						"Application": {
							"groups": {
								"Org3MSP": {
									"groups": {},
									"mod_policy": "",
									"policies": {},
									"values": {},
									"version": "0"
								}
							},
							"mod_policy": "Admins",
							"policies": {
								"Admins": {
									"mod_policy": "Admins",
									"policy": {
										"type": 3,
										"value": {
											"rule": "MAJORITY",
											"sub_policy": "Admins"
										}
									},
									"version": "0"
								},
								"Readers": {
									"mod_policy": "Admins",
									"policy": {
										"type": 3,
										"value": {
											"rule": "ANY",
											"sub_policy": "Readers"
										}
									},
									"version": "0"
								},
								"Writers": {
									"mod_policy": "Admins",
									"policy": {
										"type": 3,
										"value": {
											"rule": "ANY",
											"sub_policy": "Writers"
										}
									},
									"version": "0"
								}
							},
							"values": {},
							"version": "1"
						}
					},
					"mod_policy": "",
					"policies": {},
					"values": {
						"Consortium": {
							"mod_policy": "",
							"value": {
								"name": "SampleConsortium"
							},
							"version": "0"
						}
					},
					"version": "0"
				}
			},
			"signatures": []
		},
		"header": {
			"channel_header": {
				"channel_id": "mychannel",
				"epoch": "0",
				"extension": null,
				"timestamp": "2019-04-15T12:51:02Z",
				"tls_cert_hash": null,
				"tx_id": "",
				"type": 2,
				"version": 0
			},
			"signature_header": null
		}
	},
	"signature": null
}

Notice that the read set contains the information of Org1 and Org2 but the write set now contains the information for Org3. 3. Then as mentioned in the tutorial i used superagent to http://127.0.0.1:7059/protolator/encode/common.ConfigUpdate
4. The result that I got from there I signed it using the client object
5. Then I created request for channel configuration update, consisting the signed configuration update object. 6. Then I finally called the client.updateChannel(request) method of the client object and passed the created request as a parameter to it https://fabric-sdk-node.github.io/Client.html#updateChannel.

Problem

The response that i get from the client.updateChannel(request) method is false.

Possible Source of problem

The config_update part of the channel configuration should be properly versioned, so I possible problem might be the incorrect versioning of the components there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment