Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
* Attach `fabric-ca-server-config.yaml` as a volume [#168](https://github.com/hyperledger-labs/fablo/issues/168)
* Support tls for CA [#229](https://github.com/hyperledger-labs/fablo/issues/229)
* Use nvm to switch node version for chaincode build
* Allow to run peers in dev mode [#126](https://github.com/hyperledger-labs/fablo/issues/126)
* Allow to install each chaincode manually

### Fixes
* Support Apple M1 / arm64 architecture
Expand Down
73 changes: 68 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,22 @@ In this case, however, you should use generated `fablo-docker.sh` instead of `fa
### init

```bash
fablo init [node]
fablo init [node] [rest] [dev]
```

Creates simple network config file in current dir.
Good step to start your adventure with Fablo or set up a fast prototype.

Option `node` makes Fablo to generate a sample Node.js chaincode as well.
Fablo `init` command takes three parameters (the order does not matter):
* Option `node` makes Fablo to generate a sample Node.js chaincode as well.
* Option `rest` enables simple REST API with [Fablo REST](https://github.com/softwaremill/fablo-rest) as standalone Docker container.
* Option `dev` enables running peers in dev mode (so the hot reload for chaincode is possible).

Sample command:

```bash
fablo init node dev
```

Generated `fablo-config.json` file uses single node Solo consensus and no TLS support.
This is the simplest way to start with Hyperledger Fabric, since Raft consensus requires TLS and TLS itself adds a lot of complexity to the blockchain network and integration with it.
Expand Down Expand Up @@ -178,16 +187,69 @@ If you want to use Fablo for network configuration setup only, then the `fabric-

## Managing chaincodes

### chaincode(s) install

```bash
fablo chaincodes install
```
Install all chaincodes. Might be useful if for some reason, Fablo won't manage to do it by itself.

If you want to install a single chaincode defined in Fablo config file, execute:

```bash
fablo chaincode install <chaincode-name> <version>
```

### chaincode upgrade

```bash
fablo chaincode upgrade chaincode-name version
fablo chaincode upgrade <chaincode-name> <version>
```

Upgrades and instantiates chaincode with given name on all relevant peers.
Upgrades chaincode with given name on all relevant peers.
Chaincode directory is specified in Fablo config file.

## Chaincode scripts
### Running chaincodes in dev mode

Hyperledger Fabric allows to run peers in [dev mode](https://hyperledger-fabric.readthedocs.io/en/release-2.4/peer-chaincode-devmode.html) in order to allow simple develop of chaincodes.
In this case chaincodes do not need to be upgraded each time, but they are run locally.
This feature allows hot reload of chaincode code and speeds up the development a lot.

Fablo will run peers in dev mode when `global.peerDevMode` is set to `true`.
Note: in this case TLS has to be disabled, otherwise config validation fails.

The simplest way of trying Fablo with dev mode is as follows:

1. Execute `fablo init node dev`.
It will initialize Fablo config file with sample node chaincode and dev mode enabled.
In this case Fablo config file has `global.peerDevMode` set to `true`, and the `package.json` file for sample Node.js chaincode has a script for running chaincode in dev mode (`start:dev`).
2. Start the network with `fablo up`.
Because dev mode is enabled, chaincode containers don't start.
Instead, Fablo approves and commits chaincode definitions from Fablo config file.
3. Npm install and start the sample chaincode with:
```bash
(cd chaincodes/chaincode-kv-node && nvm use && npm i && npm run start:watch)
```
Now, when you update the chaincode source code, it will be automatically refreshed on Hyperledger Fabric Network.

Our sample chaincode definition contains some scripts for running chaincode in dev mode:

```json
"scripts": {
...
"start:dev": "fabric-chaincode-node start --peer.address \"127.0.0.1:8541\" --chaincode-id-name \"chaincode1:0.0.1\" --tls.enabled false",
"start:watch": "nodemon --exec \"npm run start:dev\"",
...
},
```

Worth considering:
* If you want chaincode to be running on multiple peers, you need to start it multiple times, specifying different `--peer.address`
* In case of errors ensure you have the same `--chaincode-id-name` as `CC_PACKAGE_ID` in Fablo output.

Feel free to update this scripts to adjust it to your chaincode definition.

## Channel scripts

### channel help

Expand Down Expand Up @@ -279,6 +341,7 @@ Example:
"global": {
"fabricVersion": "2.3.0",
"tls": false,
"peerDevMode": false,
"monitoring": {
"loglevel": "debug"
},
Expand Down
5 changes: 3 additions & 2 deletions docs/sample.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
{
"$schema": "https://github.com/softwaremill/fablo/releases/download/1.0.3-unstable/schema.json",
"$schema": "https://github.com/softwaremill/fablo/releases/download/1.1.0-unstable/schema.json",
"global": {
"fabricVersion": "2.3.2",
"tls": false
"tls": false,
"peerDevMode": false
},
"orgs": [
{
Expand Down
8 changes: 7 additions & 1 deletion docs/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
],
"properties": {
"$schema": {
"const": "https://github.com/softwaremill/fablo/releases/download/1.0.3-unstable/schema.json"
"const": "https://github.com/softwaremill/fablo/releases/download/1.1.0-unstable/schema.json"
},
"global": {
"$id": "#/properties/global",
Expand Down Expand Up @@ -68,6 +68,12 @@
"type": "boolean",
"default": true
},
"peerDevMode": {
"$id": "#/properties/global/properties/peerDevMode",
"title": "Start all peers in dev mode",
"type": "boolean",
"default": false
},
"monitoring": {
"$id": "#/properties/monitoring",
"title": "Monitoring settings",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2052,10 +2052,14 @@ elif [ \\"$1\\" = \\"start\\" ]; then
startNetwork
elif [ \\"$1\\" = \\"stop\\" ]; then
stopNetwork
elif [ \\"$1\\" = \\"chaincode\\" ] && [ \\"$2\\" = \\"install\\" ]; then
elif [ \\"$1\\" = \\"chaincodes\\" ] && [ \\"$2\\" = \\"install\\" ]; then
installChaincodes
elif [ \\"$1\\" = \\"chaincode\\" ] && [ \\"$2\\" = \\"install\\" ]; then
installChaincode \\"$3\\" \\"$4\\"
elif [ \\"$1\\" = \\"chaincode\\" ] && [ \\"$2\\" = \\"upgrade\\" ]; then
upgradeChaincode \\"$3\\" \\"$4\\"
elif [ \\"$1\\" = \\"chaincode\\" ] && [ \\"$2\\" = \\"dev\\" ]; then
runDevModeChaincode \\"$3\\" \\"$4\\"
elif [ \\"$1\\" = \\"channel\\" ]; then
channelQuery \\"\${@:2}\\"
elif [ \\"$1\\" = \\"snapshot\\" ]; then
Expand All @@ -2077,7 +2081,7 @@ fi
`;

exports[`samples/fablo-config-hlf1.3-2orgs-1chaincode-private-data.json should create proper e2e/__tmp__/samples/fablo-config-hlf1.3-2orgs-1chaincode-private-data.json.tmpdir/fablo-target/fabric-docker/.env from samples/fablo-config-hlf1.3-2orgs-1chaincode-private-data.json 1`] = `
"FABLO_VERSION=1.0.3-unstable
"FABLO_VERSION=1.1.0-unstable
FABLO_BUILD=<date with git hash>
FABLO_REST_VERSION=0.1.0
HYPERLEDGER_EXPLORER_VERSION=1.1.8
Expand Down Expand Up @@ -2316,18 +2320,41 @@ installChaincodes() {

}

notifyOrgsAboutChannels() {
printHeadline \\"Creating new channel config blocks\\" \\"U1F537\\"
createNewChannelUpdateTx \\"my-channel1\\" \\"Org1MSP\\" \\"MyChannel1\\" \\"$FABLO_NETWORK_ROOT/fabric-config\\" \\"$FABLO_NETWORK_ROOT/fabric-config/config\\"
createNewChannelUpdateTx \\"my-channel1\\" \\"Org2MSP\\" \\"MyChannel1\\" \\"$FABLO_NETWORK_ROOT/fabric-config\\" \\"$FABLO_NETWORK_ROOT/fabric-config/config\\"
installChaincode() {
local chaincodeName=\\"$1\\"
if [ -z \\"$chaincodeName\\" ]; then
echo \\"Error: chaincode name is not provided\\"
exit 1
fi

printHeadline \\"Notyfing orgs about channels\\" \\"U1F4E2\\"
notifyOrgAboutNewChannel \\"my-channel1\\" \\"Org1MSP\\" \\"cli.org1.example.com\\" \\"peer0.org1.example.com\\" \\"orderer0.group1.orderer.example.com:7030\\"
notifyOrgAboutNewChannel \\"my-channel1\\" \\"Org2MSP\\" \\"cli.org2.example.com\\" \\"peer0.org2.example.com\\" \\"orderer0.group1.orderer.example.com:7030\\"
local version=\\"$2\\"
if [ -z \\"$version\\" ]; then
echo \\"Error: chaincode version is not provided\\"
exit 1
fi

printHeadline \\"Deleting new channel config blocks\\" \\"U1F52A\\"
deleteNewChannelUpdateTx \\"my-channel1\\" \\"Org1MSP\\" \\"cli.org1.example.com\\"
deleteNewChannelUpdateTx \\"my-channel1\\" \\"Org2MSP\\" \\"cli.org2.example.com\\"
if [ \\"$chaincodeName\\" = \\"chaincode1\\" ]; then
if [ -n \\"$(ls \\"$CHAINCODES_BASE_DIR/./chaincodes/chaincode-kv-node-1.4\\")\\" ]; then
chaincodeBuild \\"chaincode1\\" \\"node\\" \\"$CHAINCODES_BASE_DIR/./chaincodes/chaincode-kv-node-1.4\\" \\"12\\"
printHeadline \\"Installing 'chaincode1' on my-channel1/Org1/peer0\\" \\"U1F60E\\"
chaincodeInstall \\"cli.org1.example.com\\" \\"peer0.org1.example.com:7041\\" \\"my-channel1\\" \\"chaincode1\\" \\"0.0.1\\" \\"node\\" \\"orderer0.group1.orderer.example.com:7030\\" \\"\\"
printHeadline \\"Installing 'chaincode1' on my-channel1/Org1/peer1\\" \\"U1F60E\\"
chaincodeInstall \\"cli.org1.example.com\\" \\"peer1.org1.example.com:7042\\" \\"my-channel1\\" \\"chaincode1\\" \\"0.0.1\\" \\"node\\" \\"orderer0.group1.orderer.example.com:7030\\" \\"\\"
printHeadline \\"Installing 'chaincode1' on my-channel1/Org2/peer0\\" \\"U1F60E\\"
chaincodeInstall \\"cli.org2.example.com\\" \\"peer0.org2.example.com:7061\\" \\"my-channel1\\" \\"chaincode1\\" \\"0.0.1\\" \\"node\\" \\"orderer0.group1.orderer.example.com:7030\\" \\"\\"
printItalics \\"Instantiating chaincode 'chaincode1' on channel 'my-channel1' as 'Org1'\\" \\"U1F618\\"
chaincodeInstantiate \\"cli.org1.example.com\\" \\"peer0.org1.example.com:7041\\" \\"my-channel1\\" \\"chaincode1\\" \\"0.0.1\\" \\"node\\" \\"orderer0.group1.orderer.example.com:7030\\" '{\\"Args\\":[]}' \\"OR('Org1MSP.member', 'Org2MSP.member')\\" \\"\\" \\"collections/chaincode1.json\\"

else
echo \\"Warning! Skipping chaincode 'chaincode1' install. Chaincode directory is empty.\\"
echo \\"Looked in dir: '$CHAINCODES_BASE_DIR/./chaincodes/chaincode-kv-node-1.4'\\"
fi
fi
}

runDevModeChaincode() {
echo \\"Running chaincode in dev mode is supported by Fablo only for V2 channel capabilities\\"
exit 1
}

upgradeChaincode() {
Expand Down Expand Up @@ -2365,6 +2392,20 @@ upgradeChaincode() {
fi
}

notifyOrgsAboutChannels() {
printHeadline \\"Creating new channel config blocks\\" \\"U1F537\\"
createNewChannelUpdateTx \\"my-channel1\\" \\"Org1MSP\\" \\"MyChannel1\\" \\"$FABLO_NETWORK_ROOT/fabric-config\\" \\"$FABLO_NETWORK_ROOT/fabric-config/config\\"
createNewChannelUpdateTx \\"my-channel1\\" \\"Org2MSP\\" \\"MyChannel1\\" \\"$FABLO_NETWORK_ROOT/fabric-config\\" \\"$FABLO_NETWORK_ROOT/fabric-config/config\\"

printHeadline \\"Notyfing orgs about channels\\" \\"U1F4E2\\"
notifyOrgAboutNewChannel \\"my-channel1\\" \\"Org1MSP\\" \\"cli.org1.example.com\\" \\"peer0.org1.example.com\\" \\"orderer0.group1.orderer.example.com:7030\\"
notifyOrgAboutNewChannel \\"my-channel1\\" \\"Org2MSP\\" \\"cli.org2.example.com\\" \\"peer0.org2.example.com\\" \\"orderer0.group1.orderer.example.com:7030\\"

printHeadline \\"Deleting new channel config blocks\\" \\"U1F52A\\"
deleteNewChannelUpdateTx \\"my-channel1\\" \\"Org1MSP\\" \\"cli.org1.example.com\\"
deleteNewChannelUpdateTx \\"my-channel1\\" \\"Org2MSP\\" \\"cli.org2.example.com\\"
}

stopNetwork() {
printHeadline \\"Stopping network\\" \\"U1F68F\\"
(cd \\"$FABLO_NETWORK_ROOT\\"/fabric-docker && docker-compose stop)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1463,10 +1463,14 @@ elif [ \\"$1\\" = \\"start\\" ]; then
startNetwork
elif [ \\"$1\\" = \\"stop\\" ]; then
stopNetwork
elif [ \\"$1\\" = \\"chaincode\\" ] && [ \\"$2\\" = \\"install\\" ]; then
elif [ \\"$1\\" = \\"chaincodes\\" ] && [ \\"$2\\" = \\"install\\" ]; then
installChaincodes
elif [ \\"$1\\" = \\"chaincode\\" ] && [ \\"$2\\" = \\"install\\" ]; then
installChaincode \\"$3\\" \\"$4\\"
elif [ \\"$1\\" = \\"chaincode\\" ] && [ \\"$2\\" = \\"upgrade\\" ]; then
upgradeChaincode \\"$3\\" \\"$4\\"
elif [ \\"$1\\" = \\"chaincode\\" ] && [ \\"$2\\" = \\"dev\\" ]; then
runDevModeChaincode \\"$3\\" \\"$4\\"
elif [ \\"$1\\" = \\"channel\\" ]; then
channelQuery \\"\${@:2}\\"
elif [ \\"$1\\" = \\"snapshot\\" ]; then
Expand All @@ -1488,7 +1492,7 @@ fi
`;

exports[`samples/fablo-config-hlf1.4-1org-1chaincode-raft.json should create proper e2e/__tmp__/samples/fablo-config-hlf1.4-1org-1chaincode-raft.json.tmpdir/fablo-target/fabric-docker/.env from samples/fablo-config-hlf1.4-1org-1chaincode-raft.json 1`] = `
"FABLO_VERSION=1.0.3-unstable
"FABLO_VERSION=1.1.0-unstable
FABLO_BUILD=<date with git hash>
FABLO_REST_VERSION=0.1.0
HYPERLEDGER_EXPLORER_VERSION=1.1.8
Expand Down Expand Up @@ -1680,15 +1684,39 @@ installChaincodes() {

}

notifyOrgsAboutChannels() {
printHeadline \\"Creating new channel config blocks\\" \\"U1F537\\"
createNewChannelUpdateTx \\"my-channel1\\" \\"Org1MSP\\" \\"MyChannel1\\" \\"$FABLO_NETWORK_ROOT/fabric-config\\" \\"$FABLO_NETWORK_ROOT/fabric-config/config\\"
installChaincode() {
local chaincodeName=\\"$1\\"
if [ -z \\"$chaincodeName\\" ]; then
echo \\"Error: chaincode name is not provided\\"
exit 1
fi

printHeadline \\"Notyfing orgs about channels\\" \\"U1F4E2\\"
notifyOrgAboutNewChannelTls \\"my-channel1\\" \\"Org1MSP\\" \\"cli.org1.example.com\\" \\"peer0.org1.example.com\\" \\"orderer0.group1.orderer.example.com:7030\\" \\"crypto-orderer/tlsca.orderer.example.com-cert.pem\\"
local version=\\"$2\\"
if [ -z \\"$version\\" ]; then
echo \\"Error: chaincode version is not provided\\"
exit 1
fi

printHeadline \\"Deleting new channel config blocks\\" \\"U1F52A\\"
deleteNewChannelUpdateTx \\"my-channel1\\" \\"Org1MSP\\" \\"cli.org1.example.com\\"
if [ \\"$chaincodeName\\" = \\"chaincode1\\" ]; then
if [ -n \\"$(ls \\"$CHAINCODES_BASE_DIR/./chaincodes/chaincode-kv-node-1.4\\")\\" ]; then
chaincodeBuild \\"chaincode1\\" \\"node\\" \\"$CHAINCODES_BASE_DIR/./chaincodes/chaincode-kv-node-1.4\\" \\"12\\"
printHeadline \\"Installing 'chaincode1' on my-channel1/Org1/peer0\\" \\"U1F60E\\"
chaincodeInstall \\"cli.org1.example.com\\" \\"peer0.org1.example.com:7041\\" \\"my-channel1\\" \\"chaincode1\\" \\"0.0.1\\" \\"node\\" \\"orderer0.group1.orderer.example.com:7030\\" \\"crypto-orderer/tlsca.orderer.example.com-cert.pem\\"
printHeadline \\"Installing 'chaincode1' on my-channel1/Org1/peer1\\" \\"U1F60E\\"
chaincodeInstall \\"cli.org1.example.com\\" \\"peer1.org1.example.com:7042\\" \\"my-channel1\\" \\"chaincode1\\" \\"0.0.1\\" \\"node\\" \\"orderer0.group1.orderer.example.com:7030\\" \\"crypto-orderer/tlsca.orderer.example.com-cert.pem\\"
printItalics \\"Instantiating chaincode 'chaincode1' on channel 'my-channel1' as 'Org1'\\" \\"U1F618\\"
chaincodeInstantiate \\"cli.org1.example.com\\" \\"peer0.org1.example.com:7041\\" \\"my-channel1\\" \\"chaincode1\\" \\"0.0.1\\" \\"node\\" \\"orderer0.group1.orderer.example.com:7030\\" '{\\"Args\\":[]}' \\"AND ('Org1MSP.member')\\" \\"crypto-orderer/tlsca.orderer.example.com-cert.pem\\" \\"\\"

else
echo \\"Warning! Skipping chaincode 'chaincode1' install. Chaincode directory is empty.\\"
echo \\"Looked in dir: '$CHAINCODES_BASE_DIR/./chaincodes/chaincode-kv-node-1.4'\\"
fi
fi
}

runDevModeChaincode() {
echo \\"Running chaincode in dev mode is supported by Fablo only for V2 channel capabilities\\"
exit 1
}

upgradeChaincode() {
Expand Down Expand Up @@ -1723,6 +1751,17 @@ upgradeChaincode() {
fi
}

notifyOrgsAboutChannels() {
printHeadline \\"Creating new channel config blocks\\" \\"U1F537\\"
createNewChannelUpdateTx \\"my-channel1\\" \\"Org1MSP\\" \\"MyChannel1\\" \\"$FABLO_NETWORK_ROOT/fabric-config\\" \\"$FABLO_NETWORK_ROOT/fabric-config/config\\"

printHeadline \\"Notyfing orgs about channels\\" \\"U1F4E2\\"
notifyOrgAboutNewChannelTls \\"my-channel1\\" \\"Org1MSP\\" \\"cli.org1.example.com\\" \\"peer0.org1.example.com\\" \\"orderer0.group1.orderer.example.com:7030\\" \\"crypto-orderer/tlsca.orderer.example.com-cert.pem\\"

printHeadline \\"Deleting new channel config blocks\\" \\"U1F52A\\"
deleteNewChannelUpdateTx \\"my-channel1\\" \\"Org1MSP\\" \\"cli.org1.example.com\\"
}

stopNetwork() {
printHeadline \\"Stopping network\\" \\"U1F68F\\"
(cd \\"$FABLO_NETWORK_ROOT\\"/fabric-docker && docker-compose stop)
Expand Down
Loading