mirror of
https://github.com/hyperledger/fabric-samples.git
synced 2026-06-17 15:35:09 +00:00
[FAB-17461] Move off_chain_data sample to test network (#122)
Signed-off-by: NIKHIL E GUPTA <negupta@us.ibm.com> Co-authored-by: NIKHIL E GUPTA <negupta@us.ibm.com>
This commit is contained in:
parent
121a44a1d1
commit
faac18e6da
9 changed files with 167 additions and 165 deletions
|
|
@ -1,28 +1,32 @@
|
||||||
# Off Chain data
|
# Off Chain data
|
||||||
|
|
||||||
This sample demonstrates how you can use [Peer channel-based event services](https://hyperledger-fabric.readthedocs.io/en/release-1.4/peer_event_services.html)
|
This sample demonstrates how you can use [Peer channel-based event services](https://hyperledger-fabric.readthedocs.io/en/release-2.0/peer_event_services.html)
|
||||||
to replicate the data on your blockchain network to an off chain database.
|
to replicate the data on your blockchain network to an off chain database.
|
||||||
Using an off chain database allows you to analyze the data from your network or
|
Using an off chain database allows you to analyze the data from your network or
|
||||||
build a dashboard without degrading the performance of your application.
|
build a dashboard without degrading the performance of your application.
|
||||||
|
|
||||||
This sample uses the [Fabric network event listener](https://fabric-sdk-node.github.io/release-1.4/tutorial-listening-to-events.html) from the Node.JS Fabric SDK to write data to local instance of
|
This sample uses the [Fabric network event listener](https://hyperledger.github.io/fabric-sdk-node/release-1.4/tutorial-channel-events.html) from the Node.JS Fabric SDK to write data to local instance of
|
||||||
CouchDB.
|
CouchDB.
|
||||||
|
|
||||||
## Getting started
|
## Getting started
|
||||||
|
|
||||||
This sample uses Node Fabric SDK application code similar to the `fabcar` sample
|
This sample uses Node Fabric SDK application code similar to the `fabcar` sample
|
||||||
to connect to a network created using the `first-network` 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.
|
||||||
|
|
||||||
### Install dependencies
|
### Starting the Network
|
||||||
|
|
||||||
You need to install Node.js version 8.9.x to use the sample application code.
|
Use the following command to start the sample network:
|
||||||
Execute the following commands to install the required dependencies:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
cd fabric-samples/off_chain_data
|
./startFabric.sh
|
||||||
npm install
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
### Configuration
|
### Configuration
|
||||||
|
|
||||||
The configuration for the listener is stored in the `config.json` file:
|
The configuration for the listener is stored in the `config.json` file:
|
||||||
|
|
@ -51,29 +55,24 @@ 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:
|
following command start a local instance of CouchDB using docker:
|
||||||
|
|
||||||
```
|
```
|
||||||
docker run --publish 5990:5984 --detach --name offchaindb hyperledger/fabric-couchdb
|
docker run --publish 5990:5984 --detach --name offchaindb couchdb
|
||||||
docker start offchaindb
|
docker start offchaindb
|
||||||
```
|
```
|
||||||
|
|
||||||
### Starting the Network
|
### Install dependencies
|
||||||
|
|
||||||
Use the following command to start the sample network:
|
You need to install Node.js version 8.9.x to use the sample application code.
|
||||||
|
Execute the following commands to install the required dependencies:
|
||||||
|
|
||||||
```
|
```
|
||||||
./startFabric.sh
|
npm install
|
||||||
```
|
```
|
||||||
|
|
||||||
This command uses the `first-network` sample to deploy a fabric network with an
|
|
||||||
ordering service, two peer organizations with two peers each, and a channel
|
|
||||||
named `mychannel`. The marbles chaincode will be installed on all four peers and
|
|
||||||
instantiated on the channel.
|
|
||||||
|
|
||||||
### Starting the Channel Event Listener
|
### Starting the Channel Event Listener
|
||||||
|
|
||||||
Once the network has started, we can use the Node.js SDK to create the user and
|
After we have installed the application dependencies, we can use the Node.js SDK
|
||||||
certificates our listener application will use to interact with the network. Run
|
to create the identity our listener application will use to interact with the
|
||||||
the following command to enroll the admin user:
|
network. Run the following command to enroll the admin user:
|
||||||
|
|
||||||
```
|
```
|
||||||
node enrollAdmin.js
|
node enrollAdmin.js
|
||||||
```
|
```
|
||||||
|
|
@ -358,18 +357,16 @@ database:
|
||||||
## Clean up
|
## Clean up
|
||||||
|
|
||||||
If you are finished using the sample application, you can bring down the network
|
If you are finished using the sample application, you can bring down the network
|
||||||
and any accompanying artifacts.
|
and any accompanying artifacts by running the following command:
|
||||||
|
```
|
||||||
|
./network-clean.sh
|
||||||
|
```
|
||||||
|
|
||||||
* Change to `fabric-samples/first-network` directory.
|
Running the script will complete the following actions:
|
||||||
* To stop the network, run `./byfn.sh down`.
|
|
||||||
* Change back to `fabric-samples/off_chain_data` directory.
|
* Bring down the Fabric test network.
|
||||||
|
* Takes down the local CouchDB database.
|
||||||
* Remove the certificates you generated by deleting the `wallet` folder.
|
* Remove the certificates you generated by deleting the `wallet` folder.
|
||||||
* Delete `nextblock.txt` so you can start with the first block next time you
|
* Delete `nextblock.txt` so you can start with the first block next time you
|
||||||
operate the listener. You can also reset the `nextMarbleNumber` in
|
operate the listener.
|
||||||
`addMarbles.json` to 100.
|
* Removes `addMarbles.json`.
|
||||||
* To take down the local CouchDB database, first stop and then remove the
|
|
||||||
docker container:
|
|
||||||
```
|
|
||||||
docker stop offchaindb
|
|
||||||
docker rm offchaindb
|
|
||||||
```
|
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ async function main() {
|
||||||
|
|
||||||
// Parse the connection profile. This would be the path to the file downloaded
|
// Parse the connection profile. This would be the path to the file downloaded
|
||||||
// from the IBM Blockchain Platform operational console.
|
// from the IBM Blockchain Platform operational console.
|
||||||
const ccpPath = path.resolve(__dirname, '..', 'first-network', 'connection-org1.json');
|
const ccpPath = path.resolve(__dirname, '..', 'test-network','organizations','peerOrganizations','org1.example.com', 'connection-org1.json');
|
||||||
const ccp = JSON.parse(fs.readFileSync(ccpPath, 'utf8'));
|
const ccp = JSON.parse(fs.readFileSync(ccpPath, 'utf8'));
|
||||||
|
|
||||||
// Configure a wallet. This wallet must already be primed with an identity that
|
// Configure a wallet. This wallet must already be primed with an identity that
|
||||||
|
|
@ -80,7 +80,7 @@ async function main() {
|
||||||
// Create a new gateway, and connect to the gateway peer node(s). The identity
|
// Create a new gateway, and connect to the gateway peer node(s). The identity
|
||||||
// specified must already exist in the specified wallet.
|
// specified must already exist in the specified wallet.
|
||||||
const gateway = new Gateway();
|
const gateway = new Gateway();
|
||||||
await gateway.connect(ccp, { wallet, identity: 'user1', discovery: { enabled: true, asLocalhost: true } });
|
await gateway.connect(ccp, { wallet, identity: 'appUser', discovery: { enabled: true, asLocalhost: true } });
|
||||||
|
|
||||||
// Get the network channel that the smart contract is deployed to.
|
// Get the network channel that the smart contract is deployed to.
|
||||||
const network = await gateway.getNetwork(channelid);
|
const network = await gateway.getNetwork(channelid);
|
||||||
|
|
|
||||||
|
|
@ -98,20 +98,20 @@ async function main() {
|
||||||
console.log(`Wallet path: ${walletPath}`);
|
console.log(`Wallet path: ${walletPath}`);
|
||||||
|
|
||||||
// Check to see if we've already enrolled the user.
|
// Check to see if we've already enrolled the user.
|
||||||
const userExists = await wallet.get('user1');
|
const userExists = await wallet.get('appUser');
|
||||||
if (!userExists) {
|
if (!userExists) {
|
||||||
console.log('An identity for the user "user1" does not exist in the wallet');
|
console.log('An identity for the user "appUser" does not exist in the wallet');
|
||||||
console.log('Run the enrollUser.js application before retrying');
|
console.log('Run the enrollUser.js application before retrying');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse the connection profile. This would be the path to the file downloaded
|
// Parse the connection profile. This would be the path to the file downloaded
|
||||||
// from the IBM Blockchain Platform operational console.
|
// from the IBM Blockchain Platform operational console.
|
||||||
const ccpPath = path.resolve(__dirname, '..', 'first-network', 'connection-org1.json');
|
const ccpPath = path.resolve(__dirname, '..', 'test-network','organizations','peerOrganizations','org1.example.com', 'connection-org1.json');
|
||||||
const ccp = JSON.parse(fs.readFileSync(ccpPath, 'utf8'));
|
const ccp = JSON.parse(fs.readFileSync(ccpPath, 'utf8'));
|
||||||
// Create a new gateway for connecting to our peer node.
|
// Create a new gateway for connecting to our peer node.
|
||||||
const gateway = new Gateway();
|
const gateway = new Gateway();
|
||||||
await gateway.connect(ccp, { wallet, identity: 'user1', discovery: { enabled: true, asLocalhost: true } });
|
await gateway.connect(ccp, { wallet, identity: 'appUser', discovery: { enabled: true, asLocalhost: true } });
|
||||||
|
|
||||||
// Get the network (channel) our contract is deployed to.
|
// Get the network (channel) our contract is deployed to.
|
||||||
const network = await gateway.getNetwork('mychannel');
|
const network = await gateway.getNetwork('mychannel');
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ async function main() {
|
||||||
|
|
||||||
// Parse the connection profile. This would be the path to the file downloaded
|
// Parse the connection profile. This would be the path to the file downloaded
|
||||||
// from the IBM Blockchain Platform operational console.
|
// from the IBM Blockchain Platform operational console.
|
||||||
const ccpPath = path.resolve(__dirname, '..', 'first-network', 'connection-org1.json');
|
const ccpPath = path.resolve(__dirname, '..', 'test-network','organizations','peerOrganizations','org1.example.com', 'connection-org1.json');
|
||||||
const ccp = JSON.parse(fs.readFileSync(ccpPath, 'utf8'));
|
const ccp = JSON.parse(fs.readFileSync(ccpPath, 'utf8'));
|
||||||
|
|
||||||
// Configure a wallet. This wallet must already be primed with an identity that
|
// Configure a wallet. This wallet must already be primed with an identity that
|
||||||
|
|
@ -47,7 +47,7 @@ async function main() {
|
||||||
// Create a new gateway, and connect to the gateway peer node(s). The identity
|
// Create a new gateway, and connect to the gateway peer node(s). The identity
|
||||||
// specified must already exist in the specified wallet.
|
// specified must already exist in the specified wallet.
|
||||||
const gateway = new Gateway();
|
const gateway = new Gateway();
|
||||||
await gateway.connect(ccp, { wallet, identity: 'user1', discovery: { enabled: true, asLocalhost: true } });
|
await gateway.connect(ccp, { wallet, identity: 'appUser', discovery: { enabled: true, asLocalhost: true } });
|
||||||
|
|
||||||
// Get the network channel that the smart contract is deployed to.
|
// Get the network channel that the smart contract is deployed to.
|
||||||
const network = await gateway.getNetwork(channelid);
|
const network = await gateway.getNetwork(channelid);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright IBM Corp. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
@ -15,7 +13,7 @@ const path = require('path');
|
||||||
async function main() {
|
async function main() {
|
||||||
try {
|
try {
|
||||||
// load the network configuration
|
// load the network configuration
|
||||||
const ccpPath = path.resolve(__dirname, '..', 'first-network', 'connection-org1.json');
|
const ccpPath = path.resolve(__dirname, '..', 'test-network', 'organizations', 'peerOrganizations', 'org1.example.com', 'connection-org1.json');
|
||||||
let ccp = JSON.parse(fs.readFileSync(ccpPath, 'utf8'));
|
let ccp = JSON.parse(fs.readFileSync(ccpPath, 'utf8'));
|
||||||
|
|
||||||
// Create a new CA client for interacting with the CA.
|
// Create a new CA client for interacting with the CA.
|
||||||
|
|
|
||||||
20
off_chain_data/network-clean.sh
Executable file
20
off_chain_data/network-clean.sh
Executable file
|
|
@ -0,0 +1,20 @@
|
||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# Copyright IBM Corp All Rights Reserved
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
#
|
||||||
|
# Exit on first error
|
||||||
|
set -ex
|
||||||
|
|
||||||
|
# Bring the test network down
|
||||||
|
pushd ../test-network
|
||||||
|
./network.sh down
|
||||||
|
popd
|
||||||
|
|
||||||
|
# clean out any old identites in the wallets
|
||||||
|
rm -rf wallet
|
||||||
|
rm -rf addMarbles.json mychannel_marbles.log mychannel__lifecycle.log nextblock.txt
|
||||||
|
|
||||||
|
docker stop offchaindb
|
||||||
|
docker rm offchaindb
|
||||||
|
|
@ -1,6 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright IBM Corp. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
@ -15,7 +13,7 @@ const path = require('path');
|
||||||
async function main() {
|
async function main() {
|
||||||
try {
|
try {
|
||||||
// load the network configuration
|
// load the network configuration
|
||||||
const ccpPath = path.resolve(__dirname, '..', 'first-network', 'connection-org1.json');
|
const ccpPath = path.resolve(__dirname, '..', 'test-network','organizations','peerOrganizations','org1.example.com', 'connection-org1.json');
|
||||||
const ccp = JSON.parse(fs.readFileSync(ccpPath, 'utf8'));
|
const ccp = JSON.parse(fs.readFileSync(ccpPath, 'utf8'));
|
||||||
|
|
||||||
// Create a new CA client for interacting with the CA.
|
// Create a new CA client for interacting with the CA.
|
||||||
|
|
@ -28,9 +26,9 @@ async function main() {
|
||||||
console.log(`Wallet path: ${walletPath}`);
|
console.log(`Wallet path: ${walletPath}`);
|
||||||
|
|
||||||
// Check to see if we've already enrolled the user.
|
// Check to see if we've already enrolled the user.
|
||||||
const userExists = await wallet.get('user1');
|
const userExists = await wallet.get('appUser');
|
||||||
if (userExists) {
|
if (userExists) {
|
||||||
console.log('An identity for the user "user1" already exists in the wallet');
|
console.log('An identity for the user "appUser" already exists in the wallet');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -49,11 +47,11 @@ async function main() {
|
||||||
// Register the user, enroll the user, and import the new identity into the wallet.
|
// Register the user, enroll the user, and import the new identity into the wallet.
|
||||||
const secret = await ca.register({
|
const secret = await ca.register({
|
||||||
affiliation: 'org1.department1',
|
affiliation: 'org1.department1',
|
||||||
enrollmentID: 'user1',
|
enrollmentID: 'appUser',
|
||||||
role: 'client'
|
role: 'client'
|
||||||
}, adminUser);
|
}, adminUser);
|
||||||
const enrollment = await ca.enroll({
|
const enrollment = await ca.enroll({
|
||||||
enrollmentID: 'user1',
|
enrollmentID: 'appUser',
|
||||||
enrollmentSecret: secret
|
enrollmentSecret: secret
|
||||||
});
|
});
|
||||||
const x509Identity = {
|
const x509Identity = {
|
||||||
|
|
@ -64,11 +62,11 @@ async function main() {
|
||||||
mspId: 'Org1MSP',
|
mspId: 'Org1MSP',
|
||||||
type: 'X.509',
|
type: 'X.509',
|
||||||
};
|
};
|
||||||
await wallet.put('user1', x509Identity);
|
await wallet.put('appUser', x509Identity);
|
||||||
console.log('Successfully registered and enrolled admin user "user1" and imported it into the wallet');
|
console.log('Successfully registered and enrolled admin user "appUser" and imported it into the wallet');
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Failed to register user "user1": ${error}`);
|
console.error(`Failed to register user "appUser": ${error}`);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,98 +7,64 @@
|
||||||
# Exit on first error
|
# Exit on first error
|
||||||
set -e pipefail
|
set -e pipefail
|
||||||
|
|
||||||
|
|
||||||
# don't rewrite paths for Windows Git Bash users
|
# don't rewrite paths for Windows Git Bash users
|
||||||
export MSYS_NO_PATHCONV=1
|
export MSYS_NO_PATHCONV=1
|
||||||
starttime=$(date +%s)
|
starttime=$(date +%s)
|
||||||
CC_SRC_LANGUAGE=golang
|
CC_SRC_LANGUAGE=golang
|
||||||
CC_RUNTIME_LANGUAGE=golang
|
CC_RUNTIME_LANGUAGE=golang
|
||||||
CC_SRC_PATH=github.com/hyperledger/fabric-samples/chaincode/marbles02/go
|
CC_SRC_PATH=../chaincode/marbles02/go
|
||||||
|
|
||||||
echo Vendoring Go dependencies ...
|
echo Vendoring Go dependencies ...
|
||||||
pushd ../chaincode/marbles02/go
|
pushd ../chaincode/marbles02/go
|
||||||
GO111MODULE=on go mod vendor
|
GO111MODULE=on go mod vendor
|
||||||
popd
|
popd
|
||||||
echo Finished vendoring Go dependencies
|
echo Finished vendoring Go dependencies
|
||||||
|
|
||||||
# clean the keystore
|
|
||||||
rm -rf ./hfc-key-store
|
|
||||||
|
|
||||||
# launch network; create channel and join peer to channel
|
# launch network; create channel and join peer to channel
|
||||||
pushd ../first-network
|
pushd ../test-network
|
||||||
echo y | ./byfn.sh down
|
./network.sh down
|
||||||
echo y | ./byfn.sh up -a -n -s couchdb
|
./network.sh up createChannel -ca -s couchdb
|
||||||
popd
|
|
||||||
|
|
||||||
CONFIG_ROOT=/opt/gopath/src/github.com/hyperledger/fabric/peer
|
export PATH=${PWD}/../bin:${PWD}:$PATH
|
||||||
ORG1_MSPCONFIGPATH=${CONFIG_ROOT}/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
|
export FABRIC_CFG_PATH=${PWD}/../config
|
||||||
ORG1_TLS_ROOTCERT_FILE=${CONFIG_ROOT}/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
|
|
||||||
ORG2_MSPCONFIGPATH=${CONFIG_ROOT}/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
|
# import environment variables
|
||||||
ORG2_TLS_ROOTCERT_FILE=${CONFIG_ROOT}/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
|
. scripts/envVar.sh
|
||||||
ORDERER_TLS_ROOTCERT_FILE=${CONFIG_ROOT}/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
|
|
||||||
|
|
||||||
echo "Packaging the marbles smart contract"
|
echo "Packaging the marbles smart contract"
|
||||||
docker exec \
|
|
||||||
cli \
|
setGlobals 1
|
||||||
peer lifecycle chaincode package marbles.tar.gz \
|
|
||||||
--path $CC_SRC_PATH \
|
peer lifecycle chaincode package marbles.tar.gz \
|
||||||
--lang $CC_RUNTIME_LANGUAGE \
|
--path $CC_SRC_PATH \
|
||||||
--label marblesv1
|
--lang $CC_RUNTIME_LANGUAGE \
|
||||||
|
--label marblesv1
|
||||||
|
|
||||||
echo "Installing smart contract on peer0.org1.example.com"
|
echo "Installing smart contract on peer0.org1.example.com"
|
||||||
docker exec \
|
|
||||||
-e CORE_PEER_LOCALMSPID=Org1MSP \
|
|
||||||
-e CORE_PEER_ADDRESS=peer0.org1.example.com:7051 \
|
|
||||||
-e CORE_PEER_MSPCONFIGPATH=${ORG1_MSPCONFIGPATH} \
|
|
||||||
-e CORE_PEER_TLS_ROOTCERT_FILE=${ORG1_TLS_ROOTCERT_FILE} \
|
|
||||||
cli \
|
|
||||||
peer lifecycle chaincode install marbles.tar.gz
|
|
||||||
|
|
||||||
echo "Installing smart contract on peer1.org1.example.com"
|
peer lifecycle chaincode install marbles.tar.gz
|
||||||
docker exec \
|
|
||||||
-e CORE_PEER_LOCALMSPID=Org1MSP \
|
|
||||||
-e CORE_PEER_ADDRESS=peer1.org1.example.com:8051 \
|
|
||||||
-e CORE_PEER_MSPCONFIGPATH=${ORG1_MSPCONFIGPATH} \
|
|
||||||
-e CORE_PEER_TLS_ROOTCERT_FILE=${ORG1_TLS_ROOTCERT_FILE} \
|
|
||||||
cli \
|
|
||||||
peer lifecycle chaincode install marbles.tar.gz
|
|
||||||
|
|
||||||
echo "Installing smart contract on peer0.org2.example.com"
|
echo "Installing smart contract on peer0.org2.example.com"
|
||||||
docker exec \
|
|
||||||
-e CORE_PEER_LOCALMSPID=Org2MSP \
|
|
||||||
-e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \
|
|
||||||
-e CORE_PEER_MSPCONFIGPATH=${ORG2_MSPCONFIGPATH} \
|
|
||||||
-e CORE_PEER_TLS_ROOTCERT_FILE=${ORG2_TLS_ROOTCERT_FILE} \
|
|
||||||
cli \
|
|
||||||
peer lifecycle chaincode install marbles.tar.gz
|
|
||||||
|
|
||||||
echo "Installing smart contract on peer1.org2.example.com"
|
setGlobals 2
|
||||||
docker exec \
|
|
||||||
-e CORE_PEER_LOCALMSPID=Org2MSP \
|
peer lifecycle chaincode install marbles.tar.gz
|
||||||
-e CORE_PEER_ADDRESS=peer1.org2.example.com:10051 \
|
|
||||||
-e CORE_PEER_MSPCONFIGPATH=${ORG2_MSPCONFIGPATH} \
|
|
||||||
-e CORE_PEER_TLS_ROOTCERT_FILE=${ORG2_TLS_ROOTCERT_FILE} \
|
|
||||||
cli \
|
|
||||||
peer lifecycle chaincode install marbles.tar.gz
|
|
||||||
|
|
||||||
echo "Query the chaincode package id"
|
echo "Query the chaincode package id"
|
||||||
docker exec \
|
|
||||||
-e CORE_PEER_LOCALMSPID=Org1MSP \
|
setGlobals 1
|
||||||
-e CORE_PEER_ADDRESS=peer0.org1.example.com:7051 \
|
|
||||||
-e CORE_PEER_MSPCONFIGPATH=${ORG1_MSPCONFIGPATH} \
|
peer lifecycle chaincode queryinstalled >&log.txt
|
||||||
-e CORE_PEER_TLS_ROOTCERT_FILE=${ORG1_TLS_ROOTCERT_FILE} \
|
|
||||||
cli \
|
PACKAGE_ID=$(sed -n "/marblesv1/{s/^Package ID: //; s/, Label:.*$//; p;}" log.txt)
|
||||||
/bin/bash -c "peer lifecycle chaincode queryinstalled > log"
|
|
||||||
PACKAGE_ID=`docker exec cli sed -nr '/Label: marblesv1/s/Package ID: (.*), Label: marblesv1/\1/p;' log`
|
|
||||||
|
|
||||||
echo "Approving the chaincode definition for org1.example.com"
|
echo "Approving the chaincode definition for org1.example.com"
|
||||||
docker exec \
|
|
||||||
-e CORE_PEER_LOCALMSPID=Org1MSP \
|
peer lifecycle chaincode approveformyorg \
|
||||||
-e CORE_PEER_ADDRESS=peer0.org1.example.com:7051 \
|
-o localhost:7050 \
|
||||||
-e CORE_PEER_MSPCONFIGPATH=${ORG1_MSPCONFIGPATH} \
|
--ordererTLSHostnameOverride orderer.example.com \
|
||||||
-e CORE_PEER_TLS_ROOTCERT_FILE=${ORG1_TLS_ROOTCERT_FILE} \
|
|
||||||
cli \
|
|
||||||
peer lifecycle chaincode approveformyorg \
|
|
||||||
-o orderer.example.com:7050 \
|
|
||||||
--channelID mychannel \
|
--channelID mychannel \
|
||||||
--name marbles \
|
--name marbles \
|
||||||
--version 1.0 \
|
--version 1.0 \
|
||||||
|
|
@ -107,17 +73,15 @@ docker exec \
|
||||||
--sequence 1 \
|
--sequence 1 \
|
||||||
--package-id $PACKAGE_ID \
|
--package-id $PACKAGE_ID \
|
||||||
--tls \
|
--tls \
|
||||||
--cafile ${ORDERER_TLS_ROOTCERT_FILE}
|
--cafile ${ORDERER_CA}
|
||||||
|
|
||||||
echo "Approving the chaincode definition for org2.example.com"
|
echo "Approving the chaincode definition for org2.example.com"
|
||||||
docker exec \
|
|
||||||
-e CORE_PEER_LOCALMSPID=Org2MSP \
|
setGlobals 2
|
||||||
-e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \
|
|
||||||
-e CORE_PEER_MSPCONFIGPATH=${ORG2_MSPCONFIGPATH} \
|
peer lifecycle chaincode approveformyorg \
|
||||||
-e CORE_PEER_TLS_ROOTCERT_FILE=${ORG2_TLS_ROOTCERT_FILE} \
|
-o localhost:7050 \
|
||||||
cli \
|
--ordererTLSHostnameOverride orderer.example.com \
|
||||||
peer lifecycle chaincode approveformyorg \
|
|
||||||
-o orderer.example.com:7050 \
|
|
||||||
--channelID mychannel \
|
--channelID mychannel \
|
||||||
--name marbles \
|
--name marbles \
|
||||||
--version 1.0 \
|
--version 1.0 \
|
||||||
|
|
@ -126,19 +90,38 @@ docker exec \
|
||||||
--sequence 1 \
|
--sequence 1 \
|
||||||
--package-id $PACKAGE_ID \
|
--package-id $PACKAGE_ID \
|
||||||
--tls \
|
--tls \
|
||||||
--cafile ${ORDERER_TLS_ROOTCERT_FILE}
|
--cafile ${ORDERER_CA}
|
||||||
|
|
||||||
echo "Waiting for the approvals to be committed ..."
|
echo "Checking if the chaincode definition is ready to commit"
|
||||||
|
|
||||||
sleep 10
|
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"
|
echo "Commit the chaincode definition to the channel"
|
||||||
docker exec \
|
|
||||||
-e CORE_PEER_LOCALMSPID=Org1MSP \
|
peer lifecycle chaincode commit \
|
||||||
-e CORE_PEER_MSPCONFIGPATH=${ORG1_MSPCONFIGPATH} \
|
-o localhost:7050 \
|
||||||
cli \
|
--ordererTLSHostnameOverride orderer.example.com \
|
||||||
peer lifecycle chaincode commit \
|
|
||||||
-o orderer.example.com:7050 \
|
|
||||||
--channelID mychannel \
|
--channelID mychannel \
|
||||||
--name marbles \
|
--name marbles \
|
||||||
--version 1.0 \
|
--version 1.0 \
|
||||||
|
|
@ -146,35 +129,41 @@ docker exec \
|
||||||
--signature-policy AND"('Org1MSP.member','Org2MSP.member')" \
|
--signature-policy AND"('Org1MSP.member','Org2MSP.member')" \
|
||||||
--sequence 1 \
|
--sequence 1 \
|
||||||
--tls \
|
--tls \
|
||||||
--cafile ${ORDERER_TLS_ROOTCERT_FILE} \
|
--cafile ${ORDERER_CA} \
|
||||||
--peerAddresses peer0.org1.example.com:7051 \
|
$PEER_CONN_PARMS
|
||||||
--tlsRootCertFiles ${ORG1_TLS_ROOTCERT_FILE} \
|
|
||||||
--peerAddresses peer0.org2.example.com:9051 \
|
|
||||||
--tlsRootCertFiles ${ORG2_TLS_ROOTCERT_FILE}
|
|
||||||
|
|
||||||
echo "Waiting for the chaincode to be committed ..."
|
echo "Check if the chaincode has been committed to the channel ..."
|
||||||
|
|
||||||
sleep 10
|
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 ... "
|
echo "invoke the marbles chaincode init function ... "
|
||||||
docker exec \
|
|
||||||
-e CORE_PEER_LOCALMSPID=Org1MSP \
|
|
||||||
-e CORE_PEER_ADDRESS=peer0.org1.example.com:7051 \
|
|
||||||
cli \
|
|
||||||
peer chaincode invoke \
|
|
||||||
-o orderer.example.com:7050 \
|
|
||||||
-C mychannel \
|
|
||||||
-n marbles \
|
|
||||||
--isInit \
|
|
||||||
-c '{"Args":["Init"]}' \
|
|
||||||
--tls \
|
|
||||||
--cafile ${ORDERER_TLS_ROOTCERT_FILE} \
|
|
||||||
--peerAddresses peer0.org1.example.com:7051 \
|
|
||||||
--tlsRootCertFiles ${ORG1_TLS_ROOTCERT_FILE} \
|
|
||||||
--peerAddresses peer0.org2.example.com:9051 \
|
|
||||||
--tlsRootCertFiles ${ORG2_TLS_ROOTCERT_FILE}
|
|
||||||
|
|
||||||
sleep 10
|
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
|
||||||
|
|
||||||
|
popd
|
||||||
|
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ async function main() {
|
||||||
|
|
||||||
// Parse the connection profile. This would be the path to the file downloaded
|
// Parse the connection profile. This would be the path to the file downloaded
|
||||||
// from the IBM Blockchain Platform operational console.
|
// from the IBM Blockchain Platform operational console.
|
||||||
const ccpPath = path.resolve(__dirname, '..', 'first-network', 'connection-org1.json');
|
const ccpPath = path.resolve(__dirname, '..', 'test-network','organizations','peerOrganizations','org1.example.com', 'connection-org1.json');
|
||||||
const ccp = JSON.parse(fs.readFileSync(ccpPath, 'utf8'));
|
const ccp = JSON.parse(fs.readFileSync(ccpPath, 'utf8'));
|
||||||
|
|
||||||
// Configure a wallet. This wallet must already be primed with an identity that
|
// Configure a wallet. This wallet must already be primed with an identity that
|
||||||
|
|
@ -47,7 +47,7 @@ async function main() {
|
||||||
// Create a new gateway, and connect to the gateway peer node(s). The identity
|
// Create a new gateway, and connect to the gateway peer node(s). The identity
|
||||||
// specified must already exist in the specified wallet.
|
// specified must already exist in the specified wallet.
|
||||||
const gateway = new Gateway();
|
const gateway = new Gateway();
|
||||||
await gateway.connect(ccp, { wallet, identity: 'user1', discovery: { enabled: true, asLocalhost: true } });
|
await gateway.connect(ccp, { wallet, identity: 'appUser', discovery: { enabled: true, asLocalhost: true } });
|
||||||
|
|
||||||
// Get the network channel that the smart contract is deployed to.
|
// Get the network channel that the smart contract is deployed to.
|
||||||
const network = await gateway.getNetwork(channelid);
|
const network = await gateway.getNetwork(channelid);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue