{"id":20018557,"url":"https://github.com/rupeshtr78/fabric-paper-sdk","last_synced_at":"2025-07-09T10:39:18.009Z","repository":{"id":44102692,"uuid":"199205171","full_name":"rupeshtr78/fabric-paper-sdk","owner":"rupeshtr78","description":"Hyperledger Smart Contract Node Js Docker","archived":false,"fork":false,"pushed_at":"2022-12-09T20:01:28.000Z","size":901,"stargazers_count":4,"open_issues_count":7,"forks_count":3,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-05-04T23:36:13.137Z","etag":null,"topics":["blockchain","blockchain-technology","docker","fabric","gateway","hyperledger","hyperledger-fabric","node-sdk","nodejs","smart-contracts","wallet"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rupeshtr78.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-07-27T19:22:21.000Z","updated_at":"2023-07-28T06:26:26.000Z","dependencies_parsed_at":"2023-01-25T16:16:37.397Z","dependency_job_id":null,"html_url":"https://github.com/rupeshtr78/fabric-paper-sdk","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/rupeshtr78/fabric-paper-sdk","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rupeshtr78%2Ffabric-paper-sdk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rupeshtr78%2Ffabric-paper-sdk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rupeshtr78%2Ffabric-paper-sdk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rupeshtr78%2Ffabric-paper-sdk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rupeshtr78","download_url":"https://codeload.github.com/rupeshtr78/fabric-paper-sdk/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rupeshtr78%2Ffabric-paper-sdk/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260945284,"owners_count":23086982,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blockchain","blockchain-technology","docker","fabric","gateway","hyperledger","hyperledger-fabric","node-sdk","nodejs","smart-contracts","wallet"],"created_at":"2024-11-13T08:23:12.231Z","updated_at":"2025-06-20T12:34:17.245Z","avatar_url":"https://github.com/rupeshtr78.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Hyperledger Fabric Smart Contract\n\nIn this article we will illustrate the steps required to deploy the commercial paper smart contract in a multi org network . In this case study we explore the concepts of adding org to a channel,wallets and identities, gateway and connection profiles in a Hyperledger Fabric network channel .\nThis article follows the commercial paper smart contract model of MagnetoCorp and DigiBank as shown below.\n\n![](images/FABRIC_PAPER_SDK.png)\n\nIn PaperNet commercial paper network. two organizations Magneto Corp and Digibank uses PaperNet\nnetwork to issue, buy, and redeem commercial paper. Refer the [link](https://hyperledger-fabric.readthedocs.io/en/release-1.4/developapps/scenario.html) for more details on the process.\n\nWe will be deploying the Hyperledger Fabric network consisting of MagnetoCorp organization, maintaining three peer nodes, one orderer with ‘solo’  ordering service. We will create a channel papernet , add Digibank organization's two peers to the papernet channel , by following [adding org to channel](https://hyperledger-fabric.readthedocs.io/en/release-1.4/channel_update_tutorial.html) procedure. \n\nAfter the network is setup we will install commercial paper smart contract package and instantiate the contract on papernet channel. We will configure connection profiles for the network gateway to manage the network interactions for both organizations. We will invoke issue,buy and redeem transactions of paper contract. We will also register users , use the corresponding  wallet and identities of respective organizations during these transactions.\n\nLets start by creating the network config for Magnetocorp.\n\n**Magnetocorp : Configure the Network**\n\n- Generate the Network Artifacts\n\n- Start CA Servers.\n\n- Start the Magnetocorp network\n\n- Create channel '***papernet***', join the peers and update anchor peer\n\n  ```bash\n  #Refer Github repo for details\n  \n  cd magntocorp\n  cryptogen generate --config=./crypto-config.yaml\n  \n  configtxgen -profile MagnetoCorpGenesis -channelID mc-sys-channel -outputBlock ./config/magneto.genesis.block\n  \n  export CHANNEL_NAME=papernet\n  \n  configtxgen -profile PapernetChannel -outputCreateChannelTx ./config/papernetchannel.tx -channelID $CHANNEL_NAME\n  \n  echo $CHANNEL_NAME\n  configtxgen -profile PapernetChannel -outputAnchorPeersUpdate ./config/MagnetoCorpanchors.tx -channelID $CHANNEL_NAME -asOrg MagnetoCorpMSP\n  \n  docker-compose -f docker-compose-ca.yaml up -d\n  docker-compose -f docker-compose-mcorp.yaml up -d\n  docker-compose -f docker-compose-cli.yaml up -d\n  ```\n\n\n\n**DigiBank: Configure the Network**\n\n- Generate the Network Artifacts\n\n```bash\n#Refer Github repo for details\n\ncd digibank\ncryptogen generate --config=./crypto-config.yaml\nconfigtxgen -profile DigiBankGenesis -channelID db-sys-channel -outputBlock ./config/digibank.genesis.block\n\nexport CHANNEL_NAME=digibankchannel\n\nconfigtxgen -profile PapernetChannel -outputCreateChannelTx ./config/digibankchannel.tx -channelID $CHANNEL_NAME\n```\n\n\n\n**Join DigiBank peers to the *papernet* Channel.**\n\nWe will add the two peers to the papernet channel and update anchor peers of DigiBank organization , by following [adding org to channel](https://hyperledger-fabric.readthedocs.io/en/release-1.4/channel_update_tutorial.html) procedure. \n\nAdd Digibank Peers to Channel\n\n```bash\n#Refer Github repo for details\ncd config/channel\nconfigtxgen -printOrg DigiBankMSP \u003e ../magnetocorp/config/channel/DigiBankMSP.json\n\n# exec into the CLI container\ndocker exec -it cli.peer0.mgc bash\ncd config/channel\n# command saves the binary protobuf channel configuration block to config_block.pb\npeer channel fetch config config_block.pb -o orderer.MagnetoCorp.com:7050 -c $CHANNEL_NAME --tls --cafile $ORDERER_CA\n\n# decode config_block.pb channel configuration block into JSON format\nconfigtxlator proto_decode --input config_block.pb --type common.Block | jq .data.data[0].payload.data.config \u003e config.json\n\n# append the DigiBankMSP configuration definition to MagnetoCorp\njq -s '.[0] * {\"channel_group\":{\"groups\":{\"Application\":{\"groups\": {\"DigiBankMSP\":.[1]}}}}}' config.json DigiBankMSP.json \u003e modified_config.json\n\n# translate config.json back into a protobuf called config.pb:\nconfigtxlator proto_encode --input config.json --type common.Config --output config.pb\n\n# encode modified_config.json to modified_config.pb:\nconfigtxlator proto_encode --input modified_config.json --type common.Config --output modified_config.pb\n\n# use configtxlator to calculate the delta between these two config protobufs. This command will output a new protobuf binary named DigiBankMSP_update.pb:\nconfigtxlator compute_update --channel_id $CHANNEL_NAME --original config.pb --updated modified_config.pb --output DigiBankMSP_update.pb\n\n# decode DigiBankMSP_update.pb into editable JSON format and call it DigiBankMSP_update.json:\nconfigtxlator proto_decode --input DigiBankMSP_update.pb --type common.ConfigUpdate | jq . \u003e DigiBankMSP_update.json\n\n# wrap in an envelope message\necho '{\"payload\":{\"header\":{\"channel_header\":{\"channel_id\":\"papernet\", \"type\":2}},\"data\":{\"config_update\":'$(cat DigiBankMSP_update.json)'}}}' | jq . \u003e DigiBankMSP_update_in_envelope.json\n\n# update object DigiBankMSP_update_in_envelope.pb: \nconfigtxlator proto_encode --input DigiBankMSP_update_in_envelope.json --type common.Envelope --output DigiBankMSP_update_in_envelope.pb\n\n# MegnetoCorpMSP Signature\npeer channel signconfigtx -f DigiBankMSP_update_in_envelope.pb\n\npeer channel update -f DigiBankMSP_update_in_envelope.pb -c $CHANNEL_NAME -o orderer.MagnetoCorp.com:7050 --tls --cafile $ORDERER_CA\n\n#verify New Block Creation\ndocker logs peer0.MagnetoCorp.com\n\n```\n\n**Start the DigiBank Network**\n\n```bash\ncd digibank\n\ndocker-compose -f docker-compose-digibank.yaml up -d\ndocker-compose -f docker-compose-cli.yaml up -d\n```\n\n**Update anchor peers of DigiBank organization** by following [update anchor peer](https://hyperledger-fabric.readthedocs.io/en/release-1.4/channel_update_tutorial.html) procedure. \n\n```bash\n#save the binary protobuf channel configuration block\npeer channel fetch config config_block.pb -o orderer.MagnetoCorp.com:7050 -c $CHANNEL_NAME --tls --cafile $ORDERER_CA\n\n# Conver to Human Readable Format\nconfigtxlator proto_decode --input config_block.pb --type common.Block | jq .data.data[0].payload.data.config \u003e config.json\n\n# Add Anchor Peer\njq '.channel_group.groups.Application.groups.DigiBankMSP.values += {\"AnchorPeers\":{\"mod_policy\": \"Admins\",\"value\":{\"anchor_peers\": [{\"host\": \"peer0.DigiBank.com\",\"port\": 17051}]},\"version\": \"0\"}}' config.json \u003e modified_anchor_config.json\n\n# jq '.channel_group.groups.Application.groups.MagnetoCorpMSP.values += {\"AnchorPeers\":{\"mod_policy\": \"Admins\",\"value\":{\"anchor_peers\": [{\"host\": \"peer0.MagnetoCorp.com\",\"port\": 7051}]},\"version\": \"0\"}}' config.json \u003e modified_anchor_config.json\n\n# Translate config.json back into protobuf format as config.pb\nconfigtxlator proto_encode --input config.json --type common.Config --output config.pb\n\n# Translate the modified_anchor_config.json into protobuf format as modified_anchor_config.pb\nconfigtxlator proto_encode --input modified_anchor_config.json --type common.Config --output modified_anchor_config.pb\n\n# Calculate the delta between the two protobuf formatted configurations.\nconfigtxlator compute_update --channel_id $CHANNEL_NAME --original config.pb --updated modified_anchor_config.pb --output anchor_update.pb\n\n# use the configtxlator command again to convert anchor_update.pb into anchor_update.json\nconfigtxlator proto_decode --input anchor_update.pb --type common.ConfigUpdate | jq . \u003e anchor_update.json\n\n# wrap the update in an envelope message, restoring the previously stripped away header, \n# outputting it to anchor_update_in_envelope.json\necho '{\"payload\":{\"header\":{\"channel_header\":{\"channel_id\":\"papernet\", \"type\":2}},\"data\":{\"config_update\":'$(cat anchor_update.json)'}}}' | jq . \u003e anchor_update_in_envelope.json\n\n# convert it to a protobuf so it can be properly signed and submitted to the orderer for the update.\nconfigtxlator proto_encode --input anchor_update_in_envelope.json --type common.Envelope --output anchor_update_in_envelope.pb\n\n# use the peer channel update command as it will also sign off on the update as the Org3 admin before submitting it to the orderer.\npeer channel update -f anchor_update_in_envelope.pb -c $CHANNEL_NAME -o orderer.MagnetoCorp.com:7050 --tls --cafile $ORDERER_CA\n\n#verify logs for anchor peer\ndocker logs -f peer0.org1.example.com\n```\n\n**Install Paper contract**\nInstall paper contract on all peer nodes in PaperNet channel . (use package method)\n\n```bash\npeer chaincode package contractpack.out -n papercontract -l node -p /opt/gopath/src/github.com/magnetocorp/contract -v 1.0 -s -S\n\npeer chaincode install contractpack.out\n```\n\n**Instantiate paper Contract on Papernet Channel**\n\n```bash\npeer chaincode instantiate -o orderer.MagnetoCorp.com:7050 -C $CHANNEL_NAME  -n papercontract -v 1.0 -l node -c '{\"Args\":[\"org.papernet.commercialpaper:instantiate\"]}' --tls --cafile $ORDERER_CA  -P  \"OR ('MagnetoCorpMSP.peer','DigiBankMSP.peer')\"\n\n```\n\n**Network Connection Profile**\n\nNow Lets us issue the commercial paper contract ad Magnetocorp.\n\nBefore that we need to configure the connection profile for both organizations.\n\n```bash\ncd commercial-paper/organization/magnetocorp/gateway/networkConnection.yaml\ncd commercial-paper/organization/digibank/gateway/networkConnection.yaml\nRefer Github repo for details\n```\n\n**Wallet**\n\nAfter creating the connection profiles We will then register users , import the registered identities to corresponding  wallets. MagnetoCorp uses **ca-MagnetoCorp.com** to issue identities and DigiBank uses ***ca-DigiBank.com*** to issue identities. These identities are stored in user wallets in each organization.\n\n- user bondissuer1@MagnetoCorp.com in MagnetoCorp.\n- user bondbuyer1@DigiBank.com in DigiBank organization\n\n```bash\ncd commercial-paper/organization/magnetocorp/application\nnpm install\n\nnode enrollAdmin.js\nnode register-issuer-1.js\n```\n\n**Invoke Issue Transaction**\n\nPerform issue transaction as bondissuer1@MagnetoCorp.com from MagnetoCorp.\n\nBelow code connected to papernet channel though a gateway using the connection profile and bondissuer1 user.\n\n```bash\ncd commercial-paper/organization/magnetocorp/application\nnode issue.js\n```\n\nResults would show in CLI like below.\n\n![](images/issuejs-magneto.png)\n\nNow lets us find the results of transaction from the couchdb interface for DigiBank Peer1.\n\nopen the link http://peer0.digibank.com:9984/_utils/#database/papernet_papercontract/_find\n\nIn the mango query window add the following query.\n\n```sql\n{\n   \"selector\": {\n      \"_id\": {\n         \"$gt\": null\n      }\n   },\n   \"fields\": [\n      \"class\",\n      \"currentState\",\n      \"issuer\",\n      \"owner\",\n      \"paperNumber\",\n      \"issueDateTime\",\n      \"maturityDateTime\",\n      \"faceValue\",\n      \"price\"\n   ]\n}\n```\n\nResults\n\n![](images/digibank-issue.png)\n\nThe current state =1 which is issue transaction.Owner and Issuer is both MagentoCorp.\n\n**Buy paper contract**\n\nBelow commands Registers bondbuyer1 user , imports the registered identity to digibank user wallet.\n\n```bash\ncd commercial-paper/organization/digibank/application/\nnpm install\n\nnode enrollAdmin.js\nnode register-buyer-1.js\n```\n\n**Invoke buy transaction** as Digibank user  bondbuyer1@Digibank.com .\n\n```bash\ncd commercial-paper/organization/digibank/application/\nnode buy.js\n```\n\nLets review the results again from couchdb interface. Rerun the query above from any peers link.\n\n![](images/digibank-buy.png)\n\nThe current state =2 which is buy transaction. Owner=Digibank  and Issuer is MagentoCorp\n\n**Invoke redeem transaction** as Digibank user  bondbuyer1@Digibank.com user\n\n```bash\ncd commercial-paper/organization/digibank/application/\n\nnode redeem.js\n```\n\nLets review the results again from couchdb interface. Rerun the query above from any of the peers link.\n\n![](images/digibank-redeem.png)\n\nThe current state =3 which is redeem transaction. Owner=MagentoCorp and Issuer is MagentoCorp\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frupeshtr78%2Ffabric-paper-sdk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frupeshtr78%2Ffabric-paper-sdk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frupeshtr78%2Ffabric-paper-sdk/lists"}