Installing bash-language-server in non global mode

Posted in Software | Leave a comment

Ethereum vs. Hyperledger: The Epilogue

I was very excited to work with Hyperledger when I first did a comparison between Ethereum vs. Hyperledger [1]. The ability to write chaincode in javascript was especially appealing to me. However after more than a month of spending time in the trenches and doing Hyperledger Fabric development, my opinions changed. If I were to revisit Part I of Ethereum vs. Hyperledger [1], I would add one more row to the table as follows:

Developer ExperienceF

I haven’t done any programming with Ethereum so don’t know how developer friendly it is but can safely say that Hyperledger scores an F on the developer experience. Lets try to break down the developer experience on following dimensions:

  1. Works without any issues
  2. SDK provides good, exhaustive and bug-free code samples showing how to write code and exercise functionality
  3. Comprehensive and accurate documentation
  4. Tech Support: When there is an issue, there is a helpful community to provide support

Rating Scale.

A – excellent. Scores +1 on all dimensions above
B – Good. Better than other alternatives out there
C – Fair. comparable to other alternative platforms
D – Poor. there exist better alternatives out there
F – Fail. -1 on all of the above dimensions

Hyperledger proudly scores an F

In reality Node.js v6.9.0-6.10.0 will land you in trouble. This is because Promises were introduced only in version 8 of Node.

  • Tech Support: virtually non-existent. You get what you pay for.

I could go on and add many more examples but above suffice.

Posted in Software | Leave a comment

Ethereum vs. Hyperledger – Which is better? Part I

Built for enterprise





Ability to write chaincode in familiar languages



Transactions can be non-deterministic



Support for private data


Enterprise Footprint


Cryptocurrency not needed


Membership Service Provider


  • Built For Enterprise:
“most enterprise apps would get tilted towards Fabric, whereas Ethereum would continue to be a hotbed for dApps that are more B2C”
Ethereum has the EVM running the Smart Contracts for applications that are attributed to being decentralized and are for mass consumption.
On the other hand, Hyperledger leverages blockchain technology for business.

  • Scalability:
  1. Ethereum uses a PoW consensus which is expensive whereas HL uses Apache Kafka to order the transactions and a customizable endorsement policy to drive consensus. Fabric’s consensus protocol can be changed and customized
  2. Ethereum uses order-execute architecture which requires all peers to execute every transaction whereas HL uses execute-order-validate architecture
  3. Ethereum can process 25 transactions per sec [1] whereas HL Fabric can process 3500 TPS [2]
  4. The experimental results, based on varying number of transactions, show that Hyperledger Fabric consistently outperforms Ethereum across all evaluation metrics which are execution time, latency and throughput. [3]. Also see [4] for more independent tests confirming the same
  • Ability to write chaincode in familiar languages: Ethereum smart contracts have to be written in Solidity language. HL Fabric chaincode can be written in Go, NodeJS or Java
  • Transactions can be non-deterministic: this is the reason why Ethereum does not support writing smart contract in a general purpose programming language
  • Support for private data: HL provides support for private data using channels and side-db. In Ethereum there are no means to issue a private transaction between members [3].
  • Enterprise Footprint: This is the most important factor that should be used to guide which platform to choose. Many big and reputed enterprises have deployed HL Fabric based blockchain solutions e.g.: I am not aware of any enterprise blockchain based on Ethereum (although I have not done exhaustive research here; also see this). JPMorgan has taken a fork of Ethereum and developed a new offering known as Quorum. there are enterprise apps built on Quorum. But Quorum is not Ethereum.
  • Cryptocurrency not needed: Ethereum requires use of a cryptocurrency known as Ether. HL Fabric has no concept of a cryptocurrency as it is N/A for enterprise apps.
  • Membership Service Provider: A MSP is what enables creation of a permissioned blockchain. Ethereum does not some with any MSP.

It is possible that Ethereum team will work to address the issues above so that its used in enterprise (see this). But in the meantime there is no reason not to use a platform that was specifically built for business.

Posted in Software | Tagged | Leave a comment

Understanding user registration and enrollment in Hyperledger Fabric


  • The bootstrap identity is defined by the username:password used in -b argument to fabric-ca-server start
  • The bootstrap identity is special and does not need a registration step. This is because it is automatically registered when the server starts
  • All other identities will first need to be registered by fabric-ca-client before they can be enrolled
  • If an identity that is not registered is tried to enroll, the enrollment will fail with following message on the fabric-ca server: “Failed to get user: : scode: 404, code: 63, msg: Failed to get User: sql: no rows in result set”. This gives us a clue as to what registration really does
  • fabric-ca-client assumes the identity of whatever is in $FABRIC_CA_HOME/msp
  • by default FABRIC_CA_HOME is set to /etc/hyperledger/fabric-ca-server
  • If TLS is enabled then:
    • we need to connect using https not http
    • we need to pass –tls.certfiles X to fabric-ca-client where X = the cert of the CA who issued cert to the server

