diff --git a/off_chain_data/README.md b/off_chain_data/README.md index 45eacd1a..156649bf 100644 --- a/off_chain_data/README.md +++ b/off_chain_data/README.md @@ -10,9 +10,9 @@ CouchDB. ## Getting started -This sample uses Node Fabric SDK application code similar to the `fabcar` sample -to connect to a running instance of the Fabric test network. Make sure that you -are running the following commands from the `off_chain_data` directory. +This sample uses Node Fabric SDK application code to connect to a running instance +of the Fabric test network. Make sure that you are running the following +commands from the `off_chain_data` directory. ### Starting the Network @@ -25,7 +25,8 @@ Use the following command to start the sample network: This command will deploy an instance of the Fabric test network. The network consists of an ordering service, two peer organizations with one peers each, and a CA for each org. The command also creates a channel named `mychannel`. The -marbles chaincode will be installed on both peers and deployed to the channel. +`asset-transfer-basic` chaincode will be installed on both peers and deployed to +the channel. ### Configuration @@ -55,10 +56,11 @@ If you set the "use_couchdb" option to true in `config.json`, you can run the following command start a local instance of CouchDB using docker: ``` -docker run --publish 5990:5984 --detach --name offchaindb couchdb +docker run --publish 5990:5984 --detach --name offchaindb couchdb:2.3.1 docker start offchaindb ``` + ### Install dependencies You need to install Node.js version 8.9.x to use the sample application code. @@ -92,53 +94,7 @@ node blockEventListener.js If the command is successful, you should see the output of the listener reading the configuration blocks of `mychannel` in addition to the blocks that recorded -the approval and commitment of the marbles chaincode definition. - -``` -Listening for block events, nextblock: 0 -Added block 0 to ProcessingMap -Added block 1 to ProcessingMap -Added block 2 to ProcessingMap -Added block 3 to ProcessingMap -Added block 4 to ProcessingMap -Added block 5 to ProcessingMap -Added block 6 to ProcessingMap ------------------------------------------------- -Block Number: 0 ------------------------------------------------- -Block Number: 1 ------------------------------------------------- -Block Number: 2 ------------------------------------------------- -Block Number: 3 -Block Timestamp: 2019-08-08T19:47:56.148Z -ChaincodeID: _lifecycle -[] ------------------------------------------------- -Block Number: 4 -Block Timestamp: 2019-08-08T19:48:00.234Z -ChaincodeID: _lifecycle -[] ------------------------------------------------- -Block Number: 5 -Block Timestamp: 2019-08-08T19:48:14.092Z -ChaincodeID: _lifecycle -[ { key: 'namespaces/fields/marbles/Collections', - is_delete: false, - value: '\u0012\u0000' }, - { key: 'namespaces/fields/marbles/EndorsementInfo', - is_delete: false, - value: '\u0012\r\n\u00031.0\u0010\u0001\u001a\u0004escc' }, - { key: 'namespaces/fields/marbles/Sequence', - is_delete: false, - value: '\b\u0001' }, - { key: 'namespaces/fields/marbles/ValidationInfo', - is_delete: false, - value: '\u00122\n\u0004vscc\u0012*\n(\u0012\f\u0012\n\b\u0002\u0012\u0002\b\u0000\u0012\u0002\b\u0001\u001a\u000b\u0012\t\n\u0007Org1MSP\u001a\u000b\u0012\t\n\u0007Org2MSP' }, - { key: 'namespaces/metadata/marbles', - is_delete: false, - value: '\n\u0013ChaincodeDefinition\u0012\bSequence\u0012\u000fEndorsementInfo\u0012\u000eValidationInfo\u0012\u000bCollections' } ] -``` +the approval and commitment of the assets chaincode definition. `blockEventListener.js` creates a listener named "offchain-listener" on the channel `mychannel`. The listener writes each block added to the channel to a @@ -157,7 +113,7 @@ read-write set. The channel event listener also writes metadata from each block to a log file defined as channelid_chaincodeid.log. In this example, events will be written to -a file named `mychannel_marbles.log`. This allows you to record a history of +a file named `mychannel_basic.log`. This allows you to record a history of changes made by each block for each key in addition to storing the latest value of the world state. @@ -166,42 +122,42 @@ new window to execute the next parts of the demo. ### Generate data on the blockchain -Now that our listener is setup, we can generate data using the marbles chaincode +Now that our listener is setup, we can generate data using the assets chaincode and use our application to replicate the data to our database. Open a new terminal and navigate to the `fabric-samples/off_chain_data` directory. -You can use the `addMarbles.js` file to add random sample data to blockchain. -The file uses the configuration information stored in `addMarbles.json` to -create a series of marbles. This file will be created during the first execution -of `addMarbles.js` if it does not exist. This program can be run multiple times -without changing the properties. The `nextMarbleNumber` will be incremented and -stored in the `addMarbles.json` file. +You can use the `addAssets.js` file to add random sample data to blockchain. +The file uses the configuration information stored in `addAssets.json` to +create a series of assets. This file will be created during the first execution +of `addAssets.js` if it does not exist. This program can be run multiple times +without changing the properties. The `nextAssetNumber` will be incremented and +stored in the `addAssets.json` file. ``` { - "nextMarbleNumber": 100, - "numberMarblesToAdd": 20 + "nextAssetNumber": 100, + "numberAssetsToAdd": 20 } ``` -Open a new window and run the following command to add 20 marbles to the +Open a new window and run the following command to add 20 assets to the blockchain: ``` -node addMarbles.js +node addAssets.js ``` -After the marbles have been added to the ledger, use the following command to -transfer one of the marbles to a new owner: +After the assets have been added to the ledger, use the following command to +transfer one of the assets to a new owner: ``` -node transferMarble.js marble110 james +node transferAsset.js asset110 james ``` -Now run the following command to delete the marble that was transferred: +Now run the following command to delete the asset that was transferred: ``` -node deleteMarble.js marble110 +node deleteAsset.js asset110 ``` ## Offchain CouchDB storage: @@ -215,17 +171,17 @@ The first table is an offline representation of the current world state of the blockchain ledger. This table was created using the read-write set data from the blocks. If the listener is running, this table should be the same as the latest values in the state database running on your peer. The table is named -after the channelid and chaincodeid, and is named mychannel_marbles in this +after the channelid and chaincodeid, and is named mychannel_basic in this example. You can navigate to this table using your browser: -http://127.0.0.1:5990/mychannel_marbles/_all_docs +http://127.0.0.1:5990/mychannel_basic/_all_docs A second table records each block as a historical record entry, and was created using the block data that was recorded in the log file. The table name appends -history to the name of the first table, and is named mychannel_marbles_history +history to the name of the first table, and is named mychannel_basic_history in this example. You can also navigate to this table using your browser: -http://127.0.0.1:5990/mychannel_marbles_history/_all_docs +http://127.0.0.1:5990/mychannel_basic_history/_all_docs -### Configure a map/reduce view for summarizing counts of marbles by color: +### Configure a map/reduce view for summarizing counts of assets by color: Now that we have state and history data replicated to tables in CouchDB, we can use the following commands query our off-chain data. We will also add an @@ -236,16 +192,16 @@ created when events are received. Open a new terminal window and execute the following: ``` -curl -X PUT http://127.0.0.1:5990/mychannel_marbles/_design/colorviewdesign -d '{"views":{"colorview":{"map":"function (doc) { emit(doc.color, 1);}","reduce":"function ( keys , values , combine ) {return sum( values )}"}}}' -H 'Content-Type:application/json' +curl -X PUT http://127.0.0.1:5990/mychannel_basic/_design/colorviewdesign -d '{"views":{"colorview":{"map":"function (doc) { emit(doc.color, 1);}","reduce":"function ( keys , values , combine ) {return sum( values )}"}}}' -H 'Content-Type:application/json' ``` -Execute a query to retrieve the total number of marbles (reduce function): +Execute a query to retrieve the total number of assets (reduce function): ``` -curl -X GET http://127.0.0.1:5990/mychannel_marbles/_design/colorviewdesign/_view/colorview?reduce=true +curl -X GET http://127.0.0.1:5990/mychannel_basic/_design/colorviewdesign/_view/colorview?reduce=true ``` -If successful, this command will return the number of marbles in the blockchain +If successful, this command will return the number of assets in the blockchain world state, without having to query the blockchain ledger: ``` @@ -254,13 +210,13 @@ world state, without having to query the blockchain ledger: ]} ``` -Execute a new query to retrieve the number of marbles by color (map function): +Execute a new query to retrieve the number of assets by color (map function): ``` -curl -X GET http://127.0.0.1:5990/mychannel_marbles/_design/colorviewdesign/_view/colorview?group=true +curl -X GET http://127.0.0.1:5990/mychannel_basic/_design/colorviewdesign/_view/colorview?group=true ``` -The command will return a list of marbles by color from the CouchDB database. +The command will return a list of assets by color from the CouchDB database. ``` {"rows":[ @@ -275,27 +231,27 @@ The command will return a list of marbles by color from the CouchDB database. To run a more complex command that reads through the block history database, we will create an index of the blocknumber, sequence, and key fields. This index -will support a query that traces the history of each marble. Execute the +will support a query that traces the history of each asset. Execute the following command to create the index: ``` -curl -X POST http://127.0.0.1:5990/mychannel_marbles_history/_index -d '{"index":{"fields":["blocknumber", "sequence", "key"]},"name":"marble_history"}' -H 'Content-Type:application/json' +curl -X POST http://127.0.0.1:5990/mychannel_basic_history/_index -d '{"index":{"fields":["blocknumber", "sequence", "key"]},"name":"asset_history"}' -H 'Content-Type:application/json' ``` -Now execute a query to retrieve the history for the marble we transferred and +Now execute a query to retrieve the history for the asset we transferred and then deleted: ``` -curl -X POST http://127.0.0.1:5990/mychannel_marbles_history/_find -d '{"selector":{"key":{"$eq":"marble110"}}, "fields":["blocknumber","is_delete","value"],"sort":[{"blocknumber":"asc"}, {"sequence":"asc"}]}' -H 'Content-Type:application/json' +curl -X POST http://127.0.0.1:5990/mychannel_basic_history/_find -d '{"selector":{"key":{"$eq":"asset110"}}, "fields":["blocknumber","is_delete","value"],"sort":[{"blocknumber":"asc"}, {"sequence":"asc"}]}' -H 'Content-Type:application/json' ``` -You should see the transaction history of the marble that was created, +You should see the transaction history of the asset that was created, transferred, and then removed from the ledger. ``` {"docs":[ -{"blocknumber":12,"is_delete":false,"value":"{\"docType\":\"marble\",\"name\":\"marble110\",\"color\":\"blue\",\"size\":60,\"owner\":\"debra\"}"}, -{"blocknumber":22,"is_delete":false,"value":"{\"docType\":\"marble\",\"name\":\"marble110\",\"color\":\"blue\",\"size\":60,\"owner\":\"james\"}"}, +{"blocknumber":12,"is_delete":false,"value":"{\"docType\":\"asset\",\"name\":\"asset110\",\"color\":\"blue\",\"size\":60,\"owner\":\"debra\"}"}, +{"blocknumber":22,"is_delete":false,"value":"{\"docType\":\"asset\",\"name\":\"asset110\",\"color\":\"blue\",\"size\":60,\"owner\":\"james\"}"}, {"blocknumber":23,"is_delete":true,"value":""} ]} ``` @@ -309,19 +265,19 @@ have missed. If you ran through the example steps above, navigate back to the terminal window where `blockEventListener.js` is running and close it. Once the listener is no -longer running, use the following command to add 20 more marbles to the +longer running, use the following command to add 20 more assets to the ledger: ``` -node addMarbles.js +node addAssets.js ``` -The listener will not be able to add the new marbles to your CouchDB database. +The listener will not be able to add the new assets to your CouchDB database. If you check the current state table using the reduce command, you will only -be able to see the original marbles in your database. +be able to see the original assets in your database. ``` -curl -X GET http://127.0.0.1:5990/mychannel_marbles/_design/colorviewdesign/_view/colorview?reduce=true +curl -X GET http://127.0.0.1:5990/mychannel_basic/_design/colorviewdesign/_view/colorview?reduce=true ``` To add the new data to your off-chain database, remove the `nextblock.txt` @@ -337,15 +293,15 @@ You can new re-run the channel listener to read every block from the channel: node blockEventListener.js ``` -This will rebuild the CouchDB tables and include the 20 marbles that have been +This will rebuild the CouchDB tables and include the 20 assets that have been added to the ledger. If you run the reduce command against your database one more time, ``` -curl -X GET http://127.0.0.1:5990/mychannel_marbles/_design/colorviewdesign/_view/colorview?reduce=true +curl -X GET http://127.0.0.1:5990/mychannel_basic/_design/colorviewdesign/_view/colorview?reduce=true ``` -you will be able to see that all of the marbles have been added to your +you will be able to see that all of the assets have been added to your database: ``` @@ -369,4 +325,4 @@ Running the script will complete the following actions: * Remove the certificates you generated by deleting the `wallet` folder. * Delete `nextblock.txt` so you can start with the first block next time you operate the listener. -* Removes `addMarbles.json`. +* Removes `addAssets.json`. diff --git a/off_chain_data/addAssets.js b/off_chain_data/addAssets.js new file mode 100644 index 00000000..1137d5f7 --- /dev/null +++ b/off_chain_data/addAssets.js @@ -0,0 +1,118 @@ +/* + * Copyright IBM Corp. All Rights Reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +/* + * + * addAssets.js will add random sample data to blockchain. + * + * $ node addAssets.js + * + * addAssets will add 10 Assets by default with a starting Asset name of "Asset100". + * Additional Assets will be added by incrementing the number at the end of the Asset name. + * + * The properties for adding Assets are stored in addAssets.json. This file will be created + * during the first execution of the utility if it does not exist. The utility can be run + * multiple times without changing the properties. The nextAssetNumber will be incremented and + * stored in the JSON file. + * + * { + * "nextAssetNumber": 100, + * "numberAssetsToAdd": 10 + * } + * + */ + +'use strict'; + +const { Wallets, Gateway } = require('fabric-network'); +const fs = require('fs'); +const path = require('path'); + +const addAssetsConfigFile = path.resolve(__dirname, 'addAssets.json'); + +const colors=[ 'blue', 'red', 'yellow', 'green', 'white', 'purple' ]; +const owners=[ 'tom', 'fred', 'julie', 'james', 'janet', 'henry', 'alice', 'marie', 'sam', 'debra', 'nancy']; +const sizes=[ 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 ]; +const appraisedValues=[ 300, 310, 320, 330, 340, 350, 360, 370, 380, 390 ]; +const docType='asset' + +const config = require('./config.json'); +const channelid = config.channelid; + +async function main() { + + try { + + let nextAssetNumber; + let numberAssetsToAdd; + let addAssetsConfig; + + // check to see if there is a config json defined + if (fs.existsSync(addAssetsConfigFile)) { + // read file the next asset and number of assets to create + let addAssetsConfigJSON = fs.readFileSync(addAssetsConfigFile, 'utf8'); + addAssetsConfig = JSON.parse(addAssetsConfigJSON); + nextAssetNumber = addAssetsConfig.nextAssetNumber; + numberAssetsToAdd = addAssetsConfig.numberAssetsToAdd; + } else { + nextAssetNumber = 100; + numberAssetsToAdd = 20; + // create a default config and save + addAssetsConfig = new Object; + addAssetsConfig.nextAssetNumber = nextAssetNumber; + addAssetsConfig.numberAssetsToAdd = numberAssetsToAdd; + fs.writeFileSync(addAssetsConfigFile, JSON.stringify(addAssetsConfig, null, 2)); + } + + // Parse the connection profile. + const ccpPath = path.resolve(__dirname, '..', 'test-network','organizations','peerOrganizations','org1.example.com', 'connection-org1.json'); + const ccp = JSON.parse(fs.readFileSync(ccpPath, 'utf8')); + + // Configure a wallet. This wallet must already be primed with an identity that + // the application can use to interact with the peer node. + const walletPath = path.resolve(__dirname, 'wallet'); + const wallet = await Wallets.newFileSystemWallet(walletPath); + + // Create a new gateway, and connect to the gateway peer node(s). The identity + // specified must already exist in the specified wallet. + const gateway = new Gateway(); + await gateway.connect(ccp, { wallet, identity: 'appUser', discovery: { enabled: true, asLocalhost: true } }); + + // Get the network channel that the smart contract is deployed to. + const network = await gateway.getNetwork(channelid); + + // Get the smart contract from the network channel. + const contract = network.getContract('basic'); + + for (var counter = nextAssetNumber; counter < nextAssetNumber + numberAssetsToAdd; counter++) { + + var randomColor = Math.floor(Math.random() * (6)); + var randomOwner = Math.floor(Math.random() * (11)); + var randomSize = Math.floor(Math.random() * (10)); + var randomValue = Math.floor(Math.random() * (9)); + + // Submit the 'CreateAsset' transaction to the smart contract, and wait for it + // to be committed to the ledger. + await contract.submitTransaction('CreateAsset', docType+counter, colors[randomColor], ''+sizes[randomSize], owners[randomOwner],appraisedValues[randomValue]); + console.log("Adding asset: " + docType + counter + " owner:" + owners[randomOwner] + " color:" + colors[randomColor] + " size:" + '' + sizes[randomSize] + " appraised value:" + '' + appraisedValues[randomValue] ); + + } + + await gateway.disconnect(); + + addAssetsConfig.nextAssetNumber = nextAssetNumber + numberAssetsToAdd; + + fs.writeFileSync(addAssetsConfigFile, JSON.stringify(addAssetsConfig, null, 2)); + + } catch (error) { + console.error(`Failed to submit transaction: ${error}`); + process.exit(1); + } + +} + +main(); diff --git a/off_chain_data/addMarbles.js b/off_chain_data/addMarbles.js deleted file mode 100644 index 8fdbdffc..00000000 --- a/off_chain_data/addMarbles.js +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - */ - -/* - * - * addMarbles.js will add random sample data to blockchain. - * - * $ node addMarbles.js - * - * addMarbles will add 10 marbles by default with a starting marble name of "marble100". - * Additional marbles will be added by incrementing the number at the end of the marble name. - * - * The properties for adding marbles are stored in addMarbles.json. This file will be created - * during the first execution of the utility if it does not exist. The utility can be run - * multiple times without changing the properties. The nextMarbleNumber will be incremented and - * stored in the JSON file. - * - * { - * "nextMarbleNumber": 100, - * "numberMarblesToAdd": 10 - * } - * - */ - -'use strict'; - -const { Wallets, Gateway } = require('fabric-network'); -const fs = require('fs'); -const path = require('path'); - -const addMarblesConfigFile = path.resolve(__dirname, 'addMarbles.json'); - -const colors=[ 'blue', 'red', 'yellow', 'green', 'white', 'purple' ]; -const owners=[ 'tom', 'fred', 'julie', 'james', 'janet', 'henry', 'alice', 'marie', 'sam', 'debra', 'nancy']; -const sizes=[ 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 ]; -const docType='marble' - -const config = require('./config.json'); -const channelid = config.channelid; - -async function main() { - - try { - - let nextMarbleNumber; - let numberMarblesToAdd; - let addMarblesConfig; - - // check to see if there is a config json defined - if (fs.existsSync(addMarblesConfigFile)) { - // read file the next marble and number of marbles to create - let addMarblesConfigJSON = fs.readFileSync(addMarblesConfigFile, 'utf8'); - addMarblesConfig = JSON.parse(addMarblesConfigJSON); - nextMarbleNumber = addMarblesConfig.nextMarbleNumber; - numberMarblesToAdd = addMarblesConfig.numberMarblesToAdd; - } else { - nextMarbleNumber = 100; - numberMarblesToAdd = 20; - // create a default config and save - addMarblesConfig = new Object; - addMarblesConfig.nextMarbleNumber = nextMarbleNumber; - addMarblesConfig.numberMarblesToAdd = numberMarblesToAdd; - fs.writeFileSync(addMarblesConfigFile, JSON.stringify(addMarblesConfig, null, 2)); - } - - // Parse the connection profile. This would be the path to the file downloaded - // from the IBM Blockchain Platform operational console. - const ccpPath = path.resolve(__dirname, '..', 'test-network','organizations','peerOrganizations','org1.example.com', 'connection-org1.json'); - const ccp = JSON.parse(fs.readFileSync(ccpPath, 'utf8')); - - // Configure a wallet. This wallet must already be primed with an identity that - // the application can use to interact with the peer node. - const walletPath = path.resolve(__dirname, 'wallet'); - const wallet = await Wallets.newFileSystemWallet(walletPath); - - // Create a new gateway, and connect to the gateway peer node(s). The identity - // specified must already exist in the specified wallet. - const gateway = new Gateway(); - await gateway.connect(ccp, { wallet, identity: 'appUser', discovery: { enabled: true, asLocalhost: true } }); - - // Get the network channel that the smart contract is deployed to. - const network = await gateway.getNetwork(channelid); - - // Get the smart contract from the network channel. - const contract = network.getContract('marbles'); - - for (var counter = nextMarbleNumber; counter < nextMarbleNumber + numberMarblesToAdd; counter++) { - - var randomColor = Math.floor(Math.random() * (6)); - var randomOwner = Math.floor(Math.random() * (11)); - var randomSize = Math.floor(Math.random() * (10)); - - // Submit the 'initMarble' transaction to the smart contract, and wait for it - // to be committed to the ledger. - await contract.submitTransaction('initMarble', docType+counter, colors[randomColor], ''+sizes[randomSize], owners[randomOwner]); - console.log("Adding marble: " + docType + counter + " owner:" + owners[randomOwner] + " color:" + colors[randomColor] + " size:" + '' + sizes[randomSize] ); - - } - - await gateway.disconnect(); - - addMarblesConfig.nextMarbleNumber = nextMarbleNumber + numberMarblesToAdd; - - fs.writeFileSync(addMarblesConfigFile, JSON.stringify(addMarblesConfig, null, 2)); - - } catch (error) { - console.error(`Failed to submit transaction: ${error}`); - process.exit(1); - } - -} - -main(); diff --git a/off_chain_data/deleteMarble.js b/off_chain_data/deleteAsset.js similarity index 78% rename from off_chain_data/deleteMarble.js rename to off_chain_data/deleteAsset.js index b12706c0..aeede815 100644 --- a/off_chain_data/deleteMarble.js +++ b/off_chain_data/deleteAsset.js @@ -7,9 +7,9 @@ /* * - * deleteMarble.js will delete a specified marble. Example: + * deleteAsset.js will delete a specified asset. Example: * - * $ node deleteMarble.js marble100 + * $ node deleteAsset.js asset100 * * The utility is meant to demonstrate delete block events. */ @@ -26,7 +26,7 @@ const channelid = config.channelid; async function main() { if (process.argv[2] == undefined) { - console.log("Usage: node deleteMarble marbleId"); + console.log("Usage: node deleteAsset AssetId"); process.exit(1); } @@ -34,8 +34,7 @@ async function main() { try { - // Parse the connection profile. This would be the path to the file downloaded - // from the IBM Blockchain Platform operational console. + // Parse the connection profile. const ccpPath = path.resolve(__dirname, '..', 'test-network','organizations','peerOrganizations','org1.example.com', 'connection-org1.json'); const ccp = JSON.parse(fs.readFileSync(ccpPath, 'utf8')); @@ -53,10 +52,10 @@ async function main() { const network = await gateway.getNetwork(channelid); // Get the smart contract from the network channel. - const contract = network.getContract('marbles'); + const contract = network.getContract('basic'); - await contract.submitTransaction('delete', deletekey); - console.log("Deleted marble: " + deletekey); + await contract.submitTransaction('DeleteAsset', deletekey); + console.log("Deleted asset: " + deletekey); await gateway.disconnect(); diff --git a/off_chain_data/network-clean.sh b/off_chain_data/network-clean.sh index 14dc7098..1d24a2a7 100755 --- a/off_chain_data/network-clean.sh +++ b/off_chain_data/network-clean.sh @@ -14,7 +14,7 @@ popd # clean out any old identites in the wallets rm -rf wallet -rm -rf addMarbles.json mychannel_marbles.log mychannel__lifecycle.log nextblock.txt +rm -rf addAssets.json mychannel_basic.log mychannel__lifecycle.log nextblock.txt docker stop offchaindb docker rm offchaindb diff --git a/off_chain_data/package.json b/off_chain_data/package.json index 9bb41be9..a693870e 100644 --- a/off_chain_data/package.json +++ b/off_chain_data/package.json @@ -15,8 +15,8 @@ "author": "Hyperledger", "license": "Apache-2.0", "dependencies": { - "fabric-ca-client": "^2.1.0", - "fabric-network": "^2.1.0" + "fabric-ca-client": "^2.2.0", + "fabric-network": "^2.2.0" }, "devDependencies": { "chai": "^4.2.0", diff --git a/off_chain_data/startFabric.sh b/off_chain_data/startFabric.sh index 1f54e6ea..fa2dedcf 100755 --- a/off_chain_data/startFabric.sh +++ b/off_chain_data/startFabric.sh @@ -7,161 +7,13 @@ # Exit on first error set -e pipefail -# don't rewrite paths for Windows Git Bash users -export MSYS_NO_PATHCONV=1 starttime=$(date +%s) -CC_SRC_LANGUAGE=golang -CC_RUNTIME_LANGUAGE=golang -CC_SRC_PATH=../chaincode/marbles02/go - -echo Vendoring Go dependencies ... -pushd ../chaincode/marbles02/go -GO111MODULE=on go mod vendor -popd -echo Finished vendoring Go dependencies # launch network; create channel and join peer to channel pushd ../test-network ./network.sh down ./network.sh up createChannel -ca -s couchdb - -export PATH=${PWD}/../bin:${PWD}:$PATH -export FABRIC_CFG_PATH=${PWD}/../config - -# import environment variables -. scripts/envVar.sh - -echo "Packaging the marbles smart contract" - -setGlobals 1 - -peer lifecycle chaincode package marbles.tar.gz \ - --path $CC_SRC_PATH \ - --lang $CC_RUNTIME_LANGUAGE \ - --label marblesv1 - -echo "Installing smart contract on peer0.org1.example.com" - -peer lifecycle chaincode install marbles.tar.gz - - -echo "Installing smart contract on peer0.org2.example.com" - -setGlobals 2 - -peer lifecycle chaincode install marbles.tar.gz - - -echo "Query the chaincode package id" - -setGlobals 1 - -peer lifecycle chaincode queryinstalled >&log.txt - -PACKAGE_ID=$(sed -n "/marblesv1/{s/^Package ID: //; s/, Label:.*$//; p;}" log.txt) - -echo "Approving the chaincode definition for org1.example.com" - -peer lifecycle chaincode approveformyorg \ - -o localhost:7050 \ - --ordererTLSHostnameOverride orderer.example.com \ - --channelID mychannel \ - --name marbles \ - --version 1.0 \ - --init-required \ - --signature-policy AND"('Org1MSP.member','Org2MSP.member')" \ - --sequence 1 \ - --package-id $PACKAGE_ID \ - --tls \ - --cafile ${ORDERER_CA} - -echo "Approving the chaincode definition for org2.example.com" - -setGlobals 2 - -peer lifecycle chaincode approveformyorg \ - -o localhost:7050 \ - --ordererTLSHostnameOverride orderer.example.com \ - --channelID mychannel \ - --name marbles \ - --version 1.0 \ - --init-required \ - --signature-policy AND"('Org1MSP.member','Org2MSP.member')" \ - --sequence 1 \ - --package-id $PACKAGE_ID \ - --tls \ - --cafile ${ORDERER_CA} - -echo "Checking if the chaincode definition is ready to commit" - -peer lifecycle chaincode checkcommitreadiness \ - --channelID mychannel \ - --name marbles \ - --version 1.0 \ - --sequence 1 \ - --output json \ - --init-required \ - --signature-policy AND"('Org1MSP.member','Org2MSP.member')" >&log.txt - -rc=0 -for var in "\"Org1MSP\": true" "\"Org2MSP\": true" -do - grep "$var" log.txt &>/dev/null || let rc=1 -done - -if test $rc -eq 0; then - echo "Chaincode definition is ready to commit" -else - sleep 10 -fi - -parsePeerConnectionParameters 1 2 - -echo "Commit the chaincode definition to the channel" - -peer lifecycle chaincode commit \ - -o localhost:7050 \ - --ordererTLSHostnameOverride orderer.example.com \ - --channelID mychannel \ - --name marbles \ - --version 1.0 \ - --init-required \ - --signature-policy AND"('Org1MSP.member','Org2MSP.member')" \ - --sequence 1 \ - --tls \ - --cafile ${ORDERER_CA} \ - $PEER_CONN_PARMS - -echo "Check if the chaincode has been committed to the channel ..." - -peer lifecycle chaincode querycommitted \ - --channelID mychannel \ - --name marbles >&log.txt - -EXPECTED_RESULT="Version: 1.0, Sequence: 1, Endorsement Plugin: escc, Validation Plugin: vscc" -VALUE=$(grep -o "Version: 1.0, Sequence: 1, Endorsement Plugin: escc, Validation Plugin: vscc" log.txt) -echo "$VALUE" - -if [ "$VALUE" = "Version: 1.0, Sequence: 1, Endorsement Plugin: escc, Validation Plugin: vscc" ] ; then - echo "chaincode has been committed" -else - sleep 10 -fi - -echo "invoke the marbles chaincode init function ... " - -peer chaincode invoke \ - -o localhost:7050 \ - --ordererTLSHostnameOverride orderer.example.com \ - -C mychannel \ - -n marbles \ - --isInit \ - -c '{"Args":["Init"]}' \ - --tls \ - --cafile ${ORDERER_CA} \ - $PEER_CONN_PARMS - -rm log.txt +./network.sh deployCC popd diff --git a/off_chain_data/transferMarble.js b/off_chain_data/transferAsset.js similarity index 75% rename from off_chain_data/transferMarble.js rename to off_chain_data/transferAsset.js index 93af01dc..42c07b6e 100644 --- a/off_chain_data/transferMarble.js +++ b/off_chain_data/transferAsset.js @@ -6,9 +6,9 @@ */ /* - * tranferMarble.js will transfer ownership a specified marble to a new ownder. Example: + * tranferAsset.js will transfer ownership a specified asset to a new ownder. Example: * - * $ node transferMarble.js marble102 jimmy + * $ node transferAsset.js asset102 jimmy * * The utility is meant to demonstrate update block events. */ @@ -25,7 +25,7 @@ const channelid = config.channelid; async function main() { if (process.argv[2] == undefined && process.argv[3] == undefined) { - console.log("Usage: node changeMarbleOwner.js marbleId owner"); + console.log("Usage: node transferAsset.js assetId owner"); process.exit(1); } @@ -34,8 +34,7 @@ async function main() { try { - // Parse the connection profile. This would be the path to the file downloaded - // from the IBM Blockchain Platform operational console. + // Parse the connection profile. const ccpPath = path.resolve(__dirname, '..', 'test-network','organizations','peerOrganizations','org1.example.com', 'connection-org1.json'); const ccp = JSON.parse(fs.readFileSync(ccpPath, 'utf8')); @@ -53,10 +52,10 @@ async function main() { const network = await gateway.getNetwork(channelid); // Get the smart contract from the network channel. - const contract = network.getContract('marbles'); + const contract = network.getContract('basic'); - await contract.submitTransaction('transferMarble', updatekey, newowner); - console.log("Transferred marble " + updatekey + " to " + newowner); + await contract.submitTransaction('TransferAsset', updatekey, newowner); + console.log("Transferred asset " + updatekey + " to " + newowner); await gateway.disconnect();