I have the CA for my organization. This is setting for CA's docker container:
version: '2'
services:
ca.org1.example.com:
container_name: ca.org1.example.com
image: hyperledger/fabric-ca
command: /bin/bash -c 'fabric-ca-server start -b rca-org-admin:rca-org-adminpw --port 6053'
environment:
- FABRIC_CA_SERVER_HOME=/tmp/hyperledger/fabric-ca/crypto
- FABRIC_CA_SERVER_TLS_ENABLED=true
- FABRIC_CA_SERVER_CSR_CN=ca.org1.example.com
- FABRIC_CA_SERVER_CSR_HOSTS=0.0.0.0
- FABRIC_CA_SERVER_DEBUG=true
- ADMIN_CREDS=rca-org-admin:rca-org-adminpw
- PORT=6053
volumes:
- /home/user/go/src/network/crypto-config/org1/ca/server:/tmp/hyperledger/fabric-ca
ports:
- 6053:6053
networks:
- basic
networks:
basic:
I have a connectionProfile.yaml with url and TLS certificate of my CA:
certificateAuthorities:
ca.org1.examlple.com:
url: https://localhost:6053
tlsCACerts:
pem: |
-----BEGIN CERTIFICATE-----
MIICMzCCAdqgAwIBAgIUYj0f4V+ms+xjSSx73MYurypAwGUwCgYIKoZIzj0EAwIw
bjELMAkGA1UEBhMCVVMxFzAVBgNVBAgTDk5vcnRoIENhcm9saW5hMRQwEgYDVQQK
EwtIeXBlcmxlZGdlcjEPMA0GA1UECxMGRmFicmljMR8wHQYDVQQDExZjYS5xcHIu
Zm9vdGJhbGxuZXQuY29tMB4XDTIwMDUwNjA5NTgwMFoXDTM1MDUwMzA5NTgwMFow
bjELMAkGA1UEBhMCVVMxFzAVBgNVBAgTDk5vcnRoIENhcm9saW5hMRQwEgYDVQQK
EwtIeXBlcmxlZGdlcjEPMA0GA1UECxMGRmFicmljMR8wHQYDVQQDExZjYS5xcHIu
Zm9vdGJhbGxuZXQuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE2q06YuK7
L6K2kwl5HPwW1exdxBoEwiQ+denvNtoq1hvo4f6zwtlD6+aVwfnu9CvLlriPEJy3
KSbM8/IuszlKyqNWMFQwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8C
AQEwHQYDVR0OBBYEFG4G17iqYS0wCNskmsFC8pUtXf8zMA8GA1UdEQQIMAaHBAAA
AAAwCgYIKoZIzj0EAwIDRwAwRAIgZMIAjEyB9aeqSJuvBqPBkJAddOCTEdsPwbzb
Bql46DICIAl998KlBM23r4iRYPoZTX8/8njPfXpi5a8lX85Skpme
-----END CERTIFICATE-----
httpOptions:
verify: false
I load this connectionProfile.yaml to my nodeJS application and try to enroll user. See code below:
const caInfo = ccp.certificateAuthorities['ca.org1.example.com'];
const caTLSCACerts = caInfo.tlsCACerts.pem;
const ca = new FabricCAServices(caInfo.url, { trustedRoots: caTLSCACerts, verify: false }, caInfo.caName);
// Create a new file system based wallet for managing identities.
const walletPath = path.join(process.cwd(), 'wallet');
const wallet = new FileSystemWallet(`${__dirname}/../hyperledger/wallet`);
console.log(`Wallet path: ${walletPath}`);
// Check to see if we've already enrolled the admin user.
const identityLabel = 'admin.org1.example.com'
const identity = await wallet.exists(identityLabel);
if (!identity) {
// Enroll the admin user, and import the new identity into the wallet.
const enrollment = await ca.enroll({ enrollmentID: 'rca-org-admin', enrollmentSecret: 'rca-org-adminpw' });
const x509Identity = {
certificate: enrollment.certificate,
privateKey: enrollment.key.toBytes(),
mspId: 'org1MSP',
type: 'X.509',
};
await wallet.import('admin.org1.example.com', x509Identity);
console.log('Successfully enrolled admin user "admin" and imported it into the wallet');
}
I guess tlsCACerts.pem needs for TLS connection with CA. User enroll was successful by this code. But if I change this certificate(tlsCACerts.pem) to some other one(any certificate, even randomly generated) and clean my wallet and try to make an enroll, it will still succeed. Logs of the container CA confirm this. It seems to me that it does not use this TLS certificate, but why, if the TLS certification is turned on on the CA server.
Version of fabric-ca-server is 1.4.6
Version of Fabric SDK for Node is 1.4.8
Maybe someone has thoughts on this issue. Maybe I'm doing something wrong?
Despite the fact that the question is 4 months old and you probably found the solution I try to answer.
I think the problem is on the line 3 of your code:
const ca = new FabricCAServices(caInfo.url, { trustedRoots: caTLSCACerts, verify: false }, caInfo.caName);
TLS option verify is false, so certificate is not actually verifying.
Try to set verify to true, I think this should work:
const ca = new FabricCAServices(caInfo.url, { trustedRoots: caTLSCACerts, verify: true }, caInfo.caName);
Related
Based on fabcar-sample (v1.4) I developed an app in which I want to use attribute values for the admin and for the users. I face an issue about how to add attribute values while I enroll in the admin. I do not know if it is possible to add attribute values for the admin. In the examples that I have seen are only added from the registered users. In the fabcar sample looks like the admin is just enrolled and not registered in contrast to the users.
registerUser.js
const gateway = new Gateway();
await gateway.connect(ccpPath, { wallet, identity: 'admin', discovery: { enabled: true, asLocalhost: true } });
console.log('Create a new gateway for connecting to our peer node');
// Get the CA client object from the gateway for interacting with the CA.
const ca = gateway.getClient().getCertificateAuthority();
const adminIdentity = gateway.getCurrentIdentity();
console.log('Get the CA client object from the gateway for interacting with the CA');
const aff = adminIdentity.getAffiliation();
const secret = await ca.register({ affiliation: aff, enrollmentID: username, role: 'client', attrs: [ {"name": "email", "value": "myemail#test.com", "ecert": true} ] }, adminIdentity);
const enrollment = await ca.enroll({ enrollmentID: username, enrollmentSecret: secret, attr_reqs: [{ name: "email", optional: false }]});
enrollAdmin.js
const caInfo = ccp.certificateAuthorities[ca_info];
const caTLSCACerts = caInfo.tlsCACerts.pem;
const ca = new FabricCAServices(caInfo.url, { trustedRoots: caTLSCACerts, verify: false }, caInfo.caName);
// Create a new file system based wallet for managing identities.
const walletPath = path.join(process.cwd(), wallet_info);
const wallet = new FileSystemWallet(walletPath);
const enrollment = await ca.enroll({ enrollmentID: username, enrollmentSecret:'adminpw'});
const identity = X509WalletMixin.createIdentity(MSP, enrollment.certificate, enrollment.key.toBytes());
await wallet.import(username, identity);
smartcontract.go
func (c *SmartContract) getEmail(stub shim.ChaincodeStubInterface) (string, error) {
email, ok, err := cid.GetAttributeValue(stub, "email")
if err != nil {
return "", err
}
if !ok {
return "", errors.New("email attribute is missing")
}
return email, nil
}
Any idea how to add attribute values on the admin while in this process in not registered the admin like the users?
In the case of the admin client, when the fabric-ca-server is executed, the value can be set in the configuration. Most of the examples work only with the ID and password by using the -b option. like fabric-ca-server start -b admin:adminpw -d
default configuration can be changed in fabric-ca-server-config.yaml file.
fabric-ca-server-config.yaml link is fabric-samples v2.0, but fabric-ca has no changes(v1.4) and the configuration form is the same.
You can add admin's attr in this file.
[EDIT] I wrote it according to the guide document, but I confirmed that it does not work. After deepdive analysis of the code, I confirmed and corrected that the regular expression did not work properly.
hf.Registrar.Attributes: "*"
to
hf.Registrar.Attributes: "email,hf.Registrar.Roles,hf.Registrar.DelegateRoles,hf.Revoker,hf.IntermediateCA,hf.GenCRL,hf.Registrar.Attributes,hf.AffiliationMgr"
in fabric-ca-server-config.yaml
Here is example.
docker-compose-ca.yaml
version: '3'
services:
ca.org1.example.com:
image: hyperledger/fabric-ca:1.4
environment:
- FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server
- FABRIC_CA_SERVER_CA_NAME=ca.org1.example.com
- FABRIC_CA_SERVER_TLS_ENABLED=true
- FABRIC_CA_SERVER_TLS_CERTFILE=/etc/hyperledger/fabric-ca-server-config/ca.org1.example.com-cert.pem
- FABRIC_CA_SERVER_TLS_KEYFILE=/etc/hyperledger/fabric-ca-server-config/<your_ca_org1_private_key>
- FABRIC_CA_SERVER_PORT=7054
ports:
- "7054:7054"
command: sh -c 'fabric-ca-server start -d'
volumes:
# mounting fabric-ca-server-config.yaml file
- ./fabric-ca-server-config.yaml:/etc/hyperledger/fabric-ca-server/fabric-ca-server-config.yaml
- ./crypto-config/peerOrganizations/org1.example.com/ca/:/etc/hyperledger/fabric-ca-server-config
container_name: ca.org1.example.com
fabric-ca-server-config.yaml
...
registry:
maxenrollments: -1
identities:
- name: test
pass: testpw
type: client
affiliation: ""
attrs:
# <add_your_attrs>
email: "myemail#test.com"
hf.Registrar.Roles: "*"
hf.Registrar.DelegateRoles: "*"
hf.Revoker: true
hf.IntermediateCA: true
hf.GenCRL: true
hf.Registrar.Attributes: "email,hf.Registrar.Roles,hf.Registrar.DelegateRoles,hf.Revoker,hf.IntermediateCA,hf.GenCRL,hf.Registrar.Attributes,hf.AffiliationMgr"
hf.AffiliationMgr: true
...
enrollAdmin.js
...
// Enroll the admin user, and import the new identity into the wallet.
// with attrs
const enrollment = await ca.enroll({ enrollmentID: 'test', enrollmentSecret: 'testpw',
attr_reqs: [{ name: "email", optional: false }] });
const x509Identity = {
credentials: {
certificate: enrollment.certificate,
privateKey: enrollment.key.toBytes(),
},
mspId: 'Org1MSP',
type: 'X.509',
};
await wallet.put('admin', x509Identity);
console.log('Successfully enrolled admin user "admin" and imported it into the wallet');
...
node enrollAdmin.js
Successfully enrolled admin user "admin" and imported it into the wallet
it works!
[NOTE] If you don't want to touch the docker or configuration it's okay to add another admin to work.
registerAndEnrollAdmin.js
...
// Register the user, enroll the user, and import the new identity into the wallet.
const adminUser = await provider.getUserContext(adminIdentity, 'admin');
const secret = await ca.register({
affiliation: 'org1.department1',
enrollmentID: 'admin2',
role: 'client',
attrs: [ {"name": "hf.Registrar.Roles", "value": "client,orderer,peer"}, {"name": "hf.Registrar.DelegateRoles", "value": "client,orderer,peer"}, {"name": "hf.Revoker", "value": "true"},
{"name": "email", "value": "test#example.com"}, {"name": "hf.Registrar.Attributes", "value": "email, hf.Registrar.Roles, hf.Registrar.DelegateRoles, hf.Revoker, hf.Registrar.Attributes"} ] }
, adminUser);
const enrollment = await ca.enroll({
enrollmentID: 'admin2',
enrollmentSecret: secret,
attr_reqs: [{ name: "email", optional: false }]
});
...
then you can register users using admin2
I need to send e-mail through my remote Postfix/Dovecot SASL service from Node.js on my desktop.
When I send email using Thunderbird, it works and the Postfix server logs show
Anonymous TLS connection established from unknown[dh.cp.ip.ip]: TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)
But not through nodemailer, where the Postfix server logs:
Nov 26 22:02:31 servicelabel postfix/submission/smtpd[27019]: connect from unknown[dh.cp.ip.ip]
Nov 26 22:02:31 servicelabel postfix/submission/smtpd[27019]: lost connection after CONNECT from unknown[dh.cp.ip.ip]
Nov 26 22:02:31 servicelabel postfix/submission/smtpd[27019]: disconnect from unknown[dh.cp.ip.ip] commands=0/0
These same settings are used for Nodemailer transport and Thunderbird
let transporter = nodemailer.createTransport(
{
host: "mx.example.com",
port: 587,
secure: false, // use TLS
// requireTLS:true,
auth: {
user: "emailuser",
pass: "password"
},
tls: { rejectUnauthorized: false },
// logger: true,
debug: true
},
{
from: 'myuser#example.com',
}
);
But Nodemailer won't connect to Dovecot with TLS the same way Thunderbird does ??
when I change secure to true to force TLS a SSL routines:ssl3_get_record:wrong version number error (below); it appears when verifying the transport.
transporter.verify(function(error, success) {
if (error) {
console.log(error);
} else {
console.log("Server is ready to take our messages");
return false;
}
});
Error: 140185182082944:error:1408F10B:SSL routines:ssl3_get_record:wrong version number:../deps/openssl/openssl/ssl/record/ssl3_record.c:332:
code:"ECONNECTION"
command:"CONN"
function:"ssl3_get_record"
library:"SSL routines"
message:"140185182082944:error:1408F10B:SSL routines:ssl3_get_record:wrong version number:../deps/openssl/openssl/ssl/record/ssl3_record.c:332:\n"
reason:"wrong version number"
stack:"Error: 140185182082944:error:1408F10B:SSL routines:ssl3_get_record:wrong version number:../deps/openssl/openssl/ssl/record/ssl3_record.c:332:\n"
When I test with this command:
openssl s_client -starttls smtp -connect mx.example.com:587
depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
verify return:1
depth=0 CN = mx.example.com
verify return:1
---
Certificate chain
0 s:CN = mx. ...
...
...
... the SSL/STARTTLS handshake succeeds and certificates
But if I use this command:
openssl s_client -connect mx.example.com:587 -crlf -ign_eof
I get the same error as with Nodemailer
CONNECTED(00000005)
140508975112640:error:1408F10B:SSL routines:ssl3_get_record:wrong version number:../ssl/record/ssl3_record.c:332:
I've tried a number of option configurations and am at a loss...
How do I send secure email through my Dovecot/Postfix server via Nodemailer? Do I need to configure some certs in Nodemailer? Should I use something different to send secure email from node.js? Any help appreciated.
My unit testing context in Mocha does not have the ciphersuites of Node.js available.
The Nodemailer has no problem initiating TLS handshake from STARTLS when running in a Node.js context.
can't add a comment to #Kickaha's response to confirm his observation.
FYI: Some of the node mailer error messages are misleading. When I fat fingered the port number, I got a wrong version error, but now it runs fine from a firebase node.js function:
try {
const mailFrom = functions.config().mail.from;
const mailPwd = functions.config().mail.pwd;
const mailHost = functions.config().mail.host;
// some code to generate the message
const mailOptions = {
from: mailFrom,
to: creatorEmail,
subject: subject,
html: message
};
const transporter = nodemailer.createTransport({
host: mailHost,
port: 465,
secure: true, // STARTTLS
auth: {
type: 'LOGIN',
user: mailFrom,
pass: mailPwd
}
});
await transporter.sendMail(mailOptions);
} catch (err) {
console.error(err);
}
I am new to hyperledger fabric and trying some hands on. I am trying to add and joined the peer into the channel using fabric SDK but I am getting ""[Remote.js]: Error: Failed to connect before the deadline URL:grpcs://localhost:7088"" this error.
I have used addPeer function of channel and after addition I tried to join the peer to channel using join channel operation. But after running the code I got the error I mentioned above. If any one can suggest how to add and join the peer using fabric API.
import { FileSystemWallet, Gateway } from 'fabric-network';
import * as path from 'path';
import { Peer } from 'fabric-client';
import { request } from 'https';
const ccpPath = path.resolve(__dirname, '..', '..', '..', 'first-network', 'connection-org1.json');
async function main() {
try {
identities.
const walletPath = path.join(process.cwd(), 'wallet');
const wallet = new FileSystemWallet(walletPath);
console.log(`Wallet path: ${walletPath}`);
// Check to see if we've already enrolled the user.
const userExists = await wallet.exists('user1');
if (!userExists) {
console.log('An identity for the user "user1" does not exist in the wallet');
console.log('Run the registerUser.ts application before retrying');
return;
}
const gateway = new Gateway();
await gateway.connect(ccpPath, { wallet, identity: 'user1', discovery: { enabled: true, asLocalhost: true } });
// Get the network (channel) our contract is deployed to.
const network = await gateway.getNetwork('mychannel');
var opts ={
name: 'peer4.org1.example.com',
request_timeout: '5252',
'pem': '-----BEGIN CERTIFICATE-----\nMIICVzCCAf2gAwIBAgIQfdwd3s8+f0YvH2esgpia7TAKBggqhkjOPQQDAjB2MQsw\nCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy\nYW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEfMB0GA1UEAxMWdGxz\nY2Eub3JnMS5leGFtcGxlLmNvbTAeFw0xOTEwMjIwNjA3MDBaFw0yOTEwMTkwNjA3\nMDBaMHYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQH\nEw1TYW4gRnJhbmNpc2NvMRkwFwYDVQQKExBvcmcxLmV4YW1wbGUuY29tMR8wHQYD\nVQQDExZ0bHNjYS5vcmcxLmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0D\nAQcDQgAEJBq3JFLV0LdNLxOBLS/BH1jh2AMjg6awzO5fz9faB0rIBj7xZg4sCwq4\nwA5M3y5kOjVDTZaEe/t+8o4DMZmBmaNtMGswDgYDVR0PAQH/BAQDAgGmMB0GA1Ud\nJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1Ud\nDgQiBCB6UC4NGyvuVZ0Bmi7aWkju7bRm3jZvU9kNXrVgFeBa6TAKBggqhkjOPQQD\nAgNIADBFAiEArR3BiLVpA0z3K53wr+2Cjjtq0gmx2un9Nlgl352bhAoCIEh9dZCK\ny+JcrTBTWM57WZvmieVvf2uUN9UgJ2xHyK9o\n-----END CERTIFICATE-----\n',
sslcerti: 'peer4.org1.example.com',
}
var peer = new Peer('grpcs://localhost:7088', opts);
var channel = network.getChannel();
channel.addPeer(peer,'Org1MSP')
var request ={
target:[peer],
block :await channel.getGenesisBlock(),
txId :gateway.getClient().newTransactionID(true)
}
channel.joinChannel(request, 5252)
}
Failed to connect before the deadline URL:grpcs://localhost:7088 --> defines that it is trying to connect to server with respective port ,but it is failing .seems to be the service is not running or port is not properly bounded.
Make sure that either service is properly running or port is enabled.If any issue let me know
I am unable to install node chaincode using fabric-node-sdk.
I am getting the following error:
installChaincode error No identity has been assigned to this client
I am using following script
const Client = require("fabric-client");
const path = require("path");
const os = require("os");
const client = new Client();
const deploy = async () => {
const connectionOpts = {
name: "peer1",
"request-timeout": 7000,
pem: path.resolve(
os.homedir,
"/fabric-samples/chaincode-docker-devmode/msp/signcerts/peer.pem"
),
"ssl-target-name-override": "peer"
};
const peer = client.newPeer("grpc://172.18.0.3:7052", connectionOpts);
const request = {
targets: peer,
chaincodePath: path.resolve(
os.homedir + "/fabric-samples/chaincode/chaincode_example02/node"
),
chaincodeId: "myc",
chaincodeVersion: "v0",
chaincodeType: "node"
};
const result = await client.installChaincode(request, 6000);
console.log(await result);
};
deploy();
How do I assign identity to client?
In the documentation, it is not demonstrated what arguments it required and how to assign identity.
Peer node want to know who is making the transaction. Try using this method before the install chincode transaction:
client.setAdminSigningIdentity(private_key, certificate, mspid)
Where:
private_key: the private key PEM string
certificate: the PEM-encoded string of certificate
mspid: The Member Service Provider id for the local signing identity (i.e 'Org1MSP')
In the chaincode install request, you need the txId:
client.setAdminSigningIdentity(private_key, certificate, mspid)
const request = {
targets: peer,
chaincodePath: path.resolve(
os.homedir + "/fabric-samples/chaincode/chaincode_example02/node"
),
chaincodeId: "myc",
chaincodeVersion: "v0",
chaincodeType: "node",
txId: client.newTransactionID(true)
};
const result = await client.installChaincode(request, 6000);
console.log(await result);
I faced the same issue as well and it is resolved after adding the below line, i.e., channel initialization.
await channel.initialize({ discover: true });
source: https://fabric-sdk-node.github.io/master/tutorial-discovery.html
Im trying to setup a hyperledger fabric network wtih 2 organizations base on byfn. The network consist of the following nodes:
cli
peer1.org1.example.com
peer0.org2.example.com
peer1.org2.example.com
peer0.org1.example.com
orderer.example.com
couchdb3
couchdb2
couchdb1
ca.org1.example.com
couchdb0
ca.org2.example.com
I using fabcar chaincode for this network and have no problem enrolling Admin, registering User and query from peer in Org1.
But when i try to perform the same query from a peer in Org2, I get the following error :
Error: 2 UNKNOWN: access denied: channel [mychannel] creator org [Org2MSP]
Would like to ask if anyone know what this error means and how can I fix this?
Following are the steps and configuration files I have used:
./byfn.sh -m down
# clean the keystore
rm -rf ./hfc-key-store
rm -rf ./hfc-key-store2
#Generate artifacts
../bin/cryptogen generate --config=./crypto-config.yaml
export FABRIC_CFG_PATH=$PWD
../bin/configtxgen -profile TwoOrgsOrdererGenesis -outputBlock ./channel-artifacts/genesis.block
export CHANNEL_NAME=mychannel && ../bin/configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID $CHANNEL_NAME
../bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org1MSP
../bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org2MSP
Then replace ca0 and ca1 keyfile in docker-compose-cli.yaml :
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
version: '2'
volumes:
orderer.example.com:
peer0.org1.example.com:
peer1.org1.example.com:
peer0.org2.example.com:
peer1.org2.example.com:
networks:
byfn:
services:
ca0:
image: hyperledger/fabric-ca:$IMAGE_TAG
environment:
- CORE_LOGGING_LEVEL=DEBUG
- FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server
- FABRIC_CA_SERVER_CA_NAME=ca-org1
- FABRIC_CA_SERVER_CA_CERTFILE=/etc/hyperledger/fabric-ca-server-config/ca.org1.example.com-cert.pem
- FABRIC_CA_SERVER_CA_KEYFILE=/etc/hyperledger/fabric-ca-server-config/f6aa4b99b3177c86e00e55e4ed5dea88ec0c67f27327955eb978b9bf80d6116e_sk
ports:
- "7054:7054"
command: sh -c 'fabric-ca-server start -b admin:adminpw -d'
volumes:
- ./crypto-config/peerOrganizations/org1.example.com/ca/:/etc/hyperledger/fabric-ca-server-config
container_name: ca.org1.example.com
networks:
- byfn
ca1:
image: hyperledger/fabric-ca:$IMAGE_TAG
environment:
- CORE_LOGGING_LEVEL=DEBUG
- FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server
- FABRIC_CA_SERVER_CA_NAME=ca-org2
- FABRIC_CA_SERVER_TLS_CERTFILE=/etc/hyperledger/fabric-ca-server-config/ca.org2.example.com-cert.pem
- FABRIC_CA_SERVER_TLS_KEYFILE=/etc/hyperledger/fabric-ca-server-config/e6a77b168161b5032d393f9590ad6e61c9d4cde51ca6cfeb8b9dc4d1932b2be9_sk
ports:
- "8054:7054"
command: sh -c 'fabric-ca-server start -b admin:adminpw -d'
volumes:
- ./crypto-config/peerOrganizations/org2.example.com/ca/:/etc/hyperledger/fabric-ca-server-config
container_name: ca.org2.example.com
networks:
- byfn
orderer.example.com:
extends:
file: base/docker-compose-base.yaml
service: orderer.example.com
container_name: orderer.example.com
networks:
- byfn
peer0.org1.example.com:
container_name: peer0.org1.example.com
extends:
file: base/docker-compose-base.yaml
service: peer0.org1.example.com
networks:
- byfn
peer1.org1.example.com:
container_name: peer1.org1.example.com
extends:
file: base/docker-compose-base.yaml
service: peer1.org1.example.com
networks:
- byfn
peer0.org2.example.com:
container_name: peer0.org2.example.com
extends:
file: base/docker-compose-base.yaml
service: peer0.org2.example.com
networks:
- byfn
peer1.org2.example.com:
container_name: peer1.org2.example.com
extends:
file: base/docker-compose-base.yaml
service: peer1.org2.example.com
networks:
- byfn
cli:
container_name: cli
image: hyperledger/fabric-tools:$IMAGE_TAG
tty: true
stdin_open: true
environment:
- GOPATH=/opt/gopath
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_LOGGING_LEVEL=DEBUG
#- CORE_LOGGING_LEVEL=INFO
- CORE_PEER_ID=cli
- CORE_PEER_ADDRESS=peer0.org1.example.com:7051
- CORE_PEER_LOCALMSPID=Org1MSP
#- CORE_PEER_TLS_ENABLED=true
#- CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt
#- CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key
#- CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
- CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin#org1.example.com/msp
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: /bin/bash
volumes:
- /var/run/:/host/var/run/
- ./../chaincode/:/opt/gopath/src/github.com/chaincode
- ./crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
- ./scripts:/opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/
- ./channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts
depends_on:
- orderer.example.com
- peer0.org1.example.com
- peer1.org1.example.com
- peer0.org2.example.com
- peer1.org2.example.com
networks:
- byfn
Then run the following to setup the network and install the chaincodes
#Startup dockers
docker-compose -f docker-compose-cli.yaml -f docker-compose-couch.yaml up -d
sleep 30
docker exec cli peer channel create -o orderer.example.com:7050 -c mychannel -f ./channel-artifacts/channel.tx
sleep 10
docker exec cli peer channel join -b mychannel.block
docker exec -e "CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin#org2.example.com/msp" -e "CORE_PEER_ADDRESS=peer0.org2.example.com:7051" -e "CORE_PEER_LOCALMSPID=Org2MSP" cli peer channel join -b mychannel.block
docker exec cli peer channel update -o orderer.example.com:7050 -c mychannel -f ./channel-artifacts/Org1MSPanchors.tx
docker exec -e "CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin#org2.example.com/msp" -e "CORE_PEER_ADDRESS=peer0.org2.example.com:7051" -e "CORE_PEER_LOCALMSPID=Org2MSP" cli peer channel update -o orderer.example.com:7050 -c mychannel -f ./channel-artifacts/Org2MSPanchors.tx
#Install chaincode
docker exec cli peer chaincode install -n fabcar -v 1.0 -p github.com/chaincode/fabcar/go
docker exec -e "CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin#org2.example.com/msp" -e "CORE_PEER_ADDRESS=peer0.org2.example.com:7051" -e "CORE_PEER_LOCALMSPID=Org2MSP" cli peer chaincode install -n fabcar -v 1.0 -p github.com/chaincode/fabcar/go
docker exec cli peer chaincode instantiate -o orderer.example.com:7050 -C mychannel -n fabcar -v 1.0 -c '{"Args":[""]}' -P "OR ('Org1MSP.member','Org2MSP.member')"
sleep 10
docker exec cli peer chaincode invoke -o orderer.example.com:7050 -C mychannel -n fabcar -c '{"function":"initLedger","Args":[""]}'
Next I run node enrollAdmin.js
'use strict';
/*
* Copyright IBM Corp All Rights Reserved
*
* SPDX-License-Identifier: Apache-2.0
*/
/*
* Enroll the admin user
*/
var Fabric_Client = require('fabric-client');
var Fabric_CA_Client = require('fabric-ca-client');
var path = require('path');
var util = require('util');
var os = require('os');
//
var fabric_client = new Fabric_Client();
var fabric_ca_client = null;
var admin_user = null;
var member_user = null;
var store_path = path.join(__dirname, 'hfc-key-store2');
console.log(' Store path:'+store_path);
// create the key value store as defined in the fabric-client/config/default.json 'key-value-store' setting
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:8054', tlsOptions , 'ca-org2', 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: 'Org2MSP',
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);
});
Then run node registerUser.js
'use strict';
/*
* Copyright IBM Corp All Rights Reserved
*
* SPDX-License-Identifier: Apache-2.0
*/
/*
* Register and Enroll a user
*/
var Fabric_Client = require('fabric-client');
var Fabric_CA_Client = require('fabric-ca-client');
var path = require('path');
var util = require('util');
var os = require('os');
//
var fabric_client = new Fabric_Client();
var fabric_ca_client = null;
var admin_user = null;
var member_user = null;
var store_path = path.join(__dirname, 'hfc-key-store2');
console.log(' Store path:'+store_path);
// create the key value store as defined in the fabric-client/config/default.json 'key-value-store' setting
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:8054', null , '', 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;
} else {
throw new Error('Failed to get admin.... run enrollAdmin.js');
}
// at this point we should have the admin user
// first need to register the user with the CA server
return fabric_ca_client.register({enrollmentID: 'User1', affiliation: 'org2.department1',role: 'client'}, admin_user);
}).then((secret) => {
// next we need to enroll the user with CA server
console.log('Successfully registered user2 - secret:'+ secret);
return fabric_ca_client.enroll({enrollmentID: 'User1', enrollmentSecret: secret});
}).then((enrollment) => {
console.log('Successfully enrolled member user "User1" ');
return fabric_client.createUser(
{username: 'User1',
mspid: 'Org2MSP',
cryptoContent: { privateKeyPEM: enrollment.key.toBytes(), signedCertPEM: enrollment.certificate }
});
}).then((user) => {
member_user = user;
return fabric_client.setUserContext(member_user);
}).then(()=>{
console.log('User1 was successfully registered and enrolled and is ready to intreact with the fabric network');
}).catch((err) => {
console.error('Failed to register: ' + err);
if(err.toString().indexOf('Authorization') > -1) {
console.error('Authorization failures may be caused by having admin credentials from a previous CA instance.\n' +
'Try again after deleting the contents of the store directory '+store_path);
}
});
Then node query.js
'use strict';
/*
* Copyright IBM Corp All Rights Reserved
*
* SPDX-License-Identifier: Apache-2.0
*/
/*
* Chaincode query
*/
var Fabric_Client = require('fabric-client');
var path = require('path');
var util = require('util');
var os = require('os');
//
var fabric_client = new Fabric_Client();
// setup the fabric network
var channel = fabric_client.newChannel('mychannel');
var peer = fabric_client.newPeer('grpc://localhost:9051');
channel.addPeer(peer);
//
var member_user = null;
var store_path = path.join(__dirname, 'hfc-key-store2');
console.log('Store path:'+store_path);
var tx_id = null;
// create the key value store as defined in the fabric-client/config/default.json 'key-value-store' setting
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);
// get the enrolled user from persistence, this user will sign all requests
return fabric_client.getUserContext('User1', true);
}).then((user_from_store) => {
if (user_from_store && user_from_store.isEnrolled()) {
console.log('Successfully loaded User1 from persistence');
member_user = user_from_store;
} else {
throw new Error('Failed to get User1.... run registerUser.js');
}
console.log('1');
// queryCar chaincode function - requires 1 argument, ex: args: ['CAR4'],
// queryAllCars chaincode function - requires no arguments , ex: args: [''],
const request = {
//targets : --- letting this default to the peers assigned to the channel
chaincodeId: 'fabcar',
fcn: 'queryAllCars',
args: ['']
};
console.log('2');
// send the query proposal to the peer
return channel.queryByChaincode(request);
}).then((query_responses) => {
console.log("Query has completed, checking results");
// query_responses could have more than one results if there multiple peers were used as targets
if (query_responses && query_responses.length == 1) {
if (query_responses[0] instanceof Error) {
console.error("error from query = ", query_responses[0]);
} else {
console.log("Response is ", query_responses[0].toString());
}
} else {
console.log("No payloads were returned from query");
}
}).catch((err) => {
console.log('3');
console.error('Failed to query successfully :: ' + err);
});
You have to check your channel configuration in configtx.yaml file.
Check if Org2 is part of the channel or not.
TwoOrgsChannel:
Consortium: SampleConsortium
<<: *ChannelDefaults
Application:
<<: *ApplicationDefaults
Organizations:
- *Org1
- *Org2
Capabilities:
<<: *ApplicationCapabilities
Check if the fabcar chaincode is installed on Org2 or not.
If you're using network-config.yaml like balance-transfer then check if peer has access to query the ledger or not.
peer0.org2.example.com:
endorsingPeer: true
chaincodeQuery: true
ledgerQuery: true
eventSource: true
Are you running these two organisations in separate machines?If so then you may have to copy the crypto materials . You can follow the link here for multiple machine setup for single organisation.
#ze9620, Your CLI environment variables configured for peer0 of org1, i think you can try by creating once more cli instance which contains evironmentals related to peer of org2 which may give the expected result.
I encountered the same issue from both a Java and NodeJS perspective. I noticed that when I was running the startFabric.sh in the fabcar directory that I was seeing:
docker exec -e "CORE_PEER_LOCALMSPID=Org1MSP" -e
"CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/msp/users/Admin#org1.example.com/msp" peer0.org1.example.com peer channel join -b mychannel.block
Error: error getting endorser client for channel: endorser client failed to connect to peer0.org1.example.com:7051: failed to create new connection: context deadline exceeded
so I did this: https://stackoverflow.com/a/52611722/10603426 and it worked for me
I think the problem is initially when you run the docker-compose file only the environment variables for ORG1 is set up and the peer(s) from ORG1is joined to the channel. You could try to do the same for ORG2 inside the cli container and make sure that the peer from ORG2 joins the channel using
peer channel join -b $CHANNEL_NAME.block
Hope this works. Good luck!