When I read hyperledger docs and specifically the section on Enrolling Bootstrap Identity, I noticed it does not register a user before enrolling. This led me to think that a user can be enrolled without registering but that is not true. If one tries to enroll a user who has not been registered, the request will fail with following error message in fabric-ca server logs:

"Failed to get user: : scode: 404, code: 63, msg: Failed to get User: sql: no rows in result set"

So how come the bootstrap identity can be enrolled without registering? The answer is that when enrolling the bootstrap identity, the username and password must match the username and password given when fabric-ca-server was started. When the server is started, it automatically registers an identity with given username and password i.e., it stores a row in sql database with given username and password – that is what registration is about. When fabric-ca-client tries to enroll a user the server will check the sql database to first verify that the user exists and fail with above message otherwise. So all users except the bootstrap identity need to be registered first before enrolling.

we illustrate this below with some actual commands. Create a docker-compose.yaml file with following contents:

Screen Shot 2018-12-28 at 10.11.00 AM

now run it

$ docker-compose up

It should spin up a docker container named my-container. Log into the container:

$ docker exec -it my-container /bin/bash

since we have enabled TLS we need to connect using https instead of http. Also we need to add localhost to FABRIC_CA_SERVER_CSR_HOSTS otherwise will get an error saying

x509: certificate is valid for rca-ord, not localhost


root@1e046d83410d:/# fabric-ca-client enroll -u https://user:userpw@localhost:7054

2018/12/28 18:07:26 [INFO] TLS Enabled

Error: Failed to get client TLS config: No trusted root certificates for TLS were provided

what happened? we enabled TLS. so when the client tried to connect to the server, the server give it a cert but the client cannot verify authenticity of the certificate. The client needs to have the CA that issued cert to server in its trusted CA list. So to fix it run:

root@1e046d83410d:/# fabric-ca-client enroll -u https://user:userpw@localhost:7054 –tls.certfiles $FABRIC_CA_SERVER_HOME/tls-cert.pem
2018/12/28 17:32:28 [INFO] TLS Enabled
2018/12/28 17:32:28 [INFO] generating key: &{A:ecdsa S:256}
2018/12/28 17:32:28 [INFO] encoded CSR
Error: Response from server: Error Code: 20 – Authentication failure

on server:
my-container | 2018/12/28 17:32:28 [INFO] POST /enroll 401 23 “Failed to get user: : scode: 404, code: 63, msg: Failed to get User: sql: no rows in result set”

this is because user is not registered.

root@1e046d83410d:/# fabric-ca-client enroll -u https://admin:adminpw@localhost:7054 –tls.certfiles $FABRIC_CA_SERVER_HOME/tls-cert.pem
2018/12/28 17:25:38 [INFO] TLS Enabled
2018/12/28 17:25:38 [INFO] generating key: &{A:ecdsa S:256}
2018/12/28 17:25:38 [INFO] encoded CSR
2018/12/28 17:25:38 [INFO] Stored client certificate at /etc/hyperledger/fabric-ca-server/msp/signcerts/cert.pem
2018/12/28 17:25:38 [INFO] Stored root CA certificate at /etc/hyperledger/fabric-ca-server/msp/cacerts/localhost-7054.pem
2018/12/28 17:25:38 [INFO] Stored Issuer public key at /etc/hyperledger/fabric-ca-server/msp/IssuerPublicKey
2018/12/28 17:25:38 [INFO] Stored Issuer revocation public key at /etc/hyperledger/fabric-ca-server/msp/IssuerRevocationPublicKey

note we gave same username and password as the one used when starting the server. This is what defines the bootstrap identity – it is the user who started the server. And the command succeeds now. we can look at the cert of bootstrap identity as follows:

root@1e046d83410d:/# openssl x509 -in /etc/hyperledger/fabric-ca-server/msp/signcerts/cert.pem -text -noout
Version: 3 (0x2)
Serial Number:
Signature Algorithm: ecdsa-with-SHA256
Issuer: C=US, ST=North Carolina, O=Hyperledger, OU=Fabric, CN=rca-ord
Not Before: Dec 28 17:21:00 2018 GMT
Not After : Dec 28 17:26:00 2019 GMT
Subject: C=US, ST=North Carolina, O=Hyperledger, OU=client, CN=admin
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
ASN1 OID: prime256v1
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature
X509v3 Basic Constraints: critical
X509v3 Subject Key Identifier:
X509v3 Authority Key Identifier:

