Aller au contenu principal

How to set up a Fabric chaincode for local dev

· 4 minutes de lecture
Calev Eliacheff

Working on a project using Hyperledger Firefly with Fabconnect Gateway, I struggled to make tests when developing the chaincode against a Firefly instance. I wanted immediate feedback and testing on my code, without a complex setup, the possibility to reset the instance etc ... Most online documentation only show how to deploy the chaincode using the regular heavy deploy process (install / approve / commit), or using the test-network only like the official CCAAS doc. But I wanted to have a Firefly setup with Fabconnect as Gateway, so none were a solution.

info

The best and up-to-date documentation on fullstack chaincode development is here https://github.com/hyperledger/fabric-samples/tree/main/full-stack-asset-transfer-guide The others part of the repo are too old or have only sparse documentation.

After taking too much time to find an efficient way to do, here is my current setup I'm really satisfied with:

Tech stack we will use

  • Blockchain: Fabric
  • Firefly + Fabconnect
  • Chaincode: Node + Typescript

We are going to use the CCAAS (Chaincode As A Service) builder, available since Fabric 2.2. There are a few gotchas, so let's go straight to the steps:

Prerequisites

Dependencies

  • A chaincode project in Nodejs + TS (I used the one from the samples' repo)
  • docker and docker-compose.
  • Fabric binaries (not mandatory, but useful)
  • Firefly

Install Fabric

We will need the peer command to work. In order to get binaries without downloading the full repo, choose a folder and use the official script:

mkdir fabric-binaries && cd fabric-binaries
curl -sSLO https://raw.githubusercontent.com/hyperledger/fabric/main/scripts/install-fabric.sh && chmod +x install-fabric.sh

Then run ./install-fabric.sh binary.

Next add the generated bin folder to your $PATH.

Install Firefly CLI

Use instructions on https://hyperledger.github.io/firefly/gettingstarted/firefly_cli.html

Initial Setup

Setup Firefly with Fabric:

ff init fabric dev 3
attention

If you have problems pulling the images, you may need to docker login. Documentation here

The environnement will create compose files in ~/.firefly/stacks/dev.

Now I will override some docker settings:

  • (May be optional) I needed a more up-to-date peer and orderer versions, since they are only at v2.2 by default. v2.4 brings a better CCAAS support and some goodies.
  • The extra_hosts part is mandatory and will be useful in the next part.

Replace the ~/.firefly/stacks/dev/docker-compose.override.yml with

~/.firefly/stacks/dev/docker-compose.override.yml
version: "2.1"

services:
fabric_orderer:
image: hyperledger/fabric-orderer:2.4.7
fabric_peer:
image: hyperledger/fabric-peer:2.4.7
extra_hosts:
- "host.docker.internal:host-gateway"

Now we can start the stack

ff start dev

Creating the CCAAS

attention

I won't explain all the steps here, check the doc if you want to deep dive about CCAAS:

remarque

You can also use the scripts in ./builders/ccaas/bin/{build, detect, release}, but the process is simple enough

Create two files:

metadata.json
{
"type": "ccaas",
"label": "asset-transfer"
}
connection.json
{
"address":"host.docker.internal:9999",
"dial_timeout":"15s"
}

Here we are outside the docker network, so the host.docker.internal will bridge us with the docker internal network we exposed earlier in extra_hosts.

Now we can build the package, which is a simple archive in archive:

#!/usr/bin/env bash

tar -czf code.tar.gz connection.json
tar -czf asset-transfer.tgz code.tar.gz metadata.json

rm code.tar.gz

Now we just need to install the fake chaincode one for good. Easiest way is to use the ff deploy command

astuce

Why can't we use ff deploy to update chaincode ? Because ff deploy was designed for CI/CD, and can't update chaincode.

ff deploy fabric dev asset-transfert.tgz firefly asset-transfert.tgz 1.0.0

Easy ! Now the setup is complete. Let's connect our chaincode.

Setting up the chaincode

If you have copied the default chaincode, you should already have these lines in your package.json, if not, add them:

{
// ...
"scripts": {
// ...
"start:server-nontls": "set -x && fabric-chaincode-node server --chaincode-address=$CHAINCODE_SERVER_ADDRESS --chaincode-id=$CHAINCODE_ID",
"start:server-debug": "set -x && NODE_OPTIONS='--inspect=0.0.0.0:9229' fabric-chaincode-node server --chaincode-address=$CHAINCODE_SERVER_ADDRESS --chaincode-id=$CHAINCODE_ID",
"start:server": "set -x && fabric-chaincode-node server --chaincode-address=$CHAINCODE_SERVER_ADDRESS --chaincode-id=$CHAINCODE_ID --chaincode-tls-key-file=/hyperledger/privatekey.pem --chaincode-tls-client-cacert-file=/hyperledger/rootcert.pem --chaincode-tls-cert-file=/hyperledger/cert.pem"
},
// ...
}

Now we need to set the vars and run the server, I wrote a small bash script, but you can i.e. hardcode them in your shell vars.

#!/usr/bin/env bash

export CHAINCODE_SERVER_ADDRESS=0.0.0.0:9999
export CHAINCODE_ID=$(peer lifecycle chaincode calculatepackageid asset-transfert.tgz)

npm run start:server-debug

Now we want to reload the chaincode every time a file is changed. The easiest thing I found is tsc-watch.

npm i --save-dev tsc-watch

then add to your package.json scripts:

"start:dev": "tsc-watch --outDir ./dist --onSuccess './scripts/runLocally.sh'",

And we are done ! Just start your chaincode with npm run start:dev, edit some files, and enjoy realtime chaincode changes on Firefly !