0

I want to connect to hyperledger fabric blockchain network on Amazon Managed Blockchain using nodejs sdk. Fabric client is a cloud9 instance, which already setup and successfully connected to peer node using fabric cli inside a docker container. But when I try to use nodejs sdk to connect to network with this code:

'use strict';

const FabricCAServices = require('fabric-ca-client');
const { Wallets, Gateway, X509Identity, User } = require('fabric-network');
const fs = require('fs');
const path = require('path');
const yaml = require('js-yaml');

const ccpPath = path.resolve(__dirname, 'connection_profile.yaml');
const ccp = yaml.load(fs.readFileSync(ccpPath, 'utf8'));

async function main() {
  try {
    const walletPath = path.join(process.cwd(), 'wallet');
    const wallet = await Wallets.newFileSystemWallet(walletPath);
    const gateway = new Gateway();
    const gatewayOptions = {identity: 'admin', wallet: wallet, discovery: {enabled: true, asLocalhost: false }}
    await gateway.connect(ccp, gatewayOptions);
    const network = await gateway.getNetwork('mychannel');
  } catch (error) {
    console.error(`Some error is occurred: ${error.stack}`);
    process.exit(1);
  }
}

main();

With content of "connection_profile.yaml" file is:

name: "ABC"
x-type: hlfv1
version: "1.0"

channels:
  mychannel:
    orderers:
      - ABCOrderer
    peers:
      peer1:
        endorsingPeer: true
        chaincodeQuery: true
        ledgerQuery: true
        eventSource: true

organizations:
  abc:
    mspid: m-***
    peers:
      - peer1
    certificateAuthorities:
      - abc

orderers:
  ABCOrderer:
    url: grpcs://orderer.n-***.managedblockchain.ap-northeast-1.amazonaws.com:30001
    grpcOptions:
      ssl-target-name-override: orderer.n-***.managedblockchain.ap-northeast-1.amazonaws.com
    tlsCACerts:
      # path: /home/ec2-user/managedblockchain-tls-chain.pem
      path: /home/ec2-user/admin-msp/admincerts/cert.pem

peers:
  peer1:
    url: grpcs://nd-***.managedblockchain.ap-northeast-1.amazonaws.com:30003
    eventUrl: grpcs://nd-***.managedblockchain.ap-northeast-1.amazonaws.com:30004
    grpcOptions:
      ssl-target-name-override: nd-***.managedblockchain.ap-northeast-1.amazonaws.com
    tlsCACerts:
      # path: /home/ec2-user/managedblockchain-tls-chain.pem
      path: /home/ec2-user/admin-msp/admincerts/cert.pem

certificateAuthorities:
  abc:
    url: https://ca.m-***.managedblockchain.ap-northeast-1.amazonaws.com:30002
    httpOptions:
      verify: true
    tlsCACerts:
      # path: /home/ec2-user/managedblockchain-tls-chain.pem
      path: /home/ec2-user/admin-msp/admincerts/cert.pem
    caName: m-***