X509v3 Subject Alternative Name:
Signature Algorithm: ecdsa-with-SHA256

Lets try to enroll the user defined in BOOTSTRAP_USER_PASS variable when we started the server

root@1e046d83410d:/# fabric-ca-client enroll -u https://rca-ord-admin:rca-ord-adminpw@localhost:7054 –tls.certfiles $FABRIC_CA_SERVER_HOME/tls-cert.pem
2018/12/28 17:36:03 [INFO] TLS Enabled
2018/12/28 17:36:03 [INFO] generating key: &{A:ecdsa S:256}
2018/12/28 17:36:03 [INFO] encoded CSR
Error: Response from server: Error Code: 20 – Authentication failure

my-container | 2018/12/28 17:36:03 [INFO] POST /enroll 401 23 “Failed to get user: : scode: 404, code: 63, msg: Failed to get User: sql: no rows in result set”

it does not work. Lets try to enroll a new user

root@1e046d83410d:/# fabric-ca-client register – admin2 –id.affiliation org1.department1 –id.attrs ‘hf.Revoker=true,admin=true:ecert’ -u https://localhost:7054 –tls.certfiles $FABRIC_CA_SERVER_HOME/tls-cert.pem
2018/12/28 17:42:34 [INFO] Configuration file location: /etc/hyperledger/fabric-ca-server/fabric-ca-client-config.yaml
2018/12/28 17:42:34 [INFO] TLS Enabled
2018/12/28 17:42:34 [INFO] TLS Enabled
Password: mMNrwlSgLXqE

Things to note:

  1. Note that we enrolled bootstrap user earlier and above command ran under its identity. the fabric-ca-client will take identity from $FABRIC_CA_HOME/msp
  2. Since we did not specify any password the server generated one for us

Example showing password set at time of registration:

root@1e046d83410d:/# fabric-ca-client register – test-user1 –id.secret test-user1pw –id.affiliation org1.department1 -u https://localhost:7054 –tls.certfiles $FABRIC_CA_SERVER_HOME/tls-cert.pem
2018/12/28 17:46:03 [INFO] Configuration file location: /etc/hyperledger/fabric-ca-server/fabric-ca-client-config.yaml
2018/12/28 17:46:03 [INFO] TLS Enabled
2018/12/28 17:46:03 [INFO] TLS Enabled
Password: test-user1pw

Also note what happens below:

root@1e046d83410d:/# mv /etc/hyperledger/fabric-ca-server/msp /etc/hyperledger/fabric-ca-server/msp1

root@1e046d83410d:/# fabric-ca-client register – test-user2 –id.secret test-user2pw –id.affiliation org1.department1 -u https://localhost:7054 –tls.certfiles $FABRIC_CA_SERVER_HOME/tls-cert.pem
2018/12/28 19:38:00 [INFO] Configuration file location: /etc/hyperledger/fabric-ca-server/fabric-ca-client-config.yaml
2018/12/28 19:38:00 [INFO] TLS Enabled
2018/12/28 19:38:00 [ERROR] Enrollment check failed: Idemix enrollment information does not exist
Error: Enrollment information does not exist. Please execute enroll command first. Example: fabric-ca-client enroll -u http://user:userpw@serverAddr:serverPort

So it looks like fabric-ca-client is taking its identity from /etc/hyperledger/fabric-ca-server/msp which is same as $FABRIC_CA_HOME/msp

PS: I am not able to get wordpress to post code. I have tried wrapping code blocks in tags as explained here but every time i have more than one line in my code, wordpress would insert p and span tags and mess it up. I haven’t found a solution to this. When I try to google this problem i come across links saying to edit functions.php file but this file cannot be accessed from I think the file can only be access if someone is running a self-hosted blog using the open source code. does not allow ftp. i cannot find functions.php under Admin -> Appearance -> … I hate wordpress.

Posted in Software | Leave a comment

E1219 23:48:19.159391389 19] Could not get common name of subject from certificate.

Returned back from vacation to find this error when I try to run hyperledger fabric sample. It used to work just fine before I left on vacation. What gives?

WITSC02X6385JGH:fabric-ca sjain68$ docker logs -f dev-peer1-jnj-mycc-1.0

> chaincode@1.0.0 start /usr/local/src

> node chaincode.js "--peer.address" "peer1-jnj:7052"

E1219 23:48:19.159391389      19] Could not get common name of subject from certificate.

{ fcn: 'create', params: [ '00000' ] }

SyntaxError: Unexpected token  in JSON at position 0

    at JSON.parse ()

    at new ClientIdentity (/usr/local/src/node_modules/fabric-shim/lib/chaincode.js:246:27)

    at Chaincode.Invoke (/usr/local/src/chaincode.js:29:17)

