configtxlator.js v0.1.1
configtxlator.js
Hyperledger Fabric's configtxlator implemented as a js library
Motivation
If you are here you want to decode your block and convert it into a javascript object through fabric-sdk-node without using a local server of configtxlator in order to do it, then you came to the right place!
This first version will allow you to append a organization to a configblock given its json generated by configtxgen.
Install
You can install this lib by
npm i configtxlator.js
if you're using typescript
npm i @types/configtxlator.js
Adding an org to a channel
First get block.json from channel:
const block = await Channel.getChannelConfigFromOrderer()
//Replace snake_case to camelCase and sequence/version tags to int
//otherwise protobuf won't work
const channelBlock = JSON.parse(
block.encodeJSON()
.replace(/(_\w)\w+":/g, (match: String) => match[1].toUpperCase() + match.substring(2)),
(key, value) =>
key === "sequence" ? parseInt(value) : key === "version" ? parseInt(value) : value
);
// Create a replica that will be modified using same process
const newChannelBlock = JSON.parse(
block.encodeJSON()
.replace(/(_\w)\w+":/g, (match: String) => match[1].toUpperCase() + match.substring(2)),
(key, value) =>
key === "sequence" ? parseInt(value) : key === "version" ? parseInt(value) : value
);
Those parses are necessary once
block.EncodeJSON()
from fabric lib returns a json where all key entries are snake_case instead of camelCase (protobufjs doesn't recognizes snake_case entries).
Convert both channelBlock
and newChannelBlock
into common.Config
protos:
const configBlock = fabProtos.common.Config.create({
channelGroup: channelBlock.config.channelGroup,
sequence: channelBlock.config.sequence
});
const newConfigBlock = fabProtos.common.Config.create({
channelGroup: newChannelBlock.config.channelGroup,
sequence: channelBlock.config.sequence
});
Convert new org's JSON got from configtxgen into a common.Config
proto:
import configtxlator = require('configtxlator.js');
const translatedNewOrg = configtxlator.convertOrgJsonToConfigGroup(
orgJson
);
Append new org config into application groups:
const orgs = newConfigBlock.channelGroup.groups.Application.groups;
newConfigBlock.channelGroup.groups.Application.groups = {
...orgs,
[orgName]: translatedNewOrg
};
Create protos object back from protos interfaces:
const originalConfig = fabProtos.common.Config.create(configBlock);
const updatedConfig = fabProtos.common.Config.create(newConfigBlock);
Finally, compute delta set between both configs:
updatedBlock = await configtxlator.computeDeltaSet(originalConfig, updatedConfig);
updatedBlock.channelId = channelName; //Channel name is the channel you're trying to modify
//Convert updatedBlock into a Uint8Array
const updatedIntArray = fabProtos.common.ConfigUpdate.encode(updatedBlock).finish();
//Convert from Uint8Array to js Buffer
const updatedBuffer = Buffer.from(updatedIntArray, 0);
//Sign updatedChannelConfig buffer
const signatures = [Client.signChannelConfig(updatedBuffer)];
And then submit a updateChannel request proposal through fabric-sdk-node