"/home/ec2-user/admin-msp/admincerts/cert.pem" is file is created by enroll member admin identity (follow this aws guide: https://docs.aws.amazon.com/managed-blockchain/latest/hyperledger-fabric-dev/get-started-enroll-admin.html). Then after 3s the console show this error:

2022-07-05T13:22:52.812Z - error: [ServiceEndpoint]: Error: Failed to connect before the deadline on Endorser- name: peer1, url:grpcs://nd-***.managedblockchain.ap-northeast-1.amazonaws.com:30003, connected:false, connectAttempted:true
2022-07-05T13:22:52.814Z - error: [ServiceEndpoint]: waitForReady - Failed to connect to remote gRPC server peer1 url:grpcs://nd-***.managedblockchain.ap-northeast-1.amazonaws.com:30003 timeout:3000
2022-07-05T13:22:52.814Z - info: [NetworkConfig]: buildPeer - Unable to connect to the endorser peer1 due to Error: Failed to connect before the deadline on Endorser- name: peer1, url:grpcs://nd-***.managedblockchain.ap-northeast-1.amazonaws.com:30003, connected:false, connectAttempted:true
2022-07-05T13:22:55.817Z - error: [ServiceEndpoint]: Error: Failed to connect before the deadline on Committer- name: ABCOrderer, url:grpcs://orderer.n-***.managedblockchain.ap-northeast-1.amazonaws.com:30001, connected:false, connectAttempted:true
2022-07-05T13:22:55.817Z - error: [ServiceEndpoint]: waitForReady - Failed to connect to remote gRPC server ABCOrderer url:grpcs://orderer.n-***.managedblockchain.ap-northeast-1.amazonaws.com:30001 timeout:3000
2022-07-05T13:22:55.818Z - info: [NetworkConfig]: buildOrderer - Unable to connect to the committer ABCOrderer due to Error: Failed to connect before the deadline on Committer- name: ABCOrderer, url:grpcs://orderer.n-***.managedblockchain.ap-northeast-1.amazonaws.com:30001, connected:false, connectAttempted:true
Some error is occurred: TypeError: Cannot read property 'toArray' of null
    at EC.sign (/home/ec2-user/src-test/node_modules/elliptic/lib/elliptic/ec/index.js:104:30)
    at CryptoSuite_ECDSA_AES.sign (/home/ec2-user/src-test/node_modules/fabric-common/lib/impl/CryptoSuite_ECDSA_AES.js:215:25)
    at Signer.sign (/home/ec2-user/src-test/node_modules/fabric-common/lib/Signer.js:59:28)
    at SigningIdentity.sign (/home/ec2-user/src-test/node_modules/fabric-common/lib/SigningIdentity.js:71:23)
    at IdentityContext.sign (/home/ec2-user/src-test/node_modules/fabric-common/lib/IdentityContext.js:91:40)
    at DiscoveryService.sign (/home/ec2-user/src-test/node_modules/fabric-common/lib/ServiceAction.js:69:40)
    at NetworkImpl._initializeInternalChannel (/home/ec2-user/src-test/node_modules/fabric-network/lib/network.js:298:35)
    at NetworkImpl._initialize (/home/ec2-user/src-test/node_modules/fabric-network/lib/network.js:250:20)
    at Gateway.getNetwork (/home/ec2-user/src-test/node_modules/fabric-network/lib/gateway.js:350:26)
    at main (/home/ec2-user/src-test/enrollUser.js:38:35)

So I think the problem probably is my connection_profile setting, which I mimic connection-profile-template.yaml file from aws blockchain samples code (https://github.com/aws-samples/non-profit-blockchain/tree/master/ngo-lambda).

# Copyright 2018 Amazon.com, Inc. or its affiliates. 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.
# A copy of the License is located at
# 
#     http://www.apache.org/licenses/LICENSE-2.0
# 
# or in the "license" file accompanying this file. This file 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.

name: "ngo"
x-type: "hlfv1"
description: "NGO Network"
version: "1.0"

channels:
  mychannel:
    orderers:
      - orderer.com
    peers:
      peer1:
        endorsingPeer: true
        chaincodeQuery: true
        ledgerQuery: true
        eventSource: true

organizations:
  Org1:
    mspid: %MEMBERID%
    peers:
      - peer1
    certificateAuthorities:
      - ca-org1

orderers:
  orderer.com:
    url: grpcs://%ORDERINGSERVICEENDPOINT%
    grpcOptions:
      ssl-target-name-override: %ORDERINGSERVICEENDPOINTNOPORT%
    tlsCACerts:
      path: %CAFILE%

peers:
  peer1:
    url: grpcs://%PEERSERVICEENDPOINT%
    eventUrl: grpcs://%PEEREVENTENDPOINT%
    grpcOptions:
      ssl-target-name-override: %PEERSERVICEENDPOINTNOPORT%
    tlsCACerts:
      path: %CAFILE%

certificateAuthorities:
  ca-org1:
    url: https://%CASERVICEENDPOINT%
    httpOptions:
      verify: false
    tlsCACerts:
      path: %CAFILE%
    caName: %MEMBERID%

So, any idea or suggestion on how can I fix it? Any help would be appreciated. Thank You!

Updated_1: I try both key file from AWS S3(managedblockchain-tls-chain.pem) and key created by CA for admin. But both do not seem to work. Here is the error when I try with key file from S3:

Some error is occurred: TypeError: Cannot read property 'toArray' of null
    at EC.sign (/home/ec2-user/src-test/node_modules/elliptic/lib/elliptic/ec/index.js:104:30)
    at CryptoSuite_ECDSA_AES.sign (/home/ec2-user/src-test/node_modules/fabric-common/lib/impl/CryptoSuite_ECDSA_AES.js:215:25)
    at Signer.sign (/home/ec2-user/src-test/node_modules/fabric-common/lib/Signer.js:59:28)
    at SigningIdentity.sign (/home/ec2-user/src-test/node_modules/fabric-common/lib/SigningIdentity.js:71:23)
    at IdentityContext.sign (/home/ec2-user/src-test/node_modules/fabric-common/lib/IdentityContext.js:91:40)
    at DiscoveryService.sign (/home/ec2-user/src-test/node_modules/fabric-common/lib/ServiceAction.js:69:40)
    at NetworkImpl._initializeInternalChannel (/home/ec2-user/src-test/node_modules/fabric-network/lib/network.js:298:35)
    at NetworkImpl._initialize (/home/ec2-user/src-test/node_modules/fabric-network/lib/network.js:250:20)
    at Gateway.getNetwork (/home/ec2-user/src-test/node_modules/fabric-network/lib/gateway.js:350:26)
    at main (/home/ec2-user/src-test/enrollUser.js:38:35)

Updated 2: Maybe the problem is my admin identity inside wallet, so I update the code to save admin identity to the wallet:

const caURL = ccp.certificateAuthorities['abc'].url;
const ca = new FabricCAServices(caURL);
const enrollment = await ca.enroll({ enrollmentID: 'admin', enrollmentSecret: 'Adminpassword' });

const X509Identity = {
  credentials: {
    certificate: enrollment.certificate,
    privateKey: enrollment.rootCertificate,
  },
  mspId: ccp.organizations['abc'].mspid,
  type: 'X.509',
};
// Create a new file system based wallet for managing identities.
const walletPath = path.join(process.cwd(), 'wallet');
const wallet = await Wallets.newFileSystemWallet(walletPath);
await wallet.put('admin', X509Identity);

Updated_3: As @david_k suggests, the problem is my identity inside the wallet is wrong, and as the result, it is denied by the gateway. So the line privateKey in Update_2 needs to be changed from privateKey: enrollment.rootCertificate, to privateKey: enrollment.key.toBytes(),

Thank you very much @david_k!

KhoaHV
  • 61
  • 1
  • 3
  • 1
    Most likely you are using the wrong file for the tls CA cert. The tls CA cert you should reference is the one you download from S3 storage that the AWS documentation tells you to download and name it `/home/ec2-user/managedblockchain-tls-chain..pem`. – david_k Jul 05 '22 at 21:38
  • @david_k Thank you for your response. As I updated in question, the managedblockchain-tls-chain.pem does not work too. Any other suggestion? – KhoaHV Jul 06 '22 at 00:39
  • 1
    Only used the `managedblockchain-tls-chain.pem` as the tlsCACert not as an identity, you should use your enrolled admin identity as the identity for your application. The error you post looks like the gateway doesn't like your application identity you are using – david_k Jul 06 '22 at 06:41
  • I think what you mean is the problem is my wallet identity, doesn't it? I updated code is used to save my admin identity to my wallet. Please help me to see any problem with it. – KhoaHV Jul 06 '22 at 06:55
  • 1
    you are putting the wrong value into `privateKey`, it shouldn't be the root certificate, it should be the private key, see https://github.com/hyperledger/fabric-samples/blob/9f844e5de3195f488797ca87598d7cbefff0c399/test-application/javascript/CAUtil.js#L41 – david_k Jul 06 '22 at 07:11
  • @david_k I change privateKey as you suggest, and was able connected to channel. Thank you very much! – KhoaHV Jul 06 '22 at 07:21

0 Answers0