Turns out there is some problem with v0.3.4 of X509 library that was released recently. Change dependencies to use 1.3.2 of fabric-shim and error should go away. 1.3.2 locks x509 version to 0.3.3. Writing this post to remind myself that the same code I wrote today may not work tomorrow. When that happens its usually a dependency problem – someone pulled the carpet from below my feet. So its better to always lock the versions of dependencies.

Btw The actual error that is happening here is

SyntaxError: Unexpected token  in JSON at position 0     at JSON.parse ()     at new ClientIdentity (/usr/local/src/node_modules/fabric-shim/lib/chaincode.js:246:27)     at Chaincode.Invoke (/usr/local/src/chaincode.js:29:17)

The E1219 23:48:19.159391389 19] Could not get common name of subject from certificate happens with any chaincode. It happens when following command is run:

> node chaincode.js “–peer.address” “peer1-jnj:7052”

Posted in Software | Leave a comment

Suggested 5 day itinerary for Hawaii

Which Island to Visit? Maui

Where to book? Book flights + hotel + car at

Total days needed? 7 (1 day to fly in and 1 day to fly back)

Where to stay? for 3 star recommend Napili Surf Beach Resort. For 4-5 star recommend Hyatt Regency or another 4 star property along Kaanapali Beach (Westin, Marriot, Sheraton etc.)

Where not to stay? Napili Shores by Outrigger. Not a disaster but Napili Surf Beach Resort is right next to it and more updated with same price.

What car to rent? Full size car like Hyundai Sonata. We had 4 pieces of baggage (3 carry-on sized, 1 bigger), 2 bagpacks, 1 stroller, 1 carseat for baby and it fit in the Sonata. There is Costco Gas near airport to fill up the tank before returning the car.

Where to rent beach gear? Boss Frog. They have locations all over Maui including Napili, Lahaina, Kihei. You can drop off your gear at any of their locations, not necessarily the one from where you picked it up.

Where to buy groceries? You can buy some on the day you land at the Costco near the airport. On other days there is a good grocery store called Napili Market in the nearby Napili Plaza if you are staying at the Napili Surf Beach Resort. There is also a Safeway in Lahaina.

Day 1 – Lahaina, Front St. Beware of many shops selling discount tickets to helicopter tours and other activities. They will require you to attend some seminar where they will try to sell you some condo or property in Hawaii. Just stay clear of them. Be prepared to pay $7/hr parking.

Day 2 – Maui Ocean Center and adjacent Harbor Shops at Maalaea Harbor. Eat at Seascape and coffee at Hula Cookies in Harbor Shops. You can buy ocean center tickets online at to get some discount.

Day 3 – Snorkel at Molokini Island. Book at Blue Water Rafting. Rent a wet suit from Boss Frog before going to snorkel. Blue Water Rafting will not provide any wet suit. Eat at Choice Health Bar in Lahaina. Have coffee on the way back at the Coffee Store in Napili Plaza.

Day 4 – Helicopter tour of Hana Rainforest. Book at Maverick Helicopters. I think Maverick is the only operator who does a landing at the Hana Rainforest so you can explore it on foot. Eat at AA Roots in Napili Plaza.

Day 5 – Boogie boarding at the beach. Check out Whaler’s Village and while there buy some cookies at Honolulu Cookies (ask them to validate parking) and spend evening watching Drums of the Pacific Maui at Hyatt Regency. Take some warm jacket as it will get about 10-12 degrees cooler in the night and you might want to have it. Hyatt Regency has valet parking for $5 which is worth it IMO.

Total Distance Covered by car: 300 miles

Further Notes:

  • Be prepared for strong winds.
  • You may rent a beach package from Maui Vacation Equipment including a Coleman tent, baby toys, a cooler and 2 Tommy Bahama Chairs for one week. You pay them in advance and they deliver the gear to your room before you check in at the hotel. They also pick it up and the delivery is included in the price. We did so but didn’t end up using it so YMMV (your mileage may vary).
Posted in Travel | Leave a comment

Unwanted redirect from Gmail to OneLogin

Is Google Chrome redirecting you to onelogin whenever you try to login into any Google account? This is how to fix it:

  1. Open Chrome
  2. Type chrome://settings/siteData
  3. search for onelogin in top right (see example screenshot below)
  4. Capture00
  5. Delete the onelogin cookies
  6. Now try logging to gmail again. Again see the annoying redirect?
  7. This time search for  in the top right
  8. Delete it (this is the crucial step)
  9. Now it should work.
Posted in Software | Leave a comment