Reputation: 495
I've been trying to follow the instructions here to create a new channel (based on an existing channel) and have an existing peer join that channel. https://fabric-sdk-node.github.io/tutorial-channel-create.html
The error I'm encountering is on newChannel.joinChannel(j_request)
. The raises [JoinChain][composerchannel2]: [Failed verifying that proposal's creator satisfies local MSP principal during channelless check policy with policy [Admins]: [This identity is not an admin]]
But I don't know how to make sure the current user is an admin.
My network is based on the basic-network in the fabric samples directory. I enrol an admin using the script from the fabcar example. See below. And I'm then trying to make sure the admin user is the current user submitting the join channel request like this:
const setAdminAsUser = async () => {
try {
const admin = await fabric_client.getUserContext('admin', true)
return fabric_client.setUserContext(admin, true)
} catch(error) {
console.log('Error setting admin as user', error)
}
}
Then my function to invite peers to the channel looks like this (though note there is only one organisation and one peer):
const invitePeerToChannel = async () => {
console.log('invite peer to channel')
var newChannel = fabric_client.newChannel('composerchannel2');
var orderer = fabric_client.newOrderer('grpc://localhost:7050');
var peer = fabric_client.newPeer('grpc://localhost:7051');
newChannel.addOrderer(orderer);
newChannel.addPeer(peer);
tx_id = fabric_client.newTransactionID(true);
let g_request = {
txId: tx_id
};
// get the genesis block from the orderer
newChannel.getGenesisBlock(g_request).then((block) =>{
genesis_block = block;
tx_id = fabric_client.newTransactionID(true);
let j_request = {
targets: ['localhost:7051'],
block: genesis_block,
txId: tx_id
};
console.log(JSON.stringify(j_request))
// send genesis block to the peer
return newChannel.joinChannel(j_request);
}).then((results) =>{
if(results && results.response && results.response.status == 200) {
console.log('Joined correctly')
} else {
console.log('Failed', results)
}
});
}
Function for enrolling the admin, based on the fabcar example:
const enrollAdmin = () => {
// create the key value store as defined in the fabric-client/config/default.json 'key-value-store' setting
return Fabric_Client.newDefaultKeyValueStore({ path: store_path}).then((state_store) => {
// assign the store to the fabric client
fabric_client.setStateStore(state_store);
var crypto_suite = Fabric_Client.newCryptoSuite();
// use the same location for the state store (where the users' certificate are kept)
// and the crypto store (where the users' keys are kept)
var crypto_store = Fabric_Client.newCryptoKeyStore({path: store_path});
crypto_suite.setCryptoKeyStore(crypto_store);
fabric_client.setCryptoSuite(crypto_suite);
var tlsOptions = {
trustedRoots: [],
verify: false
};
// be sure to change the http to https when the CA is running TLS enabled
fabric_ca_client = new Fabric_CA_Client('http://localhost:7054', tlsOptions , 'ca.org1.example.com', crypto_suite);
// first check to see if the admin is already enrolled
return fabric_client.getUserContext('admin', true);
}).then((user_from_store) => {
if (user_from_store && user_from_store.isEnrolled()) {
console.log('Successfully loaded admin from persistence');
admin_user = user_from_store;
return null;
} else {
// need to enroll it with CA server
return fabric_ca_client.enroll({
enrollmentID: 'admin',
enrollmentSecret: 'adminpw'
}).then((enrollment) => {
console.log('Successfully enrolled admin user "admin"');
return fabric_client.createUser(
{username: 'admin',
mspid: 'Org1MSP',
cryptoContent: { privateKeyPEM: enrollment.key.toBytes(), signedCertPEM: enrollment.certificate }
});
}).then((user) => {
admin_user = user;
return fabric_client.setUserContext(admin_user);
}).catch((err) => {
console.error('Failed to enroll and persist admin. Error: ' + err.stack ? err.stack : err);
throw new Error('Failed to enroll admin');
});
}
}).then(() => {
console.log('Assigned the admin user to the fabric client ::' + admin_user.toString());
}).catch((err) => {
console.error('Failed to enroll admin: ' + err);
});
}
Hitting a brick wall with the tutorial docs so any help would be brilliant!
EDIT:
Here is how I'm currently generating the config update then signing it. This is based on the SDK tutorial.
// This takes a config file that includes the organisations that will be added to the channel
const encodeChannelConfig = () => {
return new Promise((resolve, reject) => {
console.log('encoding channel config')
var config_json = fs.readFileSync("./newChannel.json");
config_json = JSON.stringify(JSON.parse(config_json))
superagent.post('http://127.0.0.1:7059/protolator/encode/common.ConfigUpdate',
config_json)
.buffer()
.end((err, res) => {
if(err) {
return;
}
resolve(res.body);
});
})
}
const signChannelConfig = (encodedChannelConfig) => {
return new Promise((resolve, reject) => {
console.log('signing channel config')
var signature = fabric_client.signChannelConfig(encodedChannelConfig);
signatures.push(signature);
resolve(signatures);
})
}
Upvotes: 1
Views: 812
Reputation: 134
Try doing a setAdminSigningIdentity on your fabric_client if you haven't already.
https://fabric-sdk-node.github.io/Client.html#setAdminSigningIdentity
This will allow the admin credentials to be used when you do the newTransactionID with the true option.
Note this admin is not the same as the admin user from the CA and the private key and cert are generated by cryptogen and are likely in a directory similar to
crypto-config/peerOrganizations/org1/users/Admin@org1/msp/keystore
crypto-config/peerOrganizations/org1/users/Admin@org1/msp/signcerts
Upvotes: 2