mirror of
https://github.com/hyperledger/fabric-samples.git
synced 2026-06-26 11:35:10 +00:00
Merge branch 'master' of github.com:girigaurav/fabric-samples into asset-transfer-sbe-java
This commit is contained in:
commit
7b6b2aba91
31 changed files with 959 additions and 493 deletions
|
|
@ -25,7 +25,7 @@ transfer an asset in a more realistic transfer scenario.
|
||||||
|
|
||||||
| **Smart Contract** | **Description** | **Tutorial** | **Smart contract languages** | **Application languages** |
|
| **Smart Contract** | **Description** | **Tutorial** | **Smart contract languages** | **Application languages** |
|
||||||
| -----------|------------------------------|----------|---------|---------|
|
| -----------|------------------------------|----------|---------|---------|
|
||||||
| [Basic](asset-transfer-basic) | The Basic sample smart contract that allows you to create and transfer an asset by putting data on the ledger and retrieving it. This sample is recommended for new Fabric users. | [Writing your first application](https://hyperledger-fabric.readthedocs.io/en/master/write_first_app.html) | Go, JavaScript, TypeScript, Java | JavaScript, Java |
|
| [Basic](asset-transfer-basic) | The Basic sample smart contract that allows you to create and transfer an asset by putting data on the ledger and retrieving it. This sample is recommended for new Fabric users. | [Writing your first application](https://hyperledger-fabric.readthedocs.io/en/master/write_first_app.html) | Go, JavaScript, TypeScript, Java | Go, JavaScript, Java |
|
||||||
| [Ledger queries](asset-transfer-ledger-queries) | The ledger queries sample demonstrates range queries and transaction updates using range queries (applicable for both LevelDB and CouchDB state databases), and how to deploy an index with your chaincode to support JSON queries (applicable for CouchDB state database only). | [Using CouchDB](https://hyperledger-fabric.readthedocs.io/en/master/couchdb_tutorial.html) | Go, JavaScript | Java |
|
| [Ledger queries](asset-transfer-ledger-queries) | The ledger queries sample demonstrates range queries and transaction updates using range queries (applicable for both LevelDB and CouchDB state databases), and how to deploy an index with your chaincode to support JSON queries (applicable for CouchDB state database only). | [Using CouchDB](https://hyperledger-fabric.readthedocs.io/en/master/couchdb_tutorial.html) | Go, JavaScript | Java |
|
||||||
| [Private data](asset-transfer-private-data) | This sample demonstrates the use of private data collections, how to manage private data collections with the chaincode lifecycle, and how the private data hash can be used to verify private data on the ledger. It also demonstrates how to control asset updates and transfers using client-based ownership and access control. | [Using Private Data](https://github.com/hyperledger/fabric-samples/tree/master/asset-transfer-private-data/chaincode-go) | Go | JavaScript |
|
| [Private data](asset-transfer-private-data) | This sample demonstrates the use of private data collections, how to manage private data collections with the chaincode lifecycle, and how the private data hash can be used to verify private data on the ledger. It also demonstrates how to control asset updates and transfers using client-based ownership and access control. | [Using Private Data](https://github.com/hyperledger/fabric-samples/tree/master/asset-transfer-private-data/chaincode-go) | Go | JavaScript |
|
||||||
| [State-Based Endorsement](asset-transfer-sbe) | This sample demonstrates how to override the chaincode-level endorsement policy to set endorsement policies at the key-level (data/asset level). | [Using State-based endorsement](https://github.com/hyperledger/fabric-samples/tree/master/asset-transfer-sbe) | TypeScript | **Coming soon** |
|
| [State-Based Endorsement](asset-transfer-sbe) | This sample demonstrates how to override the chaincode-level endorsement policy to set endorsement policies at the key-level (data/asset level). | [Using State-based endorsement](https://github.com/hyperledger/fabric-samples/tree/master/asset-transfer-sbe) | TypeScript | **Coming soon** |
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,9 @@ SPDX-License-Identifier: Apache-2.0
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
|
|
@ -18,20 +18,22 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
fmt.Println("============ application-golang starts ============")
|
log.Println("============ application-golang starts ============")
|
||||||
|
|
||||||
|
err := os.Setenv("DISCOVERY_AS_LOCALHOST", "true")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Error setting DISCOVERY_AS_LOCALHOST environemnt variable: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
os.Setenv("DISCOVERY_AS_LOCALHOST", "true")
|
|
||||||
wallet, err := gateway.NewFileSystemWallet("wallet")
|
wallet, err := gateway.NewFileSystemWallet("wallet")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("failed to create wallet: %v\n", err)
|
log.Fatalf("Failed to create wallet: %v", err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !wallet.Exists("appUser") {
|
if !wallet.Exists("appUser") {
|
||||||
err = populateWallet(wallet)
|
err = populateWallet(wallet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("failed to populate wallet contents: %v\n", err)
|
log.Fatalf("Failed to populate wallet contents: %v", err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -50,57 +52,73 @@ func main() {
|
||||||
gateway.WithIdentity(wallet, "appUser"),
|
gateway.WithIdentity(wallet, "appUser"),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("failed to connect to gateway: %v\n", err)
|
log.Fatalf("Failed to connect to gateway: %v", err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
defer gw.Close()
|
defer gw.Close()
|
||||||
|
|
||||||
network, err := gw.GetNetwork("mychannel")
|
network, err := gw.GetNetwork("mychannel")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("failed to get network: %v\n", err)
|
log.Fatalf("Failed to get network: %v", err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
contract := network.GetContract("basic")
|
contract := network.GetContract("basic")
|
||||||
|
|
||||||
result, err := contract.EvaluateTransaction("GetAllAssets")
|
result, err := contract.SubmitTransaction("InitLedger")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("failed to evaluate transaction: %v\n", err)
|
log.Fatalf("failed to evaluate transaction: %v", err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
fmt.Println(string(result))
|
log.Println(string(result))
|
||||||
|
|
||||||
result, err = contract.SubmitTransaction("CreateAsset", "asset13", "yellow", "Tom", "5", "1300")
|
result, err = contract.EvaluateTransaction("GetAllAssets")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("failed to submit transaction: %v\n", err)
|
log.Fatalf("Failed to evaluate transaction: %v", err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
fmt.Println(string(result))
|
log.Println(string(result))
|
||||||
|
|
||||||
result, err = contract.EvaluateTransaction("ReadAsset", "asset4")
|
result, err = contract.SubmitTransaction("CreateAsset", "asset13", "yellow", "5", "Tom", "1300")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("failed to evaluate transaction: %v\n", err)
|
log.Fatalf("Failed to submit transaction: %v", err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
fmt.Println(string(result))
|
log.Println(string(result))
|
||||||
|
|
||||||
|
log.Println("--> Submit Transaction: CreateAsset, creates new asset with ID, color, owner, size, and appraisedValue arguments")
|
||||||
|
result, err = contract.SubmitTransaction("CreateAsset", "asset13", "yellow", "5", "Tom", "1300")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Failed to evaluate transaction: %v", err)
|
||||||
|
}
|
||||||
|
log.Println(string(result))
|
||||||
|
|
||||||
|
log.Println("--> Evaluate Transaction: ReadAsset, function returns an asset with a given assetID")
|
||||||
|
result, err = contract.EvaluateTransaction("ReadAsset", "asset13")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("failed to evaluate transaction: %v\n", err)
|
||||||
|
}
|
||||||
|
log.Println(string(result))
|
||||||
|
|
||||||
|
log.Println("--> Evaluate Transaction: AssetExists, function returns 'true' if an asset with given assetID exist")
|
||||||
|
result, err = contract.EvaluateTransaction("AssetExists", "asset1")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("failed to evaluate transaction: %v\n", err)
|
||||||
|
}
|
||||||
|
log.Println(string(result))
|
||||||
|
|
||||||
|
log.Println("--> Submit Transaction: TransferAsset asset1, transfer to new owner of Tom")
|
||||||
_, err = contract.SubmitTransaction("TransferAsset", "asset1", "Tom")
|
_, err = contract.SubmitTransaction("TransferAsset", "asset1", "Tom")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Failed to submit transaction: %v\n", err)
|
log.Fatalf("Failed to submit transaction: %v", err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Println("--> Evaluate Transaction: ReadAsset, function returns 'asset1' attributes")
|
||||||
result, err = contract.EvaluateTransaction("ReadAsset", "asset1")
|
result, err = contract.EvaluateTransaction("ReadAsset", "asset1")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("failed to evaluate transaction: %v\n", err)
|
log.Fatalf("Failed to evaluate transaction: %v", err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
fmt.Println(string(result))
|
log.Println(string(result))
|
||||||
fmt.Println("============ application-golang ends ============")
|
log.Println("============ application-golang ends ============")
|
||||||
}
|
}
|
||||||
|
|
||||||
func populateWallet(wallet *gateway.Wallet) error {
|
func populateWallet(wallet *gateway.Wallet) error {
|
||||||
fmt.Println("============ populate wallet starts ============")
|
log.Println("============ Populating wallet ============")
|
||||||
credPath := filepath.Join(
|
credPath := filepath.Join(
|
||||||
"..",
|
"..",
|
||||||
"..",
|
"..",
|
||||||
|
|
@ -127,7 +145,7 @@ func populateWallet(wallet *gateway.Wallet) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if len(files) != 1 {
|
if len(files) != 1 {
|
||||||
return errors.New("keystore folder should have contain one file")
|
return fmt.Errorf("keystore folder should have contain one file")
|
||||||
}
|
}
|
||||||
keyPath := filepath.Join(keyDir, files[0].Name())
|
keyPath := filepath.Join(keyDir, files[0].Name())
|
||||||
key, err := ioutil.ReadFile(filepath.Clean(keyPath))
|
key, err := ioutil.ReadFile(filepath.Clean(keyPath))
|
||||||
|
|
@ -137,10 +155,5 @@ func populateWallet(wallet *gateway.Wallet) error {
|
||||||
|
|
||||||
identity := gateway.NewX509Identity("Org1MSP", string(cert), string(key))
|
identity := gateway.NewX509Identity("Org1MSP", string(cert), string(key))
|
||||||
|
|
||||||
err = wallet.Put("appUser", identity)
|
return wallet.Put("appUser", identity)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fmt.Println("============ populate wallet ends ============")
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,10 @@ set -euo pipefail
|
||||||
|
|
||||||
METADIR=$2
|
METADIR=$2
|
||||||
# check if the "type" field is set to "external"
|
# check if the "type" field is set to "external"
|
||||||
# crude way without jq, fragile but good enough for this sample...
|
# crude way without jq which is not in the default fabric peer image
|
||||||
if [ "$(grep type "$METADIR/metadata.json" |cut -f4 -d\")" = "external" ]; then
|
TYPE=$(tr -d '\n' < "$METADIR/metadata.json" | awk -F':' '{ for (i = 1; i < NF; i++){ if ($i~/type/) { print $(i+1); break }}}'| cut -d\" -f2)
|
||||||
|
|
||||||
|
if [ "$TYPE" = "external" ]; then
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,8 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
env: {
|
env: {
|
||||||
node: true,
|
node: true,
|
||||||
mocha: true
|
mocha: true,
|
||||||
|
es6: true
|
||||||
},
|
},
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
ecmaVersion: 8,
|
ecmaVersion: 8,
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,9 @@
|
||||||
# Coverage directory used by tools like istanbul
|
# Coverage directory used by tools like istanbul
|
||||||
coverage
|
coverage
|
||||||
|
|
||||||
|
# Report cache used by istanbul
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
# Dependency directories
|
# Dependency directories
|
||||||
node_modules/
|
node_modules/
|
||||||
jspm_packages/
|
jspm_packages/
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,9 @@
|
||||||
"nyc": {
|
"nyc": {
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"coverage/**",
|
"coverage/**",
|
||||||
"test/**"
|
"test/**",
|
||||||
|
"index.js",
|
||||||
|
".eslintrc.js"
|
||||||
],
|
],
|
||||||
"reporter": [
|
"reporter": [
|
||||||
"text-summary",
|
"text-summary",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,262 @@
|
||||||
|
'use strict';
|
||||||
|
const sinon = require('sinon');
|
||||||
|
const chai = require('chai');
|
||||||
|
const sinonChai = require('sinon-chai');
|
||||||
|
const expect = chai.expect;
|
||||||
|
|
||||||
|
const { Context } = require('fabric-contract-api');
|
||||||
|
const { ChaincodeStub } = require('fabric-shim');
|
||||||
|
|
||||||
|
const AssetTransfer = require('../lib/assetTransfer.js');
|
||||||
|
|
||||||
|
let assert = sinon.assert;
|
||||||
|
chai.use(sinonChai);
|
||||||
|
|
||||||
|
describe('Asset Transfer Basic Tests', () => {
|
||||||
|
let transactionContext, chaincodeStub, asset;
|
||||||
|
beforeEach(() => {
|
||||||
|
transactionContext = new Context();
|
||||||
|
|
||||||
|
chaincodeStub = sinon.createStubInstance(ChaincodeStub);
|
||||||
|
transactionContext.setChaincodeStub(chaincodeStub);
|
||||||
|
|
||||||
|
chaincodeStub.putState.callsFake((key, value) => {
|
||||||
|
if (!chaincodeStub.states) {
|
||||||
|
chaincodeStub.states = {};
|
||||||
|
}
|
||||||
|
chaincodeStub.states[key] = value;
|
||||||
|
});
|
||||||
|
|
||||||
|
chaincodeStub.getState.callsFake(async (key) => {
|
||||||
|
let ret;
|
||||||
|
if (chaincodeStub.states) {
|
||||||
|
ret = chaincodeStub.states[key];
|
||||||
|
}
|
||||||
|
return Promise.resolve(ret);
|
||||||
|
});
|
||||||
|
|
||||||
|
chaincodeStub.deleteState.callsFake(async (key) => {
|
||||||
|
if (chaincodeStub.states) {
|
||||||
|
delete chaincodeStub.states[key];
|
||||||
|
}
|
||||||
|
return Promise.resolve(key);
|
||||||
|
});
|
||||||
|
|
||||||
|
chaincodeStub.getStateByRange.callsFake(async () => {
|
||||||
|
function* internalGetStateByRange() {
|
||||||
|
if (chaincodeStub.states) {
|
||||||
|
// Shallow copy
|
||||||
|
const copied = Object.assign({}, chaincodeStub.states);
|
||||||
|
|
||||||
|
for (let key in copied) {
|
||||||
|
yield {value: copied[key]};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.resolve(internalGetStateByRange());
|
||||||
|
});
|
||||||
|
|
||||||
|
asset = {
|
||||||
|
ID: 'asset1',
|
||||||
|
Color: 'blue',
|
||||||
|
Size: 5,
|
||||||
|
Owner: 'Tomoko',
|
||||||
|
AppraisedValue: 300,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Test InitLedger', () => {
|
||||||
|
it('should return error on InitLedger', async () => {
|
||||||
|
chaincodeStub.putState.rejects('failed inserting key');
|
||||||
|
let assetTransfer = new AssetTransfer();
|
||||||
|
try {
|
||||||
|
await assetTransfer.InitLedger(transactionContext);
|
||||||
|
assert.fail('InitLedger should have failed');
|
||||||
|
} catch (err) {
|
||||||
|
expect(err.name).to.equal('failed inserting key');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return success on InitLedger', async () => {
|
||||||
|
let assetTransfer = new AssetTransfer();
|
||||||
|
await assetTransfer.InitLedger(transactionContext);
|
||||||
|
let ret = JSON.parse((await chaincodeStub.getState('asset1')).toString());
|
||||||
|
expect(ret).to.eql(Object.assign({docType: 'asset'}, asset));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Test CreateAsset', () => {
|
||||||
|
it('should return error on CreateAsset', async () => {
|
||||||
|
chaincodeStub.putState.rejects('failed inserting key');
|
||||||
|
|
||||||
|
let assetTransfer = new AssetTransfer();
|
||||||
|
try {
|
||||||
|
await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue);
|
||||||
|
assert.fail('CreateAsset should have failed');
|
||||||
|
} catch(err) {
|
||||||
|
expect(err.name).to.equal('failed inserting key');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return success on CreateAsset', async () => {
|
||||||
|
let assetTransfer = new AssetTransfer();
|
||||||
|
|
||||||
|
await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue);
|
||||||
|
|
||||||
|
let ret = JSON.parse((await chaincodeStub.getState(asset.ID)).toString());
|
||||||
|
expect(ret).to.eql(asset);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Test ReadAsset', () => {
|
||||||
|
it('should return error on ReadAsset', async () => {
|
||||||
|
let assetTransfer = new AssetTransfer();
|
||||||
|
await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await assetTransfer.ReadAsset(transactionContext, 'asset2');
|
||||||
|
assert.fail('ReadAsset should have failed');
|
||||||
|
} catch (err) {
|
||||||
|
expect(err.message).to.equal('The asset asset2 does not exist');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return success on ReadAsset', async () => {
|
||||||
|
let assetTransfer = new AssetTransfer();
|
||||||
|
await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue);
|
||||||
|
|
||||||
|
let ret = JSON.parse(await chaincodeStub.getState(asset.ID));
|
||||||
|
expect(ret).to.eql(asset);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Test UpdateAsset', () => {
|
||||||
|
it('should return error on UpdateAsset', async () => {
|
||||||
|
let assetTransfer = new AssetTransfer();
|
||||||
|
await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await assetTransfer.UpdateAsset(transactionContext, 'asset2', 'orange', 10, 'Me', 500);
|
||||||
|
assert.fail('UpdateAsset should have failed');
|
||||||
|
} catch (err) {
|
||||||
|
expect(err.message).to.equal('The asset asset2 does not exist');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return success on UpdateAsset', async () => {
|
||||||
|
let assetTransfer = new AssetTransfer();
|
||||||
|
await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue);
|
||||||
|
|
||||||
|
await assetTransfer.UpdateAsset(transactionContext, 'asset1', 'orange', 10, 'Me', 500);
|
||||||
|
let ret = JSON.parse(await chaincodeStub.getState(asset.ID));
|
||||||
|
let expected = {
|
||||||
|
ID: 'asset1',
|
||||||
|
Color: 'orange',
|
||||||
|
Size: 10,
|
||||||
|
Owner: 'Me',
|
||||||
|
AppraisedValue: 500
|
||||||
|
};
|
||||||
|
expect(ret).to.eql(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Test DeleteAsset', () => {
|
||||||
|
it('should return error on DeleteAsset', async () => {
|
||||||
|
let assetTransfer = new AssetTransfer();
|
||||||
|
await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await assetTransfer.DeleteAsset(transactionContext, 'asset2');
|
||||||
|
assert.fail('DeleteAsset should have failed');
|
||||||
|
} catch (err) {
|
||||||
|
expect(err.message).to.equal('The asset asset2 does not exist');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return success on DeleteAsset', async () => {
|
||||||
|
let assetTransfer = new AssetTransfer();
|
||||||
|
await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue);
|
||||||
|
|
||||||
|
await assetTransfer.DeleteAsset(transactionContext, asset.ID);
|
||||||
|
let ret = await chaincodeStub.getState(asset.ID);
|
||||||
|
expect(ret).to.equal(undefined);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Test TransferAsset', () => {
|
||||||
|
it('should return error on TransferAsset', async () => {
|
||||||
|
let assetTransfer = new AssetTransfer();
|
||||||
|
await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await assetTransfer.TransferAsset(transactionContext, 'asset2', 'Me');
|
||||||
|
assert.fail('DeleteAsset should have failed');
|
||||||
|
} catch (err) {
|
||||||
|
expect(err.message).to.equal('The asset asset2 does not exist');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return success on TransferAsset', async () => {
|
||||||
|
let assetTransfer = new AssetTransfer();
|
||||||
|
await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue);
|
||||||
|
|
||||||
|
await assetTransfer.TransferAsset(transactionContext, asset.ID, 'Me');
|
||||||
|
let ret = JSON.parse((await chaincodeStub.getState(asset.ID)).toString());
|
||||||
|
expect(ret).to.eql(Object.assign({}, asset, {Owner: 'Me'}));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Test GetAllAssets', () => {
|
||||||
|
it('should return success on GetAllAssets', async () => {
|
||||||
|
let assetTransfer = new AssetTransfer();
|
||||||
|
|
||||||
|
await assetTransfer.CreateAsset(transactionContext, 'asset1', 'blue', 5, 'Robert', 100);
|
||||||
|
await assetTransfer.CreateAsset(transactionContext, 'asset2', 'orange', 10, 'Paul', 200);
|
||||||
|
await assetTransfer.CreateAsset(transactionContext, 'asset3', 'red', 15, 'Troy', 300);
|
||||||
|
await assetTransfer.CreateAsset(transactionContext, 'asset4', 'pink', 20, 'Van', 400);
|
||||||
|
|
||||||
|
let ret = await assetTransfer.GetAllAssets(transactionContext);
|
||||||
|
ret = JSON.parse(ret);
|
||||||
|
expect(ret.length).to.equal(4);
|
||||||
|
|
||||||
|
let expected = [
|
||||||
|
{Record: {ID: 'asset1', Color: 'blue', Size: 5, Owner: 'Robert', AppraisedValue: 100}},
|
||||||
|
{Record: {ID: 'asset2', Color: 'orange', Size: 10, Owner: 'Paul', AppraisedValue: 200}},
|
||||||
|
{Record: {ID: 'asset3', Color: 'red', Size: 15, Owner: 'Troy', AppraisedValue: 300}},
|
||||||
|
{Record: {ID: 'asset4', Color: 'pink', Size: 20, Owner: 'Van', AppraisedValue: 400}}
|
||||||
|
];
|
||||||
|
|
||||||
|
expect(ret).to.eql(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return success on GetAllAssets for non JSON value', async () => {
|
||||||
|
let assetTransfer = new AssetTransfer();
|
||||||
|
|
||||||
|
chaincodeStub.putState.onFirstCall().callsFake((key, value) => {
|
||||||
|
if (!chaincodeStub.states) {
|
||||||
|
chaincodeStub.states = {};
|
||||||
|
}
|
||||||
|
chaincodeStub.states[key] = 'non-json-value';
|
||||||
|
});
|
||||||
|
|
||||||
|
await assetTransfer.CreateAsset(transactionContext, 'asset1', 'blue', 5, 'Robert', 100);
|
||||||
|
await assetTransfer.CreateAsset(transactionContext, 'asset2', 'orange', 10, 'Paul', 200);
|
||||||
|
await assetTransfer.CreateAsset(transactionContext, 'asset3', 'red', 15, 'Troy', 300);
|
||||||
|
await assetTransfer.CreateAsset(transactionContext, 'asset4', 'pink', 20, 'Van', 400);
|
||||||
|
|
||||||
|
let ret = await assetTransfer.GetAllAssets(transactionContext);
|
||||||
|
ret = JSON.parse(ret);
|
||||||
|
expect(ret.length).to.equal(4);
|
||||||
|
|
||||||
|
let expected = [
|
||||||
|
{Record: 'non-json-value'},
|
||||||
|
{Record: {ID: 'asset2', Color: 'orange', Size: 10, Owner: 'Paul', AppraisedValue: 200}},
|
||||||
|
{Record: {ID: 'asset3', Color: 'red', Size: 15, Owner: 'Troy', AppraisedValue: 300}},
|
||||||
|
{Record: {ID: 'asset4', Color: 'pink', Size: 20, Owner: 'Van', AppraisedValue: 400}}
|
||||||
|
];
|
||||||
|
|
||||||
|
expect(ret).to.eql(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
#
|
||||||
|
|
||||||
|
coverage
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
env: {
|
||||||
|
node: true,
|
||||||
|
mocha: true
|
||||||
|
},
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 8,
|
||||||
|
sourceType: 'script'
|
||||||
|
},
|
||||||
|
extends: 'eslint:recommended',
|
||||||
|
rules: {
|
||||||
|
indent: ['error', 'tab'],
|
||||||
|
'linebreak-style': ['error', 'unix'],
|
||||||
|
quotes: ['error', 'single'],
|
||||||
|
semi: ['error', 'always'],
|
||||||
|
'no-unused-vars': ['error', { args: 'none' }],
|
||||||
|
'no-console': 'off',
|
||||||
|
curly: 'error',
|
||||||
|
eqeqeq: 'error',
|
||||||
|
'no-throw-literal': 'error',
|
||||||
|
strict: 'error',
|
||||||
|
'no-var': 'error',
|
||||||
|
'dot-notation': 'error',
|
||||||
|
'no-trailing-spaces': 'error',
|
||||||
|
'no-use-before-define': 'error',
|
||||||
|
'no-useless-call': 'error',
|
||||||
|
'no-with': 'error',
|
||||||
|
'operator-linebreak': 'error',
|
||||||
|
yoda: 'error',
|
||||||
|
'quote-props': ['error', 'as-needed']
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -67,30 +67,32 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const { Contract } = require('fabric-contract-api');
|
const {Contract} = require('fabric-contract-api');
|
||||||
|
|
||||||
class Chaincode extends Contract{
|
class Chaincode extends Contract {
|
||||||
|
|
||||||
// CreateAsset - create a new asset, store into chaincode state
|
// CreateAsset - create a new asset, store into chaincode state
|
||||||
async CreateAsset(ctx, assetID, color, size, owner, appraisedValue) {
|
async CreateAsset(ctx, assetID, color, size, owner, appraisedValue) {
|
||||||
const exists = await this.AssetExists(ctx, assetID)
|
const exists = await this.AssetExists(ctx, assetID);
|
||||||
if (exists) {
|
if (exists) {
|
||||||
throw new Error(`The asset ${assetID} already exists`)
|
throw new Error(`The asset ${assetID} already exists`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==== Create asset object and marshal to JSON ====
|
// ==== Create asset object and marshal to JSON ====
|
||||||
let asset = {};
|
let asset = {
|
||||||
asset.docType = 'asset';
|
docType: 'asset',
|
||||||
asset.ID = assetID;
|
assetID: assetID,
|
||||||
asset.color = color;
|
color: color,
|
||||||
asset.size = size;
|
size: size,
|
||||||
asset.owner = owner;
|
owner: owner,
|
||||||
asset.appraisedValue = appraisedValue;
|
appraisedValue: appraisedValue
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// === Save asset to state ===
|
// === Save asset to state ===
|
||||||
await ctx.stub.putState(assetID, Buffer.from(JSON.stringify(asset)));
|
await ctx.stub.putState(assetID, Buffer.from(JSON.stringify(asset)));
|
||||||
let indexName = 'color~name'
|
let indexName = 'color~name';
|
||||||
let colorNameIndexKey = await ctx.stub.createCompositeKey(indexName, [asset.color, asset.ID]);
|
let colorNameIndexKey = await ctx.stub.createCompositeKey(indexName, [asset.color, asset.assetID]);
|
||||||
|
|
||||||
// Save index entry to state. Only the key name is needed, no need to store a duplicate copy of the marble.
|
// Save index entry to state. Only the key name is needed, no need to store a duplicate copy of the marble.
|
||||||
// Note - passing a 'nil' value will effectively delete the key from state, therefore we pass null character as value
|
// Note - passing a 'nil' value will effectively delete the key from state, therefore we pass null character as value
|
||||||
|
|
@ -113,31 +115,31 @@ class Chaincode extends Contract{
|
||||||
throw new Error('Asset name must not be empty');
|
throw new Error('Asset name must not be empty');
|
||||||
}
|
}
|
||||||
|
|
||||||
var exists = await this.AssetExists(ctx, id)
|
let exists = await this.AssetExists(ctx, id);
|
||||||
if (!exists) {
|
if (!exists) {
|
||||||
throw new Error(`Asset ${id} does not exist`)
|
throw new Error(`Asset ${id} does not exist`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// to maintain the color~name index, we need to read the asset first and get its color
|
// to maintain the color~name index, we need to read the asset first and get its color
|
||||||
let valAsbytes = await ctx.stub.getState(id); // get the asset from chaincode state
|
let valAsbytes = await ctx.stub.getState(id); // get the asset from chaincode state
|
||||||
let jsonResp = {};
|
let jsonResp = {};
|
||||||
if (!valAsbytes) {
|
if (!valAsbytes) {
|
||||||
jsonResp.error = 'Asset does not exist: ' + name;
|
jsonResp.error = `Asset does not exist: ${id}`;
|
||||||
throw new Error(jsonResp);
|
throw new Error(jsonResp);
|
||||||
}
|
}
|
||||||
let assetJSON = {};
|
let assetJSON;
|
||||||
try {
|
try {
|
||||||
assetJSON = JSON.parse(valAsbytes.toString());
|
assetJSON = JSON.parse(valAsbytes.toString());
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
jsonResp = {};
|
jsonResp = {};
|
||||||
jsonResp.error = 'Failed to decode JSON of: ' + id;
|
jsonResp.error = `Failed to decode JSON of: ${id}`;
|
||||||
throw new Error(jsonResp);
|
throw new Error(jsonResp);
|
||||||
}
|
}
|
||||||
await ctx.stub.deleteState(id); //remove the asset from chaincode state
|
await ctx.stub.deleteState(id); //remove the asset from chaincode state
|
||||||
|
|
||||||
// delete the index
|
// delete the index
|
||||||
let indexName = 'color~name';
|
let indexName = 'color~name';
|
||||||
let colorNameIndexKey = ctx.stub.createCompositeKey(indexName, [assetJSON.color, assetJSON.ID]);
|
let colorNameIndexKey = ctx.stub.createCompositeKey(indexName, [assetJSON.color, assetJSON.assetID]);
|
||||||
if (!colorNameIndexKey) {
|
if (!colorNameIndexKey) {
|
||||||
throw new Error(' Failed to create the createCompositeKey');
|
throw new Error(' Failed to create the createCompositeKey');
|
||||||
}
|
}
|
||||||
|
|
@ -145,7 +147,7 @@ class Chaincode extends Contract{
|
||||||
await ctx.stub.deleteState(colorNameIndexKey);
|
await ctx.stub.deleteState(colorNameIndexKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TransferAsset transfers an asset by setting a new owner name on the asset
|
// TransferAsset transfers a asset by setting a new owner name on the asset
|
||||||
async TransferAsset(ctx, assetName, newOwner) {
|
async TransferAsset(ctx, assetName, newOwner) {
|
||||||
|
|
||||||
let assetAsBytes = await ctx.stub.getState(assetName);
|
let assetAsBytes = await ctx.stub.getState(assetName);
|
||||||
|
|
@ -166,14 +168,14 @@ class Chaincode extends Contract{
|
||||||
await ctx.stub.putState(assetName, assetJSONasBytes); //rewrite the asset
|
await ctx.stub.putState(assetName, assetJSONasBytes); //rewrite the asset
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAssetsByRange performs a range query based on the start and end keys provided.
|
// GetAssetsByRange performs a range query based on the start and end keys provided.
|
||||||
// Read-only function results are not typically submitted to ordering. If the read-only
|
// Read-only function results are not typically submitted to ordering. If the read-only
|
||||||
// results are submitted to ordering, or if the query is used in an update transaction
|
// results are submitted to ordering, or if the query is used in an update transaction
|
||||||
// and submitted to ordering, then the committing peers will re-execute to guarantee that
|
// and submitted to ordering, then the committing peers will re-execute to guarantee that
|
||||||
// result sets are stable between endorsement time and commit time. The transaction is
|
// result sets are stable between endorsement time and commit time. The transaction is
|
||||||
// invalidated by the committing peers if the result set has changed between endorsement
|
// invalidated by the committing peers if the result set has changed between endorsement
|
||||||
// time and commit time.
|
// time and commit time.
|
||||||
// Therefore, range queries are a safe option for performing update transactions based on query results.
|
// Therefore, range queries are a safe option for performing update transactions based on query results.
|
||||||
async GetAssetsByRange(ctx, startKey, endKey) {
|
async GetAssetsByRange(ctx, startKey, endKey) {
|
||||||
|
|
||||||
let resultsIterator = await ctx.stub.getStateByRange(startKey, endKey);
|
let resultsIterator = await ctx.stub.getStateByRange(startKey, endKey);
|
||||||
|
|
@ -195,25 +197,25 @@ class Chaincode extends Contract{
|
||||||
let coloredAssetResultsIterator = await ctx.stub.getStateByPartialCompositeKey('color~name', [color]);
|
let coloredAssetResultsIterator = await ctx.stub.getStateByPartialCompositeKey('color~name', [color]);
|
||||||
|
|
||||||
// Iterate through result set and for each asset found, transfer to newOwner
|
// Iterate through result set and for each asset found, transfer to newOwner
|
||||||
while (true) {
|
|
||||||
let responseRange = await coloredAssetResultsIterator.next();
|
let responseRange = await coloredAssetResultsIterator.next();
|
||||||
|
while (!responseRange.done) {
|
||||||
if (!responseRange || !responseRange.value || !responseRange.value.key) {
|
if (!responseRange || !responseRange.value || !responseRange.value.key) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let objectType;
|
let objectType;
|
||||||
let attributes;
|
let attributes;
|
||||||
({
|
(
|
||||||
objectType,
|
{objectType, attributes} = await ctx.stub.splitCompositeKey(responseRange.value.key)
|
||||||
attributes
|
);
|
||||||
} = await ctx.stub.splitCompositeKey(responseRange.value.key));
|
|
||||||
|
|
||||||
console.log(objectType)
|
console.log(objectType);
|
||||||
let returnedAssetName = attributes[1];
|
let returnedAssetName = attributes[1];
|
||||||
|
|
||||||
// Now call the transfer function for the found asset.
|
// Now call the transfer function for the found asset.
|
||||||
// Re-use the same function that is used to transfer individual assets
|
// Re-use the same function that is used to transfer individual assets
|
||||||
await this.TransferAsset(ctx, returnedAssetName, newOwner);
|
await this.TransferAsset(ctx, returnedAssetName, newOwner);
|
||||||
|
responseRange = await coloredAssetResultsIterator.next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -227,8 +229,7 @@ class Chaincode extends Contract{
|
||||||
queryString.selector = {};
|
queryString.selector = {};
|
||||||
queryString.selector.docType = 'asset';
|
queryString.selector.docType = 'asset';
|
||||||
queryString.selector.owner = owner;
|
queryString.selector.owner = owner;
|
||||||
let queryResults = await this.GetQueryResultForQueryString(ctx, JSON.stringify(queryString));
|
return await this.GetQueryResultForQueryString(ctx, JSON.stringify(queryString)); //shim.success(queryResults);
|
||||||
return queryResults; //shim.success(queryResults);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Example: Ad hoc rich query
|
// Example: Ad hoc rich query
|
||||||
|
|
@ -238,8 +239,7 @@ class Chaincode extends Contract{
|
||||||
// If this is not desired, follow the QueryAssetsForOwner example for parameterized queries.
|
// If this is not desired, follow the QueryAssetsForOwner example for parameterized queries.
|
||||||
// Only available on state databases that support rich query (e.g. CouchDB)
|
// Only available on state databases that support rich query (e.g. CouchDB)
|
||||||
async QueryAssets(ctx, queryString) {
|
async QueryAssets(ctx, queryString) {
|
||||||
let queryResults = await this.GetQueryResultForQueryString(ctx, queryString);
|
return await this.GetQueryResultForQueryString(ctx, queryString);
|
||||||
return queryResults;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetQueryResultForQueryString executes the passed in query string.
|
// GetQueryResultForQueryString executes the passed in query string.
|
||||||
|
|
@ -259,7 +259,7 @@ class Chaincode extends Contract{
|
||||||
// Paginated range queries are only valid for read only transactions.
|
// Paginated range queries are only valid for read only transactions.
|
||||||
async GetAssetsByRangeWithPagination(ctx, startKey, endKey, pageSize, bookmark) {
|
async GetAssetsByRangeWithPagination(ctx, startKey, endKey, pageSize, bookmark) {
|
||||||
|
|
||||||
const { iterator, metadata } = await ctx.stub.getStateByRangeWithPagination(startKey, endKey, pageSize, bookmark);
|
const {iterator, metadata} = await ctx.stub.getStateByRangeWithPagination(startKey, endKey, pageSize, bookmark);
|
||||||
const results = await this.GetAllResults(iterator, false);
|
const results = await this.GetAllResults(iterator, false);
|
||||||
|
|
||||||
results.ResponseMetadata = {
|
results.ResponseMetadata = {
|
||||||
|
|
@ -279,7 +279,7 @@ class Chaincode extends Contract{
|
||||||
// Paginated queries are only valid for read only transactions.
|
// Paginated queries are only valid for read only transactions.
|
||||||
async QueryAssetsWithPagination(ctx, queryString, pageSize, bookmark) {
|
async QueryAssetsWithPagination(ctx, queryString, pageSize, bookmark) {
|
||||||
|
|
||||||
const { iterator, metadata } = await ctx.stub.getQueryResultWithPagination(queryString, pageSize, bookmark);
|
const {iterator, metadata} = await ctx.stub.getQueryResultWithPagination(queryString, pageSize, bookmark);
|
||||||
const results = await this.GetAllResults(iterator, false);
|
const results = await this.GetAllResults(iterator, false);
|
||||||
|
|
||||||
results.ResponseMetadata = {
|
results.ResponseMetadata = {
|
||||||
|
|
@ -293,8 +293,8 @@ class Chaincode extends Contract{
|
||||||
// GetAssetHistory returns the chain of custody for an asset since issuance.
|
// GetAssetHistory returns the chain of custody for an asset since issuance.
|
||||||
async GetAssetHistory(ctx, assetName) {
|
async GetAssetHistory(ctx, assetName) {
|
||||||
|
|
||||||
const resultsIterator = await ctx.stub.getHistoryForKey(assetName);
|
let resultsIterator = await ctx.stub.getHistoryForKey(assetName);
|
||||||
const results = await this.GetAllResults(resultsIterator, true);
|
let results = await this.GetAllResults(resultsIterator, true);
|
||||||
|
|
||||||
return JSON.stringify(results);
|
return JSON.stringify(results);
|
||||||
}
|
}
|
||||||
|
|
@ -302,39 +302,40 @@ class Chaincode extends Contract{
|
||||||
// AssetExists returns true when asset with given ID exists in world state
|
// AssetExists returns true when asset with given ID exists in world state
|
||||||
async AssetExists(ctx, assetName) {
|
async AssetExists(ctx, assetName) {
|
||||||
// ==== Check if asset already exists ====
|
// ==== Check if asset already exists ====
|
||||||
const assetState = await ctx.stub.getState(assetName);
|
let assetState = await ctx.stub.getState(assetName);
|
||||||
if ( !assetState || assetState.length === 0 ) {
|
return assetState && assetState.length > 0;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async GetAllResults(iterator, isHistory) {
|
async GetAllResults(iterator, isHistory) {
|
||||||
const allResults = [];
|
let allResults = [];
|
||||||
let res = await iterator.next();
|
let res = await iterator.next();
|
||||||
while (!res.done) {
|
while (!res.done) {
|
||||||
const jsonRes = {};
|
if (res.value && res.value.value.toString()) {
|
||||||
|
let jsonRes = {};
|
||||||
if (isHistory) {
|
console.log(res.value.value.toString('utf8'));
|
||||||
jsonRes.TxId = res.value.txId;
|
if (isHistory && isHistory === true) {
|
||||||
|
jsonRes.TxId = res.value.tx_id;
|
||||||
jsonRes.Timestamp = res.value.timestamp;
|
jsonRes.Timestamp = res.value.timestamp;
|
||||||
jsonRes.IsDelete = res.value.isDelete;
|
try {
|
||||||
|
jsonRes.Value = JSON.parse(res.value.value.toString('utf8'));
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
jsonRes.Value = res.value.value.toString('utf8');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res.value.value.length > 0) {
|
|
||||||
jsonRes.Record = JSON.parse(res.value.value.toString('utf8'));
|
|
||||||
} else {
|
} else {
|
||||||
jsonRes.Record = {ID: res.value.key};
|
|
||||||
}
|
|
||||||
|
|
||||||
jsonRes.Key = res.value.key;
|
jsonRes.Key = res.value.key;
|
||||||
|
try {
|
||||||
console.log('Result: ' + JSON.stringify(jsonRes));
|
jsonRes.Record = JSON.parse(res.value.value.toString('utf8'));
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
jsonRes.Record = res.value.value.toString('utf8');
|
||||||
|
}
|
||||||
|
}
|
||||||
allResults.push(jsonRes);
|
allResults.push(jsonRes);
|
||||||
|
}
|
||||||
res = await iterator.next();
|
res = await iterator.next();
|
||||||
}
|
}
|
||||||
|
iterator.close();
|
||||||
await iterator.close();
|
|
||||||
return allResults;
|
return allResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -342,42 +343,42 @@ class Chaincode extends Contract{
|
||||||
async InitLedger(ctx) {
|
async InitLedger(ctx) {
|
||||||
const assets = [
|
const assets = [
|
||||||
{
|
{
|
||||||
ID: 'asset1',
|
assetID: 'asset1',
|
||||||
color: 'blue',
|
color: 'blue',
|
||||||
size: 5,
|
size: 5,
|
||||||
owner: 'Tom',
|
owner: 'Tom',
|
||||||
appraisedValue: 100
|
appraisedValue: 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: 'asset2',
|
assetID: 'asset2',
|
||||||
color: 'red',
|
color: 'red',
|
||||||
size: 5,
|
size: 5,
|
||||||
owner: 'Brad',
|
owner: 'Brad',
|
||||||
appraisedValue: 100
|
appraisedValue: 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: 'asset3',
|
assetID: 'asset3',
|
||||||
color: 'green',
|
color: 'green',
|
||||||
size: 10,
|
size: 10,
|
||||||
owner: 'Jin Soo',
|
owner: 'Jin Soo',
|
||||||
appraisedValue: 200
|
appraisedValue: 200
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: 'asset4',
|
assetID: 'asset4',
|
||||||
color: 'yellow',
|
color: 'yellow',
|
||||||
size: 10,
|
size: 10,
|
||||||
owner: 'Max',
|
owner: 'Max',
|
||||||
appraisedValue: 200
|
appraisedValue: 200
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: 'asset5',
|
assetID: 'asset5',
|
||||||
color: 'black',
|
color: 'black',
|
||||||
size: 15,
|
size: 15,
|
||||||
owner: 'Adriana',
|
owner: 'Adriana',
|
||||||
appraisedValue: 250
|
appraisedValue: 250
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: 'asset6',
|
assetID: 'asset6',
|
||||||
color: 'white',
|
color: 'white',
|
||||||
size: 15,
|
size: 15,
|
||||||
owner: 'Michel',
|
owner: 'Michel',
|
||||||
|
|
@ -385,14 +386,14 @@ class Chaincode extends Contract{
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
for (let i = 0; i < assets.length; i++) {
|
for (let asset in assets) {
|
||||||
await this.CreateAsset(
|
await this.CreateAsset(
|
||||||
ctx,
|
ctx,
|
||||||
assets[i].ID,
|
asset.assetID,
|
||||||
assets[i].color,
|
asset.color,
|
||||||
assets[i].size,
|
asset.size,
|
||||||
assets[i].owner,
|
asset.owner,
|
||||||
assets[i].appraisedValue
|
asset.appraisedValue
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,7 @@ async function main() {
|
||||||
let asset2Data = { objectType: assetType, assetID: assetID2, color: 'blue', size: 35, appraisedValue: 727 };
|
let asset2Data = { objectType: assetType, assetID: assetID2, color: 'blue', size: 35, appraisedValue: 727 };
|
||||||
|
|
||||||
console.log('\n**************** As Org1 Client ****************');
|
console.log('\n**************** As Org1 Client ****************');
|
||||||
console.log('Adding Assets to work with: Submit Transaction: CreateAsset ' + assetID1);
|
console.log('Adding Assets to work with:\n--> Submit Transaction: CreateAsset ' + assetID1);
|
||||||
let statefulTxn = contractOrg1.createTransaction('CreateAsset');
|
let statefulTxn = contractOrg1.createTransaction('CreateAsset');
|
||||||
//if you need to customize endorsement to specific set of Orgs, use setEndorsingOrganizations
|
//if you need to customize endorsement to specific set of Orgs, use setEndorsingOrganizations
|
||||||
//statefulTxn.setEndorsingOrganizations(mspOrg1);
|
//statefulTxn.setEndorsingOrganizations(mspOrg1);
|
||||||
|
|
|
||||||
|
|
@ -147,7 +147,6 @@ func (s *SmartContract) QueryAssetByOwner(ctx contractapi.TransactionContextInte
|
||||||
return queryResults, nil
|
return queryResults, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// QueryAssets uses a query string to perform a query for assets.
|
// QueryAssets uses a query string to perform a query for assets.
|
||||||
// Query string matching state database syntax is passed in and executed as is.
|
// Query string matching state database syntax is passed in and executed as is.
|
||||||
// Supports ad hoc queries that can be defined at runtime by the client.
|
// Supports ad hoc queries that can be defined at runtime by the client.
|
||||||
|
|
|
||||||
|
|
@ -1,55 +1,135 @@
|
||||||
# Sample to demonstrate State-Based Endorsements (SBE)
|
# State-based endorsement asset transfer sample
|
||||||
|
|
||||||
## Introduction to SBE
|
Transactions that are submitted to Hyperledger Fabric networks need to be endorsed by peers that are joined to a channel before the transaction can be added to the ledger. Fabric peers endorse transactions by executing a smart contract using the inputs of the transaction proposal. The peers then sign the input and output generated by the smart contract execution. The endorsement policy specifies the set of organizations whose peers need to endorse a transaction before it can be added to the ledger.
|
||||||
Fabric allows different ways to set endorsements for transactions on the network. The default method is specified in chaincode definition, which is agreed by channel members and committed to the channel. However, there are cases where it may be necessary for a particular Key (public channel state or private data collection state) to have a different endorsement policy. State-Based endorsement allows endorsement policies to be overridden for the specified Key's. State-Based Endorsements are also known as Key Level Endorsements. To learn more about endorsement policies and State-Based endorsements, visit the [Fabric Endorsement Policies documentation](https://hyperledger-fabric.readthedocs.io/en/master/endorsement-policies.html).
|
|
||||||
|
Each chaincode that is deployed to a channel has an endorsement policy that governs the assets managed by the chaincode smart contracts. However, you can override the chaincode level endorsement policy to create an endorsement policy for a specific key, either on the public channel ledger or in a private collection. State-based endorsement policies, also known as key-level endorsement policies, allow channel members use different endorsement policies for assets that are managed by the same smart contract. For more information about endorsement policies and state-based endorsement, visit the [Endorsement Policies](https://hyperledger-fabric.readthedocs.io/en/master/endorsement-policies.html) topic in the Fabric documentation.
|
||||||
|
|
||||||
|
## About the Sample
|
||||||
|
|
||||||
|
The state-based endorsement (SBE) asset transfer sample demonstrates how to use key-level endorsement policies to ensure that an asset only needs to be endorsed by an asset owner. In the course of the tutorial, you will use the smart contract to complete the following transfer scenario:
|
||||||
|
|
||||||
|
- Deploy the SBE smart contract to a channel that was created using the Fabric test network. The channel will have two members, Org1 and Org2, that will participate in the asset transfer. Each organization operates one peer that is joined to the channel.
|
||||||
|
- Create an asset using the chaincode endorsement policy. The chaincode level endorsement policy requires that a majority of organizations on the channel to endorse a transaction. As a result, the transaction that creates the asset needs to be endorsed by peers that belong to Org1 and Org2. When the asset is created, the smart contract creates a state-based endorsement policy that specifies that only the organization that owns that asset needs to endorse any asset updates. Because the asset is owned by Org1, any future updates to the asset need to be endorsed by the Org1 peer.
|
||||||
|
- Update the asset using the state-based endorsement policy.
|
||||||
|
- Transfer the asset to Org2. The transfer transaction will create a new state-based endorsement policy that reflects the new asset owner.
|
||||||
|
- Update the asset once more, this time with Org2 as the owner. Because the state-based endorsement policy has been updated, this transaction only needs to be endorsed by Org2.
|
||||||
|
|
||||||
|
|
||||||
Fabric Shim Method's for State-Based endorsements (below references from fabric-shim, ChaincodeStub for Node):
|
## Deploy the smart contract
|
||||||
- setStateValidationParameter(key: string, ep: Uint8Array): Promise<void>;
|
|
||||||
- getStateValidationParameter(key: string): Promise<Uint8Array>;
|
|
||||||
- setPrivateDataValidationParameter(collection: string, key: string, ep: Uint8Array): Promise<void>;
|
|
||||||
- getPrivateDataValidationParameter(collection: string, key: string): Promise<Uint8Array>;
|
|
||||||
|
|
||||||
|
We are going to run the SBE smart contract using the Fabric test network. Open a command terminal and navigate to test network directory in your local clone of the `fabric-samples`. We will operate from the `test-network` directory for the remainder of the tutorial.
|
||||||
|
```
|
||||||
|
cd fabric-samples/test-network
|
||||||
|
```
|
||||||
|
|
||||||
## About the SBE Asset Transfer Sample
|
Run the following command to deploy the test network and create a channel named `mychannel`:
|
||||||
Using this sample we demonstrate State-Based Endorsements (SBE), and set a different endorsement policy for a specified Key, instead of the default chaincode policy. This sample is deployed and demonstrated on the fabric-samples, Test network (2 Org network, Org1 and Org2). The endorsement policy for chaincodes deployed in this network defaults to majority, that is both Org's need to endorse transactions on the network. To bootstrap the Test Network, and deploy the SBE Asset Transfer Sample chaincode, visit the [Test Network documentation](https://hyperledger-fabric.readthedocs.io/en/latest/test_network.html).
|
|
||||||
|
|
||||||
This sample demonstrates modifying the default chaincode policy (requiring endorsements from both Org Peers), and changing it to a less restrictive policy requiring endorsement only from a specific Org Peer for the specified Key. Endorsements can also be modified to be more restrictive for a particular Key in a similar way.
|
```
|
||||||
|
./network.sh up createChannel
|
||||||
|
```
|
||||||
|
|
||||||
On Asset creation, State-Based endorsements for the Asset Key is set to either Org1 or Org2 Peer, depending on the client Org creating the Asset. Creation of Asset still needs the default chaincode endorsement policy, and hence will need to be endorsed by both Org's (Org1 & Org2). However, all future updates for the Asset Key will use the modified endorsements as per the State-Based endorsements set during Asset creation.
|
You can use the test network script to deploy the smart contract to the channel that was just created. The script uses the Fabric chaincode lifecycle to deploy the smart contract to the channel. We will use the default chaincode level endorsement policy used by the Fabric chaincode lifecycle, which requires an endorsement from a majority of channel members. In our case, this will require that both Org1 and Org2 endorse a transaction (2 of 2). Deploy the smart contract to `mychannel` using the following command:
|
||||||
|
```
|
||||||
|
./network.sh deployCC -ccn sbe -ccl typescript
|
||||||
|
```
|
||||||
|
|
||||||
Hence transactions like UpdateAsset or TransferAsset will not succeed if endorsed by the non-owner Org Peer.
|
Set the following environment variables to interact with the network as a user from Org1:
|
||||||
|
|
||||||
Sample invokations to demonstrate State-Based Endorsements (SBE) on test-network, using client identity of Org1
|
```
|
||||||
* Create Asset (requires Org1 & Org2 Peer to endorse as per the default chaincode endorsement policy, however future updates will need only Org1 Peer to endorse, as the State-Based endorsement policy is set for assetId Key during the createAsset transaction)
|
export PATH=${PWD}/../bin:${PWD}:$PATH
|
||||||
```bash
|
export FABRIC_CFG_PATH=$PWD/../config/
|
||||||
|
export CORE_PEER_TLS_ENABLED=true
|
||||||
|
export CORE_PEER_LOCALMSPID="Org1MSP"
|
||||||
|
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp
|
||||||
|
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
|
||||||
|
export CORE_PEER_ADDRESS=localhost:7051
|
||||||
|
```
|
||||||
|
|
||||||
|
## Run the transfer scenario
|
||||||
|
|
||||||
|
We can now invoke the SBE smart contract to create a new asset:
|
||||||
|
```
|
||||||
peer chaincode invoke -o localhost:7050 --waitForEvent --ordererTLSHostnameOverride orderer.example.com --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n sbe --peerAddresses localhost:7051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"function":"CreateAsset","Args":["asset1","100","Org1User1"]}'
|
peer chaincode invoke -o localhost:7050 --waitForEvent --ordererTLSHostnameOverride orderer.example.com --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n sbe --peerAddresses localhost:7051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"function":"CreateAsset","Args":["asset1","100","Org1User1"]}'
|
||||||
```
|
```
|
||||||
* Read & Verify Asset (Use this to verify changes for UpdateAsset & TransferAsset)
|
The create transaction needs to target both peers from Org1 and Org2 to meet the chaincode endorsement policy. The chaincode will read the MSP ID of the client user submitting the transaction and assign that organization as the asset owner. As a result, the asset will initially be owned by Org1.
|
||||||
```bash
|
|
||||||
|
You can query the asset using with the following command:
|
||||||
|
```
|
||||||
peer chaincode query -C mychannel -n sbe -c '{"Args":["ReadAsset","asset1"]}'
|
peer chaincode query -C mychannel -n sbe -c '{"Args":["ReadAsset","asset1"]}'
|
||||||
```
|
```
|
||||||
* Update Asset (requires Org1 Peer to endorse as per SBE specified for assetId Key, but since Org2 Peer is endorsing it will result in ENDORSEMENT_POLICY_FAILURE by the peer during endorsement validations for the transaction)
|
The result is a new asset owned by Org1, identified using the Org1 MSP ID `Org1MSP`:
|
||||||
```bash
|
`{"ID":"asset1","Value":100,"Owner":"Org1User1","OwnerOrg":"Org1MSP"}`
|
||||||
|
|
||||||
|
In addition to creating the asset, the `CreateAsset` function also sets a state-based endorsement policy for the asset. Only a peer of the asset owner, can successfully endorse an asset update. To demonstrate the key-level endorsement policy, lets try to update the asset while targeting the Org2 peer:
|
||||||
|
```
|
||||||
peer chaincode invoke -o localhost:7050 --waitForEvent --ordererTLSHostnameOverride orderer.example.com --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n sbe --peerAddresses localhost:9051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"function":"UpdateAsset","Args":["asset1","200"]}'
|
peer chaincode invoke -o localhost:7050 --waitForEvent --ordererTLSHostnameOverride orderer.example.com --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n sbe --peerAddresses localhost:9051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"function":"UpdateAsset","Args":["asset1","200"]}'
|
||||||
```
|
```
|
||||||
* Update Asset succeeds (requires Org1 Peer to endorse as per SBE specified for assetId Key, and Org1 Peer is endorsing here)
|
The result is an endorsement policy failure:
|
||||||
```bash
|
```
|
||||||
|
Error: transaction invalidated with status (ENDORSEMENT_POLICY_FAILURE) - proposal response: <nil>
|
||||||
|
```
|
||||||
|
|
||||||
|
If we attempt to update the asset with an endorsement from the Org1 peer, the update succeeds:
|
||||||
|
```
|
||||||
peer chaincode invoke -o localhost:7050 --waitForEvent --ordererTLSHostnameOverride orderer.example.com --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n sbe --peerAddresses localhost:7051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt -c '{"function":"UpdateAsset","Args":["asset1","200"]}'
|
peer chaincode invoke -o localhost:7050 --waitForEvent --ordererTLSHostnameOverride orderer.example.com --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n sbe --peerAddresses localhost:7051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt -c '{"function":"UpdateAsset","Args":["asset1","200"]}'
|
||||||
```
|
```
|
||||||
* Transfer Asset (requires Org1 Peer to endorse as per SBE specified for assetId Key, but since Org2 Peer is endorsing it will result in ENDORSEMENT_POLICY_FAILURE by the peer during endorsement validations for the transaction)
|
You can query the asset one more time to verify that the update was successful:
|
||||||
```bash
|
```
|
||||||
peer chaincode invoke -o localhost:7050 --waitForEvent --ordererTLSHostnameOverride orderer.example.com --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n sbe --peerAddresses localhost:9051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"function":"TransferAsset","Args":["asset1","Org2User1","Org2MSP"]}'
|
peer chaincode query -C mychannel -n sbe -c '{"Args":["ReadAsset","asset1"]}'
|
||||||
|
```
|
||||||
|
|
||||||
|
The asset value is now 200:
|
||||||
|
```
|
||||||
|
{"ID":"asset1","Value":200,"Owner":"Org1User1","OwnerOrg":"Org1MSP"}
|
||||||
|
```
|
||||||
|
|
||||||
|
Now that we have tested the asset key-level endorsement policy, we can transfer the asset to Org2. Run the following command to transfer the asset from Org1 to Org2. This time the Org2 MSP ID is provided as a transaction input. The `TransferAsset` function will update the endorsement policy to specify that only a peer of the new owner can update the asset. Note that this command targets the Org1 peer.
|
||||||
|
|
||||||
```
|
```
|
||||||
* Transfer Asset succeeds (requires Org1 Peer to endorse as per SBE specified for assetId Key, and Org1 Peer is endorsing here)
|
|
||||||
```bash
|
|
||||||
peer chaincode invoke -o localhost:7050 --waitForEvent --ordererTLSHostnameOverride orderer.example.com --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n sbe --peerAddresses localhost:7051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt -c '{"function":"TransferAsset","Args":["asset1","Org2User1","Org2MSP"]}'
|
peer chaincode invoke -o localhost:7050 --waitForEvent --ordererTLSHostnameOverride orderer.example.com --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n sbe --peerAddresses localhost:7051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt -c '{"function":"TransferAsset","Args":["asset1","Org2User1","Org2MSP"]}'
|
||||||
```
|
```
|
||||||
* Update Asset (now requires Org2 Peer to endorse as per SBE specified for assetId Key, but since Org1 Peer is endorsing it will result in ENDORSEMENT_POLICY_FAILURE by the peer during endorsement validations for the transaction)
|
|
||||||
```bash
|
We can query the asset to see that the owner has been updated from Org1 to Org2:
|
||||||
|
```
|
||||||
|
peer chaincode query -C mychannel -n sbe -c '{"Args":["ReadAsset","asset1"]}'
|
||||||
|
```
|
||||||
|
|
||||||
|
The owning organization is now Org2:
|
||||||
|
```
|
||||||
|
{"ID":"asset1","Value":200,"Owner":"Org2User1","OwnerOrg":"Org2MSP"}
|
||||||
|
```
|
||||||
|
|
||||||
|
Org2 now needs to endorse any asset updates. Run the following command to try to update the asset with an endorsement from the Org1 peer:
|
||||||
|
```
|
||||||
peer chaincode invoke -o localhost:7050 --waitForEvent --ordererTLSHostnameOverride orderer.example.com --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n sbe --peerAddresses localhost:7051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt -c '{"function":"UpdateAsset","Args":["asset1","300"]}'
|
peer chaincode invoke -o localhost:7050 --waitForEvent --ordererTLSHostnameOverride orderer.example.com --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n sbe --peerAddresses localhost:7051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt -c '{"function":"UpdateAsset","Args":["asset1","300"]}'
|
||||||
```
|
```
|
||||||
* Update Asset succeeds (requires Org2 Peer to endorse as per SBE specified for assetId Key, and Org2 Peer is endorsing here)
|
|
||||||
```bash
|
The response will be an endorsement policy failure:
|
||||||
|
```
|
||||||
|
Error: transaction invalidated with status (ENDORSEMENT_POLICY_FAILURE) - proposal response: <nil>
|
||||||
|
```
|
||||||
|
|
||||||
|
Now try to update the asset with an endorsement from the Org2 peer:
|
||||||
|
```
|
||||||
peer chaincode invoke -o localhost:7050 --waitForEvent --ordererTLSHostnameOverride orderer.example.com --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n sbe --peerAddresses localhost:9051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"function":"UpdateAsset","Args":["asset1","300"]}'
|
peer chaincode invoke -o localhost:7050 --waitForEvent --ordererTLSHostnameOverride orderer.example.com --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n sbe --peerAddresses localhost:9051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"function":"UpdateAsset","Args":["asset1","300"]}'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
You can query the asset again to verify that the transaction update succeeded:
|
||||||
|
```
|
||||||
|
peer chaincode query -C mychannel -n sbe -c '{"Args":["ReadAsset","asset1"]}'
|
||||||
|
```
|
||||||
|
|
||||||
|
The asset value is now 300:
|
||||||
|
```
|
||||||
|
{"ID":"asset1","Value":300,"Owner":"Org2User1","OwnerOrg":"Org2MSP"}
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that the transaction to update the asset was submitted by a user from Org1, even though the asset was owned by Org2. The transfer enabled by the SBE smart contract is a simple scenario meant only to demonstrate the use of state-based endorsement policies. The smart contract can use access control to specify that an asset can only be updated by its owner. Private data collections can also be used to ensure that transfers need to be endorsed by the owner and recipient of the transfer, instead of just the asset owner. For a more realistic example of an asset transfer scenario, see the [Secured asset transfer in Fabric](https://hyperledger-fabric.readthedocs.io/en/master/secured_asset_transfer/secured_private_asset_transfer_tutorial.html) tutorial.
|
||||||
|
|
||||||
|
## Clean up
|
||||||
|
|
||||||
|
When you are finished, you can bring down the test network. The command will remove all the nodes of the test network, and delete any ledger data that you created:
|
||||||
|
|
||||||
|
```
|
||||||
|
./network.sh down
|
||||||
|
```
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ import { Object, Property } from 'fabric-contract-api';
|
||||||
|
|
||||||
@Object()
|
@Object()
|
||||||
export class Asset {
|
export class Asset {
|
||||||
|
|
||||||
@Property()
|
@Property()
|
||||||
public ID: string;
|
public ID: string;
|
||||||
|
|
||||||
|
|
@ -18,5 +17,4 @@ export class Asset {
|
||||||
|
|
||||||
@Property()
|
@Property()
|
||||||
public OwnerOrg: string;
|
public OwnerOrg: string;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ export class AssetContract extends Contract {
|
||||||
if (exists) {
|
if (exists) {
|
||||||
throw new Error(`The asset ${assetId} already exists`);
|
throw new Error(`The asset ${assetId} already exists`);
|
||||||
}
|
}
|
||||||
const ownerOrg = this.getClientOrgId(ctx);
|
const ownerOrg = AssetContract.getClientOrgId(ctx);
|
||||||
const asset = new Asset();
|
const asset = new Asset();
|
||||||
asset.ID = assetId;
|
asset.ID = assetId;
|
||||||
asset.Value = value;
|
asset.Value = value;
|
||||||
|
|
@ -27,7 +27,7 @@ export class AssetContract extends Contract {
|
||||||
// Create the asset
|
// Create the asset
|
||||||
await ctx.stub.putState(assetId, buffer);
|
await ctx.stub.putState(assetId, buffer);
|
||||||
// Set the endorsement policy of the assetId Key, such that current owner Org Peer is required to endorse future updates
|
// Set the endorsement policy of the assetId Key, such that current owner Org Peer is required to endorse future updates
|
||||||
await this.setAssetStateBasedEndorsement(ctx, asset.ID, [ownerOrg]);
|
await AssetContract.setAssetStateBasedEndorsement(ctx, asset.ID, [ownerOrg]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadAsset returns asset with given assetId
|
// ReadAsset returns asset with given assetId
|
||||||
|
|
@ -78,7 +78,7 @@ export class AssetContract extends Contract {
|
||||||
// Update the asset
|
// Update the asset
|
||||||
await ctx.stub.putState(assetId, Buffer.from(JSON.stringify(asset)));
|
await ctx.stub.putState(assetId, Buffer.from(JSON.stringify(asset)));
|
||||||
// Re-Set the endorsement policy of the assetId Key, such that a new owner Org Peer is required to endorse future updates
|
// Re-Set the endorsement policy of the assetId Key, such that a new owner Org Peer is required to endorse future updates
|
||||||
await this.setAssetStateBasedEndorsement(ctx, asset.ID, [newOwnerOrg]);
|
await AssetContract.setAssetStateBasedEndorsement(ctx, asset.ID, [newOwnerOrg]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// AssetExists returns true when asset with given ID exists
|
// AssetExists returns true when asset with given ID exists
|
||||||
|
|
@ -89,14 +89,14 @@ export class AssetContract extends Contract {
|
||||||
|
|
||||||
// setAssetStateBasedEndorsement sets an endorsement policy to the assetId Key
|
// setAssetStateBasedEndorsement sets an endorsement policy to the assetId Key
|
||||||
// setAssetStateBasedEndorsement enforces that the owner Org Peers must endorse future update transactions for the specified assetId Key
|
// setAssetStateBasedEndorsement enforces that the owner Org Peers must endorse future update transactions for the specified assetId Key
|
||||||
private async setAssetStateBasedEndorsement(ctx: Context, assetId: string, ownerOrgs: string[]): Promise<void> {
|
private static async setAssetStateBasedEndorsement(ctx: Context, assetId: string, ownerOrgs: string[]): Promise<void> {
|
||||||
let ep = new KeyEndorsementPolicy();
|
const ep = new KeyEndorsementPolicy();
|
||||||
ep.addOrgs("MEMBER", ...ownerOrgs);
|
ep.addOrgs('MEMBER', ...ownerOrgs);
|
||||||
await ctx.stub.setStateValidationParameter(assetId, ep.getPolicy());
|
await ctx.stub.setStateValidationParameter(assetId, ep.getPolicy());
|
||||||
}
|
}
|
||||||
|
|
||||||
// getClientOrgId gets the client's OrgId (MSPID)
|
// getClientOrgId gets the client's OrgId (MSPID)
|
||||||
private getClientOrgId(ctx: Context): string {
|
private static getClientOrgId(ctx: Context): string {
|
||||||
return ctx.clientIdentity.getMSPID();
|
return ctx.clientIdentity.getMSPID();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,14 @@ jobs:
|
||||||
vmImage: ubuntu-18.04
|
vmImage: ubuntu-18.04
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
|
Basic-Application-Go:
|
||||||
|
DIRECTORY: asset-transfer-basic
|
||||||
|
LANGUAGE: go
|
||||||
|
TYPE: application
|
||||||
|
Basic-Application-Java:
|
||||||
|
DIRECTORY: asset-transfer-basic
|
||||||
|
LANGUAGE: java
|
||||||
|
TYPE: application
|
||||||
Basic-Application-Javascript:
|
Basic-Application-Javascript:
|
||||||
DIRECTORY: asset-transfer-basic
|
DIRECTORY: asset-transfer-basic
|
||||||
LANGUAGE: javascript
|
LANGUAGE: javascript
|
||||||
|
|
@ -96,10 +104,26 @@ jobs:
|
||||||
DIRECTORY: asset-transfer-basic
|
DIRECTORY: asset-transfer-basic
|
||||||
LANGUAGE: typescript
|
LANGUAGE: typescript
|
||||||
TYPE: chaincode
|
TYPE: chaincode
|
||||||
|
Ledger-Application-Java:
|
||||||
|
DIRECTORY: asset-transfer-ledger-queries
|
||||||
|
LANGUAGE: java
|
||||||
|
TYPE: application
|
||||||
Ledger-Chaincode-Go:
|
Ledger-Chaincode-Go:
|
||||||
DIRECTORY: asset-transfer-ledger-queries
|
DIRECTORY: asset-transfer-ledger-queries
|
||||||
LANGUAGE: go
|
LANGUAGE: go
|
||||||
TYPE: chaincode
|
TYPE: chaincode
|
||||||
|
Ledger-Chaincode-Javascript:
|
||||||
|
DIRECTORY: asset-transfer-ledger-queries
|
||||||
|
LANGUAGE: javascript
|
||||||
|
TYPE: chaincode
|
||||||
|
PrivateData-Application-Javascript:
|
||||||
|
DIRECTORY: asset-transfer-private-data
|
||||||
|
LANGUAGE: javascript
|
||||||
|
TYPE: application
|
||||||
|
PrivateData-Chaincode-Go:
|
||||||
|
DIRECTORY: asset-transfer-private-data
|
||||||
|
LANGUAGE: go
|
||||||
|
TYPE: chaincode
|
||||||
SBE-Chaincode-Typescript:
|
SBE-Chaincode-Typescript:
|
||||||
DIRECTORY: asset-transfer-sbe
|
DIRECTORY: asset-transfer-sbe
|
||||||
LANGUAGE: typescript
|
LANGUAGE: typescript
|
||||||
|
|
@ -108,14 +132,6 @@ jobs:
|
||||||
DIRECTORY: asset-transfer-sbe
|
DIRECTORY: asset-transfer-sbe
|
||||||
LANGUAGE: java
|
LANGUAGE: java
|
||||||
TYPE: chaincode
|
TYPE: chaincode
|
||||||
PrivateData-Chaincode-Go:
|
|
||||||
DIRECTORY: asset-transfer-private-data
|
|
||||||
LANGUAGE: go
|
|
||||||
TYPE: chaincode
|
|
||||||
PrivateData-Application-Javascript:
|
|
||||||
DIRECTORY: asset-transfer-private-data
|
|
||||||
LANGUAGE: javascript
|
|
||||||
TYPE: application
|
|
||||||
Secured-Chaincode-Go:
|
Secured-Chaincode-Go:
|
||||||
DIRECTORY: asset-transfer-secured-agreement
|
DIRECTORY: asset-transfer-secured-agreement
|
||||||
LANGUAGE: go
|
LANGUAGE: go
|
||||||
|
|
@ -166,6 +182,9 @@ jobs:
|
||||||
Ledger-Go:
|
Ledger-Go:
|
||||||
CHAINCODE_NAME: ledger
|
CHAINCODE_NAME: ledger
|
||||||
CHAINCODE_LANGUAGE: go
|
CHAINCODE_LANGUAGE: go
|
||||||
|
Ledger-Javascript:
|
||||||
|
CHAINCODE_NAME: ledger
|
||||||
|
CHAINCODE_LANGUAGE: javascript
|
||||||
steps:
|
steps:
|
||||||
- template: templates/install-deps.yml
|
- template: templates/install-deps.yml
|
||||||
- script: ../ci/scripts/run-test-network-ledger.sh
|
- script: ../ci/scripts/run-test-network-ledger.sh
|
||||||
|
|
@ -193,12 +212,12 @@ jobs:
|
||||||
vmImage: ubuntu-18.04
|
vmImage: ubuntu-18.04
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
Basic-Java:
|
SBE-Typescript:
|
||||||
CHAINCODE_NAME: sbe
|
|
||||||
CHAINCODE_LANGUAGE: java
|
|
||||||
Basic-Typescript:
|
|
||||||
CHAINCODE_NAME: sbe
|
CHAINCODE_NAME: sbe
|
||||||
CHAINCODE_LANGUAGE: typescript
|
CHAINCODE_LANGUAGE: typescript
|
||||||
|
SBE-Java:
|
||||||
|
CHAINCODE_NAME: sbe
|
||||||
|
CHAINCODE_LANGUAGE: java
|
||||||
steps:
|
steps:
|
||||||
- template: templates/install-deps.yml
|
- template: templates/install-deps.yml
|
||||||
- script: ../ci/scripts/run-test-network-sbe.sh
|
- script: ../ci/scripts/run-test-network-sbe.sh
|
||||||
|
|
|
||||||
|
|
@ -11,20 +11,42 @@ function print() {
|
||||||
echo -e "${GREEN}${1}${NC}"
|
echo -e "${GREEN}${1}${NC}"
|
||||||
}
|
}
|
||||||
|
|
||||||
print "Creating network"
|
function createNetwork() {
|
||||||
./network.sh up createChannel -ca -s couchdb -i "${FABRIC_VERSION}"
|
print "Creating network"
|
||||||
print "Deploying ${CHAINCODE_NAME} chaincode"
|
./network.sh up createChannel -ca -s couchdb -i "${FABRIC_VERSION}"
|
||||||
./network.sh deployCC -ccn "${CHAINCODE_NAME}" -ccv 1 -ccs 1 -ccl "${CHAINCODE_LANGUAGE}"
|
print "Deploying ${CHAINCODE_NAME} chaincode"
|
||||||
|
./network.sh deployCC -ccn "${CHAINCODE_NAME}" -ccv 1 -ccs 1 -ccl "${CHAINCODE_LANGUAGE}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function stopNetwork() {
|
||||||
|
print "Stopping network"
|
||||||
|
./network.sh down
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run Go application
|
||||||
|
#createNetwork
|
||||||
|
#print "Initializing Go application"
|
||||||
|
#pushd ../asset-transfer-basic/application-go
|
||||||
|
#print "Executing AssetTransfer.go"
|
||||||
|
#go run .
|
||||||
|
#popd
|
||||||
|
#stopNetwork
|
||||||
|
|
||||||
|
# Run Java application
|
||||||
|
createNetwork
|
||||||
|
print "Initializing Java application"
|
||||||
|
pushd ../asset-transfer-basic/application-java
|
||||||
|
print "Executing Gradle Run"
|
||||||
|
gradle run
|
||||||
|
popd
|
||||||
|
stopNetwork
|
||||||
|
|
||||||
# Run Javascript application
|
# Run Javascript application
|
||||||
|
createNetwork
|
||||||
print "Initializing Javascript application"
|
print "Initializing Javascript application"
|
||||||
pushd ../asset-transfer-basic/application-javascript
|
pushd ../asset-transfer-basic/application-javascript
|
||||||
npm install
|
npm install
|
||||||
print "Executing app.js"
|
print "Executing app.js"
|
||||||
node app.js
|
node app.js
|
||||||
popd
|
popd
|
||||||
|
stopNetwork
|
||||||
print "Stopping network"
|
|
||||||
./network.sh down
|
|
||||||
rm -R ../asset-transfer-basic/application-javascript/wallet
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
FABRIC_VERSION=${FABRIC_VERSION:-2.2}
|
FABRIC_VERSION=${FABRIC_VERSION:-2.2}
|
||||||
|
CHAINCODE_LANGUAGE=${CHAINCODE_LANGUAGE:-go}
|
||||||
CHAINCODE_NAME=${CHAINCODE_NAME:-ledger}
|
CHAINCODE_NAME=${CHAINCODE_NAME:-ledger}
|
||||||
|
|
||||||
function print() {
|
function print() {
|
||||||
|
|
@ -10,31 +11,33 @@ function print() {
|
||||||
echo -e "${GREEN}${1}${NC}"
|
echo -e "${GREEN}${1}${NC}"
|
||||||
}
|
}
|
||||||
|
|
||||||
print "Creating network"
|
function createNetwork() {
|
||||||
./network.sh up createChannel -ca -s couchdb -i "${FABRIC_VERSION}"
|
print "Creating network"
|
||||||
|
./network.sh up createChannel -ca -s couchdb -i "${FABRIC_VERSION}"
|
||||||
|
print "Deploying ${CHAINCODE_NAME} chaincode"
|
||||||
|
./network.sh deployCC -ccn "${CHAINCODE_NAME}" -ccv 1 -ccs 1 -ccl "${CHAINCODE_LANGUAGE}"
|
||||||
|
}
|
||||||
|
|
||||||
print "Deploying ${CHAINCODE_NAME} go chaincode"
|
function stopNetwork() {
|
||||||
./network.sh deployCC -ccn "${CHAINCODE_NAME}" -ccv 1.0 -ccs 1 -ccl go
|
print "Stopping network"
|
||||||
|
./network.sh down
|
||||||
|
}
|
||||||
|
|
||||||
# Run Javascript application against the go chaincode
|
# Run Java application
|
||||||
|
createNetwork
|
||||||
|
print "Initializing Java application"
|
||||||
|
pushd ../asset-transfer-ledger-queries/application-java
|
||||||
|
print "Executing Gradle Run"
|
||||||
|
gradle run
|
||||||
|
popd
|
||||||
|
stopNetwork
|
||||||
|
|
||||||
|
# Run Javascript application
|
||||||
|
createNetwork
|
||||||
print "Initializing Javascript application"
|
print "Initializing Javascript application"
|
||||||
pushd ../asset-transfer-ledger-queries/application-javascript
|
pushd ../asset-transfer-ledger-queries/application-javascript
|
||||||
npm install
|
npm install
|
||||||
print "Executing app.js"
|
print "Executing app.js"
|
||||||
node app.js
|
node app.js
|
||||||
popd
|
popd
|
||||||
|
stopNetwork
|
||||||
print "Deploying ${CHAINCODE_NAME} javascript chaincode"
|
|
||||||
./network.sh deployCC -ccn "${CHAINCODE_NAME}" -ccv 2.0 -ccs 2 -ccl javascript
|
|
||||||
|
|
||||||
# Run Javascript application against the javascript chaincode
|
|
||||||
print "Initializing Javascript application"
|
|
||||||
pushd ../asset-transfer-ledger-queries/application-javascript
|
|
||||||
npm install
|
|
||||||
print "Executing app.js"
|
|
||||||
node app.js skipInit
|
|
||||||
popd
|
|
||||||
|
|
||||||
print "Stopping network"
|
|
||||||
./network.sh down
|
|
||||||
rm -R ../asset-transfer-ledger-queries/application-javascript/wallet
|
|
||||||
|
|
|
||||||
|
|
@ -11,19 +11,24 @@ function print() {
|
||||||
echo -e "${GREEN}${1}${NC}"
|
echo -e "${GREEN}${1}${NC}"
|
||||||
}
|
}
|
||||||
|
|
||||||
print "Creating network"
|
function createNetwork() {
|
||||||
./network.sh up createChannel -ca -s couchdb -i "${FABRIC_VERSION}"
|
print "Creating network"
|
||||||
|
./network.sh up createChannel -ca -s couchdb -i "${FABRIC_VERSION}"
|
||||||
|
print "Deploying ${CHAINCODE_NAME} chaincode"
|
||||||
|
./network.sh deployCC -ccn "${CHAINCODE_NAME}" -ccv 1 -ccs 1 -ccl "${CHAINCODE_LANGUAGE}" -ccep "OR('Org1MSP.peer','Org2MSP.peer')" -cccg ../asset-transfer-private-data/chaincode-go/collections_config.json
|
||||||
|
}
|
||||||
|
|
||||||
print "Deploying private-data ${CHAINCODE_NAME} chaincode"
|
function stopNetwork() {
|
||||||
./network.sh deployCC -ccn "${CHAINCODE_NAME}" -ccv 1 -ccs 1 -ccl "${CHAINCODE_LANGUAGE}" -ccep "OR('Org1MSP.peer','Org2MSP.peer')" -cccg ../asset-transfer-private-data/chaincode-go/collections_config.json
|
print "Stopping network"
|
||||||
|
./network.sh down
|
||||||
|
}
|
||||||
|
|
||||||
# Run Javascript application
|
# Run Javascript application
|
||||||
|
createNetwork
|
||||||
print "Initializing Javascript application"
|
print "Initializing Javascript application"
|
||||||
pushd ../asset-transfer-private-data/application-javascript
|
pushd ../asset-transfer-private-data/application-javascript
|
||||||
npm install
|
npm install
|
||||||
print "Executing app.js"
|
print "Executing app.js"
|
||||||
node app.js
|
node app.js
|
||||||
popd
|
popd
|
||||||
|
stopNetwork
|
||||||
print "Stopping network"
|
|
||||||
./network.sh down
|
|
||||||
|
|
|
||||||
|
|
@ -11,11 +11,18 @@ function print() {
|
||||||
echo -e "${GREEN}${1}${NC}"
|
echo -e "${GREEN}${1}${NC}"
|
||||||
}
|
}
|
||||||
|
|
||||||
print "Creating network"
|
function createNetwork() {
|
||||||
./network.sh up createChannel -ca -s couchdb -i "${FABRIC_VERSION}"
|
print "Creating network"
|
||||||
|
./network.sh up createChannel -ca -s couchdb -i "${FABRIC_VERSION}"
|
||||||
|
print "Deploying ${CHAINCODE_NAME} chaincode"
|
||||||
|
./network.sh deployCC -ccn "${CHAINCODE_NAME}" -ccv 1 -ccs 1 -ccl "${CHAINCODE_LANGUAGE}"
|
||||||
|
}
|
||||||
|
|
||||||
print "Deploying ${CHAINCODE_NAME} chaincode"
|
function stopNetwork() {
|
||||||
./network.sh deployCC -ccn "${CHAINCODE_NAME}" -ccv 1 -ccs 1 -ccl "${CHAINCODE_LANGUAGE}"
|
print "Stopping network"
|
||||||
|
./network.sh down
|
||||||
|
}
|
||||||
|
|
||||||
print "Stopping network"
|
# Run Javascript application
|
||||||
./network.sh down
|
createNetwork
|
||||||
|
stopNetwork
|
||||||
|
|
|
||||||
|
|
@ -11,11 +11,18 @@ function print() {
|
||||||
echo -e "${GREEN}${1}${NC}"
|
echo -e "${GREEN}${1}${NC}"
|
||||||
}
|
}
|
||||||
|
|
||||||
print "Creating network"
|
function createNetwork() {
|
||||||
./network.sh up createChannel -ca -s couchdb -i "${FABRIC_VERSION}"
|
print "Creating network"
|
||||||
|
./network.sh up createChannel -ca -s couchdb -i "${FABRIC_VERSION}"
|
||||||
|
print "Deploying ${CHAINCODE_NAME} chaincode"
|
||||||
|
./network.sh deployCC -ccn "${CHAINCODE_NAME}" -ccv 1 -ccs 1 -ccl "${CHAINCODE_LANGUAGE}"
|
||||||
|
}
|
||||||
|
|
||||||
print "Deploying ${CHAINCODE_NAME} chaincode"
|
function stopNetwork() {
|
||||||
./network.sh deployCC -ccn "${CHAINCODE_NAME}" -ccv 1 -ccs 1 -ccl "${CHAINCODE_LANGUAGE}"
|
print "Stopping network"
|
||||||
|
./network.sh down
|
||||||
|
}
|
||||||
|
|
||||||
print "Stopping network"
|
# Run Javascript application
|
||||||
./network.sh down
|
createNetwork
|
||||||
|
stopNetwork
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ checkCommitReadiness() {
|
||||||
set -x
|
set -x
|
||||||
peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name bigdatacc --signature-policy "OR('Org1MSP.peer', 'Org2MSP.peer')" --version 0 --init-required --sequence 1 >&log.txt
|
peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name bigdatacc --signature-policy "OR('Org1MSP.peer', 'Org2MSP.peer')" --version 0 --init-required --sequence 1 >&log.txt
|
||||||
res=$?
|
res=$?
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
test $res -eq 0 || continue
|
test $res -eq 0 || continue
|
||||||
let rc=0
|
let rc=0
|
||||||
for var in "$@"
|
for var in "$@"
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ checkCommitReadiness() {
|
||||||
set -x
|
set -x
|
||||||
peer lifecycle chaincode checkcommitreadiness -o irs-orderer:7050 --channelID irs --signature-policy "AND(OR('partya.peer','partyb.peer','partyc.peer'), 'auditor.peer')" --name irscc --version 1 --init-required --sequence 1 >&log.txt
|
peer lifecycle chaincode checkcommitreadiness -o irs-orderer:7050 --channelID irs --signature-policy "AND(OR('partya.peer','partyb.peer','partyc.peer'), 'auditor.peer')" --name irscc --version 1 --init-required --sequence 1 >&log.txt
|
||||||
res=$?
|
res=$?
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
test $res -eq 0 || continue
|
test $res -eq 0 || continue
|
||||||
let rc=0
|
let rc=0
|
||||||
for var in "$@"
|
for var in "$@"
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ function generateOrg3() {
|
||||||
set -x
|
set -x
|
||||||
cryptogen generate --config=org3-crypto.yaml --output="../organizations"
|
cryptogen generate --config=org3-crypto.yaml --output="../organizations"
|
||||||
res=$?
|
res=$?
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
if [ $res -ne 0 ]; then
|
if [ $res -ne 0 ]; then
|
||||||
echo "Failed to generate certificates..."
|
echo "Failed to generate certificates..."
|
||||||
exit 1
|
exit 1
|
||||||
|
|
@ -131,7 +131,7 @@ function generateOrg3Definition() {
|
||||||
set -x
|
set -x
|
||||||
configtxgen -printOrg Org3MSP > ../organizations/peerOrganizations/org3.example.com/org3.json
|
configtxgen -printOrg Org3MSP > ../organizations/peerOrganizations/org3.example.com/org3.json
|
||||||
res=$?
|
res=$?
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
if [ $res -ne 0 ]; then
|
if [ $res -ne 0 ]; then
|
||||||
echo "Failed to generate Org3 config material..."
|
echo "Failed to generate Org3 config material..."
|
||||||
exit 1
|
exit 1
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ function createOrg3 {
|
||||||
|
|
||||||
set -x
|
set -x
|
||||||
fabric-ca-client enroll -u https://admin:adminpw@localhost:11054 --caname ca-org3 --tls.certfiles ${PWD}/fabric-ca/org3/tls-cert.pem
|
fabric-ca-client enroll -u https://admin:adminpw@localhost:11054 --caname ca-org3 --tls.certfiles ${PWD}/fabric-ca/org3/tls-cert.pem
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
|
|
||||||
echo 'NodeOUs:
|
echo 'NodeOUs:
|
||||||
Enable: true
|
Enable: true
|
||||||
|
|
@ -35,21 +35,21 @@ function createOrg3 {
|
||||||
echo
|
echo
|
||||||
set -x
|
set -x
|
||||||
fabric-ca-client register --caname ca-org3 --id.name peer0 --id.secret peer0pw --id.type peer --tls.certfiles ${PWD}/fabric-ca/org3/tls-cert.pem
|
fabric-ca-client register --caname ca-org3 --id.name peer0 --id.secret peer0pw --id.type peer --tls.certfiles ${PWD}/fabric-ca/org3/tls-cert.pem
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "Register user"
|
echo "Register user"
|
||||||
echo
|
echo
|
||||||
set -x
|
set -x
|
||||||
fabric-ca-client register --caname ca-org3 --id.name user1 --id.secret user1pw --id.type client --tls.certfiles ${PWD}/fabric-ca/org3/tls-cert.pem
|
fabric-ca-client register --caname ca-org3 --id.name user1 --id.secret user1pw --id.type client --tls.certfiles ${PWD}/fabric-ca/org3/tls-cert.pem
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "Register the org admin"
|
echo "Register the org admin"
|
||||||
echo
|
echo
|
||||||
set -x
|
set -x
|
||||||
fabric-ca-client register --caname ca-org3 --id.name org3admin --id.secret org3adminpw --id.type admin --tls.certfiles ${PWD}/fabric-ca/org3/tls-cert.pem
|
fabric-ca-client register --caname ca-org3 --id.name org3admin --id.secret org3adminpw --id.type admin --tls.certfiles ${PWD}/fabric-ca/org3/tls-cert.pem
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
|
|
||||||
mkdir -p ../organizations/peerOrganizations/org3.example.com/peers
|
mkdir -p ../organizations/peerOrganizations/org3.example.com/peers
|
||||||
mkdir -p ../organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com
|
mkdir -p ../organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com
|
||||||
|
|
@ -59,7 +59,7 @@ function createOrg3 {
|
||||||
echo
|
echo
|
||||||
set -x
|
set -x
|
||||||
fabric-ca-client enroll -u https://peer0:peer0pw@localhost:11054 --caname ca-org3 -M ${PWD}/../organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/msp --csr.hosts peer0.org3.example.com --tls.certfiles ${PWD}/fabric-ca/org3/tls-cert.pem
|
fabric-ca-client enroll -u https://peer0:peer0pw@localhost:11054 --caname ca-org3 -M ${PWD}/../organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/msp --csr.hosts peer0.org3.example.com --tls.certfiles ${PWD}/fabric-ca/org3/tls-cert.pem
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
|
|
||||||
cp ${PWD}/../organizations/peerOrganizations/org3.example.com/msp/config.yaml ${PWD}/../organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/msp/config.yaml
|
cp ${PWD}/../organizations/peerOrganizations/org3.example.com/msp/config.yaml ${PWD}/../organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/msp/config.yaml
|
||||||
|
|
||||||
|
|
@ -68,7 +68,7 @@ function createOrg3 {
|
||||||
echo
|
echo
|
||||||
set -x
|
set -x
|
||||||
fabric-ca-client enroll -u https://peer0:peer0pw@localhost:11054 --caname ca-org3 -M ${PWD}/../organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls --enrollment.profile tls --csr.hosts peer0.org3.example.com --csr.hosts localhost --tls.certfiles ${PWD}/fabric-ca/org3/tls-cert.pem
|
fabric-ca-client enroll -u https://peer0:peer0pw@localhost:11054 --caname ca-org3 -M ${PWD}/../organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls --enrollment.profile tls --csr.hosts peer0.org3.example.com --csr.hosts localhost --tls.certfiles ${PWD}/fabric-ca/org3/tls-cert.pem
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
|
|
||||||
|
|
||||||
cp ${PWD}/../organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/tlscacerts/* ${PWD}/../organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/ca.crt
|
cp ${PWD}/../organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/tlscacerts/* ${PWD}/../organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/ca.crt
|
||||||
|
|
@ -92,7 +92,7 @@ function createOrg3 {
|
||||||
echo
|
echo
|
||||||
set -x
|
set -x
|
||||||
fabric-ca-client enroll -u https://user1:user1pw@localhost:11054 --caname ca-org3 -M ${PWD}/../organizations/peerOrganizations/org3.example.com/users/User1@org3.example.com/msp --tls.certfiles ${PWD}/fabric-ca/org3/tls-cert.pem
|
fabric-ca-client enroll -u https://user1:user1pw@localhost:11054 --caname ca-org3 -M ${PWD}/../organizations/peerOrganizations/org3.example.com/users/User1@org3.example.com/msp --tls.certfiles ${PWD}/fabric-ca/org3/tls-cert.pem
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
|
|
||||||
cp ${PWD}/../organizations/peerOrganizations/org3.example.com/msp/config.yaml ${PWD}/../organizations/peerOrganizations/org3.example.com/users/User1@org3.example.com/msp/config.yaml
|
cp ${PWD}/../organizations/peerOrganizations/org3.example.com/msp/config.yaml ${PWD}/../organizations/peerOrganizations/org3.example.com/users/User1@org3.example.com/msp/config.yaml
|
||||||
|
|
||||||
|
|
@ -103,7 +103,7 @@ function createOrg3 {
|
||||||
echo
|
echo
|
||||||
set -x
|
set -x
|
||||||
fabric-ca-client enroll -u https://org3admin:org3adminpw@localhost:11054 --caname ca-org3 -M ${PWD}/../organizations/peerOrganizations/org3.example.com/users/Admin@org3.example.com/msp --tls.certfiles ${PWD}/fabric-ca/org3/tls-cert.pem
|
fabric-ca-client enroll -u https://org3admin:org3adminpw@localhost:11054 --caname ca-org3 -M ${PWD}/../organizations/peerOrganizations/org3.example.com/users/Admin@org3.example.com/msp --tls.certfiles ${PWD}/fabric-ca/org3/tls-cert.pem
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
|
|
||||||
cp ${PWD}/../organizations/peerOrganizations/org3.example.com/msp/config.yaml ${PWD}/../organizations/peerOrganizations/org3.example.com/users/Admin@org3.example.com/msp/config.yaml
|
cp ${PWD}/../organizations/peerOrganizations/org3.example.com/msp/config.yaml ${PWD}/../organizations/peerOrganizations/org3.example.com/users/Admin@org3.example.com/msp/config.yaml
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -214,7 +214,7 @@ function createOrgs() {
|
||||||
set -x
|
set -x
|
||||||
cryptogen generate --config=./organizations/cryptogen/crypto-config-org1.yaml --output="organizations"
|
cryptogen generate --config=./organizations/cryptogen/crypto-config-org1.yaml --output="organizations"
|
||||||
res=$?
|
res=$?
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
if [ $res -ne 0 ]; then
|
if [ $res -ne 0 ]; then
|
||||||
echo $'\e[1;32m'"Failed to generate certificates..."$'\e[0m'
|
echo $'\e[1;32m'"Failed to generate certificates..."$'\e[0m'
|
||||||
exit 1
|
exit 1
|
||||||
|
|
@ -227,7 +227,7 @@ function createOrgs() {
|
||||||
set -x
|
set -x
|
||||||
cryptogen generate --config=./organizations/cryptogen/crypto-config-org2.yaml --output="organizations"
|
cryptogen generate --config=./organizations/cryptogen/crypto-config-org2.yaml --output="organizations"
|
||||||
res=$?
|
res=$?
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
if [ $res -ne 0 ]; then
|
if [ $res -ne 0 ]; then
|
||||||
echo $'\e[1;32m'"Failed to generate certificates..."$'\e[0m'
|
echo $'\e[1;32m'"Failed to generate certificates..."$'\e[0m'
|
||||||
exit 1
|
exit 1
|
||||||
|
|
@ -240,7 +240,7 @@ function createOrgs() {
|
||||||
set -x
|
set -x
|
||||||
cryptogen generate --config=./organizations/cryptogen/crypto-config-orderer.yaml --output="organizations"
|
cryptogen generate --config=./organizations/cryptogen/crypto-config-orderer.yaml --output="organizations"
|
||||||
res=$?
|
res=$?
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
if [ $res -ne 0 ]; then
|
if [ $res -ne 0 ]; then
|
||||||
echo $'\e[1;32m'"Failed to generate certificates..."$'\e[0m'
|
echo $'\e[1;32m'"Failed to generate certificates..."$'\e[0m'
|
||||||
exit 1
|
exit 1
|
||||||
|
|
@ -329,7 +329,7 @@ function createConsortium() {
|
||||||
set -x
|
set -x
|
||||||
configtxgen -profile TwoOrgsOrdererGenesis -channelID system-channel -outputBlock ./system-genesis-block/genesis.block
|
configtxgen -profile TwoOrgsOrdererGenesis -channelID system-channel -outputBlock ./system-genesis-block/genesis.block
|
||||||
res=$?
|
res=$?
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
if [ $res -ne 0 ]; then
|
if [ $res -ne 0 ]; then
|
||||||
echo $'\e[1;32m'"Failed to generate orderer genesis block..."$'\e[0m'
|
echo $'\e[1;32m'"Failed to generate orderer genesis block..."$'\e[0m'
|
||||||
exit 1
|
exit 1
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ function createOrg1 {
|
||||||
|
|
||||||
set -x
|
set -x
|
||||||
fabric-ca-client enroll -u https://admin:adminpw@localhost:7054 --caname ca-org1 --tls.certfiles ${PWD}/organizations/fabric-ca/org1/tls-cert.pem
|
fabric-ca-client enroll -u https://admin:adminpw@localhost:7054 --caname ca-org1 --tls.certfiles ${PWD}/organizations/fabric-ca/org1/tls-cert.pem
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
|
|
||||||
echo 'NodeOUs:
|
echo 'NodeOUs:
|
||||||
Enable: true
|
Enable: true
|
||||||
|
|
@ -35,21 +35,21 @@ function createOrg1 {
|
||||||
echo
|
echo
|
||||||
set -x
|
set -x
|
||||||
fabric-ca-client register --caname ca-org1 --id.name peer0 --id.secret peer0pw --id.type peer --tls.certfiles ${PWD}/organizations/fabric-ca/org1/tls-cert.pem
|
fabric-ca-client register --caname ca-org1 --id.name peer0 --id.secret peer0pw --id.type peer --tls.certfiles ${PWD}/organizations/fabric-ca/org1/tls-cert.pem
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "Register user"
|
echo "Register user"
|
||||||
echo
|
echo
|
||||||
set -x
|
set -x
|
||||||
fabric-ca-client register --caname ca-org1 --id.name user1 --id.secret user1pw --id.type client --tls.certfiles ${PWD}/organizations/fabric-ca/org1/tls-cert.pem
|
fabric-ca-client register --caname ca-org1 --id.name user1 --id.secret user1pw --id.type client --tls.certfiles ${PWD}/organizations/fabric-ca/org1/tls-cert.pem
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "Register the org admin"
|
echo "Register the org admin"
|
||||||
echo
|
echo
|
||||||
set -x
|
set -x
|
||||||
fabric-ca-client register --caname ca-org1 --id.name org1admin --id.secret org1adminpw --id.type admin --tls.certfiles ${PWD}/organizations/fabric-ca/org1/tls-cert.pem
|
fabric-ca-client register --caname ca-org1 --id.name org1admin --id.secret org1adminpw --id.type admin --tls.certfiles ${PWD}/organizations/fabric-ca/org1/tls-cert.pem
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
|
|
||||||
mkdir -p organizations/peerOrganizations/org1.example.com/peers
|
mkdir -p organizations/peerOrganizations/org1.example.com/peers
|
||||||
mkdir -p organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com
|
mkdir -p organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com
|
||||||
|
|
@ -59,7 +59,7 @@ function createOrg1 {
|
||||||
echo
|
echo
|
||||||
set -x
|
set -x
|
||||||
fabric-ca-client enroll -u https://peer0:peer0pw@localhost:7054 --caname ca-org1 -M ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp --csr.hosts peer0.org1.example.com --tls.certfiles ${PWD}/organizations/fabric-ca/org1/tls-cert.pem
|
fabric-ca-client enroll -u https://peer0:peer0pw@localhost:7054 --caname ca-org1 -M ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp --csr.hosts peer0.org1.example.com --tls.certfiles ${PWD}/organizations/fabric-ca/org1/tls-cert.pem
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
|
|
||||||
cp ${PWD}/organizations/peerOrganizations/org1.example.com/msp/config.yaml ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp/config.yaml
|
cp ${PWD}/organizations/peerOrganizations/org1.example.com/msp/config.yaml ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp/config.yaml
|
||||||
|
|
||||||
|
|
@ -68,7 +68,7 @@ function createOrg1 {
|
||||||
echo
|
echo
|
||||||
set -x
|
set -x
|
||||||
fabric-ca-client enroll -u https://peer0:peer0pw@localhost:7054 --caname ca-org1 -M ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls --enrollment.profile tls --csr.hosts peer0.org1.example.com --csr.hosts localhost --tls.certfiles ${PWD}/organizations/fabric-ca/org1/tls-cert.pem
|
fabric-ca-client enroll -u https://peer0:peer0pw@localhost:7054 --caname ca-org1 -M ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls --enrollment.profile tls --csr.hosts peer0.org1.example.com --csr.hosts localhost --tls.certfiles ${PWD}/organizations/fabric-ca/org1/tls-cert.pem
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
|
|
||||||
|
|
||||||
cp ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/tlscacerts/* ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
|
cp ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/tlscacerts/* ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
|
||||||
|
|
@ -92,7 +92,7 @@ function createOrg1 {
|
||||||
echo
|
echo
|
||||||
set -x
|
set -x
|
||||||
fabric-ca-client enroll -u https://user1:user1pw@localhost:7054 --caname ca-org1 -M ${PWD}/organizations/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp --tls.certfiles ${PWD}/organizations/fabric-ca/org1/tls-cert.pem
|
fabric-ca-client enroll -u https://user1:user1pw@localhost:7054 --caname ca-org1 -M ${PWD}/organizations/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp --tls.certfiles ${PWD}/organizations/fabric-ca/org1/tls-cert.pem
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
|
|
||||||
cp ${PWD}/organizations/peerOrganizations/org1.example.com/msp/config.yaml ${PWD}/organizations/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp/config.yaml
|
cp ${PWD}/organizations/peerOrganizations/org1.example.com/msp/config.yaml ${PWD}/organizations/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp/config.yaml
|
||||||
|
|
||||||
|
|
@ -103,7 +103,7 @@ function createOrg1 {
|
||||||
echo
|
echo
|
||||||
set -x
|
set -x
|
||||||
fabric-ca-client enroll -u https://org1admin:org1adminpw@localhost:7054 --caname ca-org1 -M ${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp --tls.certfiles ${PWD}/organizations/fabric-ca/org1/tls-cert.pem
|
fabric-ca-client enroll -u https://org1admin:org1adminpw@localhost:7054 --caname ca-org1 -M ${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp --tls.certfiles ${PWD}/organizations/fabric-ca/org1/tls-cert.pem
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
|
|
||||||
cp ${PWD}/organizations/peerOrganizations/org1.example.com/msp/config.yaml ${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/config.yaml
|
cp ${PWD}/organizations/peerOrganizations/org1.example.com/msp/config.yaml ${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/config.yaml
|
||||||
|
|
||||||
|
|
@ -123,7 +123,7 @@ function createOrg2 {
|
||||||
|
|
||||||
set -x
|
set -x
|
||||||
fabric-ca-client enroll -u https://admin:adminpw@localhost:8054 --caname ca-org2 --tls.certfiles ${PWD}/organizations/fabric-ca/org2/tls-cert.pem
|
fabric-ca-client enroll -u https://admin:adminpw@localhost:8054 --caname ca-org2 --tls.certfiles ${PWD}/organizations/fabric-ca/org2/tls-cert.pem
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
|
|
||||||
echo 'NodeOUs:
|
echo 'NodeOUs:
|
||||||
Enable: true
|
Enable: true
|
||||||
|
|
@ -145,21 +145,21 @@ function createOrg2 {
|
||||||
echo
|
echo
|
||||||
set -x
|
set -x
|
||||||
fabric-ca-client register --caname ca-org2 --id.name peer0 --id.secret peer0pw --id.type peer --tls.certfiles ${PWD}/organizations/fabric-ca/org2/tls-cert.pem
|
fabric-ca-client register --caname ca-org2 --id.name peer0 --id.secret peer0pw --id.type peer --tls.certfiles ${PWD}/organizations/fabric-ca/org2/tls-cert.pem
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "Register user"
|
echo "Register user"
|
||||||
echo
|
echo
|
||||||
set -x
|
set -x
|
||||||
fabric-ca-client register --caname ca-org2 --id.name user1 --id.secret user1pw --id.type client --tls.certfiles ${PWD}/organizations/fabric-ca/org2/tls-cert.pem
|
fabric-ca-client register --caname ca-org2 --id.name user1 --id.secret user1pw --id.type client --tls.certfiles ${PWD}/organizations/fabric-ca/org2/tls-cert.pem
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "Register the org admin"
|
echo "Register the org admin"
|
||||||
echo
|
echo
|
||||||
set -x
|
set -x
|
||||||
fabric-ca-client register --caname ca-org2 --id.name org2admin --id.secret org2adminpw --id.type admin --tls.certfiles ${PWD}/organizations/fabric-ca/org2/tls-cert.pem
|
fabric-ca-client register --caname ca-org2 --id.name org2admin --id.secret org2adminpw --id.type admin --tls.certfiles ${PWD}/organizations/fabric-ca/org2/tls-cert.pem
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
|
|
||||||
mkdir -p organizations/peerOrganizations/org2.example.com/peers
|
mkdir -p organizations/peerOrganizations/org2.example.com/peers
|
||||||
mkdir -p organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com
|
mkdir -p organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com
|
||||||
|
|
@ -169,7 +169,7 @@ function createOrg2 {
|
||||||
echo
|
echo
|
||||||
set -x
|
set -x
|
||||||
fabric-ca-client enroll -u https://peer0:peer0pw@localhost:8054 --caname ca-org2 -M ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/msp --csr.hosts peer0.org2.example.com --tls.certfiles ${PWD}/organizations/fabric-ca/org2/tls-cert.pem
|
fabric-ca-client enroll -u https://peer0:peer0pw@localhost:8054 --caname ca-org2 -M ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/msp --csr.hosts peer0.org2.example.com --tls.certfiles ${PWD}/organizations/fabric-ca/org2/tls-cert.pem
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
|
|
||||||
cp ${PWD}/organizations/peerOrganizations/org2.example.com/msp/config.yaml ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/msp/config.yaml
|
cp ${PWD}/organizations/peerOrganizations/org2.example.com/msp/config.yaml ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/msp/config.yaml
|
||||||
|
|
||||||
|
|
@ -178,7 +178,7 @@ function createOrg2 {
|
||||||
echo
|
echo
|
||||||
set -x
|
set -x
|
||||||
fabric-ca-client enroll -u https://peer0:peer0pw@localhost:8054 --caname ca-org2 -M ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls --enrollment.profile tls --csr.hosts peer0.org2.example.com --csr.hosts localhost --tls.certfiles ${PWD}/organizations/fabric-ca/org2/tls-cert.pem
|
fabric-ca-client enroll -u https://peer0:peer0pw@localhost:8054 --caname ca-org2 -M ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls --enrollment.profile tls --csr.hosts peer0.org2.example.com --csr.hosts localhost --tls.certfiles ${PWD}/organizations/fabric-ca/org2/tls-cert.pem
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
|
|
||||||
|
|
||||||
cp ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/tlscacerts/* ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
|
cp ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/tlscacerts/* ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
|
||||||
|
|
@ -202,7 +202,7 @@ function createOrg2 {
|
||||||
echo
|
echo
|
||||||
set -x
|
set -x
|
||||||
fabric-ca-client enroll -u https://user1:user1pw@localhost:8054 --caname ca-org2 -M ${PWD}/organizations/peerOrganizations/org2.example.com/users/User1@org2.example.com/msp --tls.certfiles ${PWD}/organizations/fabric-ca/org2/tls-cert.pem
|
fabric-ca-client enroll -u https://user1:user1pw@localhost:8054 --caname ca-org2 -M ${PWD}/organizations/peerOrganizations/org2.example.com/users/User1@org2.example.com/msp --tls.certfiles ${PWD}/organizations/fabric-ca/org2/tls-cert.pem
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
|
|
||||||
cp ${PWD}/organizations/peerOrganizations/org2.example.com/msp/config.yaml ${PWD}/organizations/peerOrganizations/org2.example.com/users/User1@org2.example.com/msp/config.yaml
|
cp ${PWD}/organizations/peerOrganizations/org2.example.com/msp/config.yaml ${PWD}/organizations/peerOrganizations/org2.example.com/users/User1@org2.example.com/msp/config.yaml
|
||||||
|
|
||||||
|
|
@ -213,7 +213,7 @@ function createOrg2 {
|
||||||
echo
|
echo
|
||||||
set -x
|
set -x
|
||||||
fabric-ca-client enroll -u https://org2admin:org2adminpw@localhost:8054 --caname ca-org2 -M ${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp --tls.certfiles ${PWD}/organizations/fabric-ca/org2/tls-cert.pem
|
fabric-ca-client enroll -u https://org2admin:org2adminpw@localhost:8054 --caname ca-org2 -M ${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp --tls.certfiles ${PWD}/organizations/fabric-ca/org2/tls-cert.pem
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
|
|
||||||
cp ${PWD}/organizations/peerOrganizations/org2.example.com/msp/config.yaml ${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp/config.yaml
|
cp ${PWD}/organizations/peerOrganizations/org2.example.com/msp/config.yaml ${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp/config.yaml
|
||||||
|
|
||||||
|
|
@ -232,7 +232,7 @@ function createOrderer {
|
||||||
|
|
||||||
set -x
|
set -x
|
||||||
fabric-ca-client enroll -u https://admin:adminpw@localhost:9054 --caname ca-orderer --tls.certfiles ${PWD}/organizations/fabric-ca/ordererOrg/tls-cert.pem
|
fabric-ca-client enroll -u https://admin:adminpw@localhost:9054 --caname ca-orderer --tls.certfiles ${PWD}/organizations/fabric-ca/ordererOrg/tls-cert.pem
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
|
|
||||||
echo 'NodeOUs:
|
echo 'NodeOUs:
|
||||||
Enable: true
|
Enable: true
|
||||||
|
|
@ -255,14 +255,14 @@ function createOrderer {
|
||||||
echo
|
echo
|
||||||
set -x
|
set -x
|
||||||
fabric-ca-client register --caname ca-orderer --id.name orderer --id.secret ordererpw --id.type orderer --tls.certfiles ${PWD}/organizations/fabric-ca/ordererOrg/tls-cert.pem
|
fabric-ca-client register --caname ca-orderer --id.name orderer --id.secret ordererpw --id.type orderer --tls.certfiles ${PWD}/organizations/fabric-ca/ordererOrg/tls-cert.pem
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "Register the orderer admin"
|
echo "Register the orderer admin"
|
||||||
echo
|
echo
|
||||||
set -x
|
set -x
|
||||||
fabric-ca-client register --caname ca-orderer --id.name ordererAdmin --id.secret ordererAdminpw --id.type admin --tls.certfiles ${PWD}/organizations/fabric-ca/ordererOrg/tls-cert.pem
|
fabric-ca-client register --caname ca-orderer --id.name ordererAdmin --id.secret ordererAdminpw --id.type admin --tls.certfiles ${PWD}/organizations/fabric-ca/ordererOrg/tls-cert.pem
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
|
|
||||||
mkdir -p organizations/ordererOrganizations/example.com/orderers
|
mkdir -p organizations/ordererOrganizations/example.com/orderers
|
||||||
mkdir -p organizations/ordererOrganizations/example.com/orderers/example.com
|
mkdir -p organizations/ordererOrganizations/example.com/orderers/example.com
|
||||||
|
|
@ -274,7 +274,7 @@ function createOrderer {
|
||||||
echo
|
echo
|
||||||
set -x
|
set -x
|
||||||
fabric-ca-client enroll -u https://orderer:ordererpw@localhost:9054 --caname ca-orderer -M ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp --csr.hosts orderer.example.com --csr.hosts localhost --tls.certfiles ${PWD}/organizations/fabric-ca/ordererOrg/tls-cert.pem
|
fabric-ca-client enroll -u https://orderer:ordererpw@localhost:9054 --caname ca-orderer -M ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp --csr.hosts orderer.example.com --csr.hosts localhost --tls.certfiles ${PWD}/organizations/fabric-ca/ordererOrg/tls-cert.pem
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
|
|
||||||
cp ${PWD}/organizations/ordererOrganizations/example.com/msp/config.yaml ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/config.yaml
|
cp ${PWD}/organizations/ordererOrganizations/example.com/msp/config.yaml ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/config.yaml
|
||||||
|
|
||||||
|
|
@ -283,7 +283,7 @@ function createOrderer {
|
||||||
echo
|
echo
|
||||||
set -x
|
set -x
|
||||||
fabric-ca-client enroll -u https://orderer:ordererpw@localhost:9054 --caname ca-orderer -M ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls --enrollment.profile tls --csr.hosts orderer.example.com --csr.hosts localhost --tls.certfiles ${PWD}/organizations/fabric-ca/ordererOrg/tls-cert.pem
|
fabric-ca-client enroll -u https://orderer:ordererpw@localhost:9054 --caname ca-orderer -M ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls --enrollment.profile tls --csr.hosts orderer.example.com --csr.hosts localhost --tls.certfiles ${PWD}/organizations/fabric-ca/ordererOrg/tls-cert.pem
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
|
|
||||||
cp ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/tlscacerts/* ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt
|
cp ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/tlscacerts/* ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt
|
||||||
cp ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/signcerts/* ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt
|
cp ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/signcerts/* ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt
|
||||||
|
|
@ -303,7 +303,7 @@ function createOrderer {
|
||||||
echo
|
echo
|
||||||
set -x
|
set -x
|
||||||
fabric-ca-client enroll -u https://ordererAdmin:ordererAdminpw@localhost:9054 --caname ca-orderer -M ${PWD}/organizations/ordererOrganizations/example.com/users/Admin@example.com/msp --tls.certfiles ${PWD}/organizations/fabric-ca/ordererOrg/tls-cert.pem
|
fabric-ca-client enroll -u https://ordererAdmin:ordererAdminpw@localhost:9054 --caname ca-orderer -M ${PWD}/organizations/ordererOrganizations/example.com/users/Admin@example.com/msp --tls.certfiles ${PWD}/organizations/fabric-ca/ordererOrg/tls-cert.pem
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
|
|
||||||
cp ${PWD}/organizations/ordererOrganizations/example.com/msp/config.yaml ${PWD}/organizations/ordererOrganizations/example.com/users/Admin@example.com/msp/config.yaml
|
cp ${PWD}/organizations/ordererOrganizations/example.com/msp/config.yaml ${PWD}/organizations/ordererOrganizations/example.com/users/Admin@example.com/msp/config.yaml
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ createChannelTx() {
|
||||||
set -x
|
set -x
|
||||||
configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/${CHANNEL_NAME}.tx -channelID $CHANNEL_NAME
|
configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/${CHANNEL_NAME}.tx -channelID $CHANNEL_NAME
|
||||||
res=$?
|
res=$?
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
if [ $res -ne 0 ]; then
|
if [ $res -ne 0 ]; then
|
||||||
echo "Failed to generate channel configuration transaction..."
|
echo "Failed to generate channel configuration transaction..."
|
||||||
exit 1
|
exit 1
|
||||||
|
|
@ -39,7 +39,7 @@ createAncorPeerTx() {
|
||||||
set -x
|
set -x
|
||||||
configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/${orgmsp}anchors.tx -channelID $CHANNEL_NAME -asOrg ${orgmsp}
|
configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/${orgmsp}anchors.tx -channelID $CHANNEL_NAME -asOrg ${orgmsp}
|
||||||
res=$?
|
res=$?
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
if [ $res -ne 0 ]; then
|
if [ $res -ne 0 ]; then
|
||||||
echo "Failed to generate anchor peer update transaction for ${orgmsp}..."
|
echo "Failed to generate anchor peer update transaction for ${orgmsp}..."
|
||||||
exit 1
|
exit 1
|
||||||
|
|
@ -58,7 +58,7 @@ createChannel() {
|
||||||
set -x
|
set -x
|
||||||
peer channel create -o localhost:7050 -c $CHANNEL_NAME --ordererTLSHostnameOverride orderer.example.com -f ./channel-artifacts/${CHANNEL_NAME}.tx --outputBlock ./channel-artifacts/${CHANNEL_NAME}.block --tls --cafile $ORDERER_CA >&log.txt
|
peer channel create -o localhost:7050 -c $CHANNEL_NAME --ordererTLSHostnameOverride orderer.example.com -f ./channel-artifacts/${CHANNEL_NAME}.tx --outputBlock ./channel-artifacts/${CHANNEL_NAME}.block --tls --cafile $ORDERER_CA >&log.txt
|
||||||
res=$?
|
res=$?
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
let rc=$res
|
let rc=$res
|
||||||
COUNTER=$(expr $COUNTER + 1)
|
COUNTER=$(expr $COUNTER + 1)
|
||||||
done
|
done
|
||||||
|
|
@ -81,7 +81,7 @@ joinChannel() {
|
||||||
set -x
|
set -x
|
||||||
peer channel join -b ./channel-artifacts/$CHANNEL_NAME.block >&log.txt
|
peer channel join -b ./channel-artifacts/$CHANNEL_NAME.block >&log.txt
|
||||||
res=$?
|
res=$?
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
let rc=$res
|
let rc=$res
|
||||||
COUNTER=$(expr $COUNTER + 1)
|
COUNTER=$(expr $COUNTER + 1)
|
||||||
done
|
done
|
||||||
|
|
@ -101,7 +101,7 @@ updateAnchorPeers() {
|
||||||
set -x
|
set -x
|
||||||
peer channel update -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com -c $CHANNEL_NAME -f ./channel-artifacts/${CORE_PEER_LOCALMSPID}anchors.tx --tls --cafile $ORDERER_CA >&log.txt
|
peer channel update -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com -c $CHANNEL_NAME -f ./channel-artifacts/${CORE_PEER_LOCALMSPID}anchors.tx --tls --cafile $ORDERER_CA >&log.txt
|
||||||
res=$?
|
res=$?
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
let rc=$res
|
let rc=$res
|
||||||
COUNTER=$(expr $COUNTER + 1)
|
COUNTER=$(expr $COUNTER + 1)
|
||||||
done
|
done
|
||||||
|
|
|
||||||
|
|
@ -153,7 +153,7 @@ packageChaincode() {
|
||||||
set -x
|
set -x
|
||||||
peer lifecycle chaincode package ${CC_NAME}.tar.gz --path ${CC_SRC_PATH} --lang ${CC_RUNTIME_LANGUAGE} --label ${CC_NAME}_${CC_VERSION} >&log.txt
|
peer lifecycle chaincode package ${CC_NAME}.tar.gz --path ${CC_SRC_PATH} --lang ${CC_RUNTIME_LANGUAGE} --label ${CC_NAME}_${CC_VERSION} >&log.txt
|
||||||
res=$?
|
res=$?
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
cat log.txt
|
cat log.txt
|
||||||
verifyResult $res "Chaincode packaging on peer0.org${ORG} has failed"
|
verifyResult $res "Chaincode packaging on peer0.org${ORG} has failed"
|
||||||
echo "===================== Chaincode is packaged on peer0.org${ORG} ===================== "
|
echo "===================== Chaincode is packaged on peer0.org${ORG} ===================== "
|
||||||
|
|
@ -167,7 +167,7 @@ installChaincode() {
|
||||||
set -x
|
set -x
|
||||||
peer lifecycle chaincode install ${CC_NAME}.tar.gz >&log.txt
|
peer lifecycle chaincode install ${CC_NAME}.tar.gz >&log.txt
|
||||||
res=$?
|
res=$?
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
cat log.txt
|
cat log.txt
|
||||||
verifyResult $res "Chaincode installation on peer0.org${ORG} has failed"
|
verifyResult $res "Chaincode installation on peer0.org${ORG} has failed"
|
||||||
echo "===================== Chaincode is installed on peer0.org${ORG} ===================== "
|
echo "===================== Chaincode is installed on peer0.org${ORG} ===================== "
|
||||||
|
|
@ -181,7 +181,7 @@ queryInstalled() {
|
||||||
set -x
|
set -x
|
||||||
peer lifecycle chaincode queryinstalled >&log.txt
|
peer lifecycle chaincode queryinstalled >&log.txt
|
||||||
res=$?
|
res=$?
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
cat log.txt
|
cat log.txt
|
||||||
PACKAGE_ID=$(sed -n "/${CC_NAME}_${CC_VERSION}/{s/^Package ID: //; s/, Label:.*$//; p;}" log.txt)
|
PACKAGE_ID=$(sed -n "/${CC_NAME}_${CC_VERSION}/{s/^Package ID: //; s/, Label:.*$//; p;}" log.txt)
|
||||||
verifyResult $res "Query installed on peer0.org${ORG} has failed"
|
verifyResult $res "Query installed on peer0.org${ORG} has failed"
|
||||||
|
|
@ -196,7 +196,7 @@ approveForMyOrg() {
|
||||||
set -x
|
set -x
|
||||||
peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile $ORDERER_CA --channelID $CHANNEL_NAME --name ${CC_NAME} --version ${CC_VERSION} --package-id ${PACKAGE_ID} --sequence ${CC_SEQUENCE} ${INIT_REQUIRED} ${CC_END_POLICY} ${CC_COLL_CONFIG} >&log.txt
|
peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile $ORDERER_CA --channelID $CHANNEL_NAME --name ${CC_NAME} --version ${CC_VERSION} --package-id ${PACKAGE_ID} --sequence ${CC_SEQUENCE} ${INIT_REQUIRED} ${CC_END_POLICY} ${CC_COLL_CONFIG} >&log.txt
|
||||||
res=$?
|
res=$?
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
cat log.txt
|
cat log.txt
|
||||||
verifyResult $res "Chaincode definition approved on peer0.org${ORG} on channel '$CHANNEL_NAME' failed"
|
verifyResult $res "Chaincode definition approved on peer0.org${ORG} on channel '$CHANNEL_NAME' failed"
|
||||||
echo "===================== Chaincode definition approved on peer0.org${ORG} on channel '$CHANNEL_NAME' ===================== "
|
echo "===================== Chaincode definition approved on peer0.org${ORG} on channel '$CHANNEL_NAME' ===================== "
|
||||||
|
|
@ -219,7 +219,7 @@ checkCommitReadiness() {
|
||||||
set -x
|
set -x
|
||||||
peer lifecycle chaincode checkcommitreadiness --channelID $CHANNEL_NAME --name ${CC_NAME} --version ${CC_VERSION} --sequence ${CC_SEQUENCE} ${INIT_REQUIRED} ${CC_END_POLICY} ${CC_COLL_CONFIG} --output json >&log.txt
|
peer lifecycle chaincode checkcommitreadiness --channelID $CHANNEL_NAME --name ${CC_NAME} --version ${CC_VERSION} --sequence ${CC_SEQUENCE} ${INIT_REQUIRED} ${CC_END_POLICY} ${CC_COLL_CONFIG} --output json >&log.txt
|
||||||
res=$?
|
res=$?
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
let rc=0
|
let rc=0
|
||||||
for var in "$@"; do
|
for var in "$@"; do
|
||||||
grep "$var" log.txt &>/dev/null || let rc=1
|
grep "$var" log.txt &>/dev/null || let rc=1
|
||||||
|
|
@ -249,7 +249,7 @@ commitChaincodeDefinition() {
|
||||||
set -x
|
set -x
|
||||||
peer lifecycle chaincode commit -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile $ORDERER_CA --channelID $CHANNEL_NAME --name ${CC_NAME} $PEER_CONN_PARMS --version ${CC_VERSION} --sequence ${CC_SEQUENCE} ${INIT_REQUIRED} ${CC_END_POLICY} ${CC_COLL_CONFIG} >&log.txt
|
peer lifecycle chaincode commit -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile $ORDERER_CA --channelID $CHANNEL_NAME --name ${CC_NAME} $PEER_CONN_PARMS --version ${CC_VERSION} --sequence ${CC_SEQUENCE} ${INIT_REQUIRED} ${CC_END_POLICY} ${CC_COLL_CONFIG} >&log.txt
|
||||||
res=$?
|
res=$?
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
cat log.txt
|
cat log.txt
|
||||||
verifyResult $res "Chaincode definition commit failed on peer0.org${ORG} on channel '$CHANNEL_NAME' failed"
|
verifyResult $res "Chaincode definition commit failed on peer0.org${ORG} on channel '$CHANNEL_NAME' failed"
|
||||||
echo "===================== Chaincode definition committed on channel '$CHANNEL_NAME' ===================== "
|
echo "===================== Chaincode definition committed on channel '$CHANNEL_NAME' ===================== "
|
||||||
|
|
@ -272,7 +272,7 @@ queryCommitted() {
|
||||||
set -x
|
set -x
|
||||||
peer lifecycle chaincode querycommitted --channelID $CHANNEL_NAME --name ${CC_NAME} >&log.txt
|
peer lifecycle chaincode querycommitted --channelID $CHANNEL_NAME --name ${CC_NAME} >&log.txt
|
||||||
res=$?
|
res=$?
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
test $res -eq 0 && VALUE=$(cat log.txt | grep -o '^Version: '$CC_VERSION', Sequence: [0-9]*, Endorsement Plugin: escc, Validation Plugin: vscc')
|
test $res -eq 0 && VALUE=$(cat log.txt | grep -o '^Version: '$CC_VERSION', Sequence: [0-9]*, Endorsement Plugin: escc, Validation Plugin: vscc')
|
||||||
test "$VALUE" = "$EXPECTED_RESULT" && let rc=0
|
test "$VALUE" = "$EXPECTED_RESULT" && let rc=0
|
||||||
COUNTER=$(expr $COUNTER + 1)
|
COUNTER=$(expr $COUNTER + 1)
|
||||||
|
|
@ -303,7 +303,7 @@ chaincodeInvokeInit() {
|
||||||
echo invoke fcn call:${fcn_call}
|
echo invoke fcn call:${fcn_call}
|
||||||
peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile $ORDERER_CA -C $CHANNEL_NAME -n ${CC_NAME} $PEER_CONN_PARMS --isInit -c ${fcn_call} >&log.txt
|
peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile $ORDERER_CA -C $CHANNEL_NAME -n ${CC_NAME} $PEER_CONN_PARMS --isInit -c ${fcn_call} >&log.txt
|
||||||
res=$?
|
res=$?
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
cat log.txt
|
cat log.txt
|
||||||
verifyResult $res "Invoke execution on $PEERS failed "
|
verifyResult $res "Invoke execution on $PEERS failed "
|
||||||
echo "===================== Invoke transaction successful on $PEERS on channel '$CHANNEL_NAME' ===================== "
|
echo "===================== Invoke transaction successful on $PEERS on channel '$CHANNEL_NAME' ===================== "
|
||||||
|
|
@ -324,7 +324,7 @@ chaincodeQuery() {
|
||||||
set -x
|
set -x
|
||||||
peer chaincode query -C $CHANNEL_NAME -n ${CC_NAME} -c '{"Args":["queryAllCars"]}' >&log.txt
|
peer chaincode query -C $CHANNEL_NAME -n ${CC_NAME} -c '{"Args":["queryAllCars"]}' >&log.txt
|
||||||
res=$?
|
res=$?
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
let rc=$res
|
let rc=$res
|
||||||
COUNTER=$(expr $COUNTER + 1)
|
COUNTER=$(expr $COUNTER + 1)
|
||||||
done
|
done
|
||||||
|
|
|
||||||
|
|
@ -40,12 +40,12 @@ fetchChannelConfig() {
|
||||||
echo "Fetching the most recent configuration block for the channel"
|
echo "Fetching the most recent configuration block for the channel"
|
||||||
set -x
|
set -x
|
||||||
peer channel fetch config config_block.pb -o orderer.example.com:7050 --ordererTLSHostnameOverride orderer.example.com -c $CHANNEL --tls --cafile $ORDERER_CA
|
peer channel fetch config config_block.pb -o orderer.example.com:7050 --ordererTLSHostnameOverride orderer.example.com -c $CHANNEL --tls --cafile $ORDERER_CA
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
|
|
||||||
echo "Decoding config block to JSON and isolating config to ${OUTPUT}"
|
echo "Decoding config block to JSON and isolating config to ${OUTPUT}"
|
||||||
set -x
|
set -x
|
||||||
configtxlator proto_decode --input config_block.pb --type common.Block | jq .data.data[0].payload.data.config >"${OUTPUT}"
|
configtxlator proto_decode --input config_block.pb --type common.Block | jq .data.data[0].payload.data.config >"${OUTPUT}"
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
# createConfigUpdate <channel_id> <original_config.json> <modified_config.json> <output.pb>
|
# createConfigUpdate <channel_id> <original_config.json> <modified_config.json> <output.pb>
|
||||||
|
|
@ -64,7 +64,7 @@ createConfigUpdate() {
|
||||||
configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate >config_update.json
|
configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate >config_update.json
|
||||||
echo '{"payload":{"header":{"channel_header":{"channel_id":"'$CHANNEL'", "type":2}},"data":{"config_update":'$(cat config_update.json)'}}}' | jq . >config_update_in_envelope.json
|
echo '{"payload":{"header":{"channel_header":{"channel_id":"'$CHANNEL'", "type":2}},"data":{"config_update":'$(cat config_update.json)'}}}' | jq . >config_update_in_envelope.json
|
||||||
configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope >"${OUTPUT}"
|
configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope >"${OUTPUT}"
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
# signConfigtxAsPeerOrg <org> <configtx.pb>
|
# signConfigtxAsPeerOrg <org> <configtx.pb>
|
||||||
|
|
@ -75,7 +75,7 @@ signConfigtxAsPeerOrg() {
|
||||||
setGlobals $PEERORG
|
setGlobals $PEERORG
|
||||||
set -x
|
set -x
|
||||||
peer channel signconfigtx -f "${TX}"
|
peer channel signconfigtx -f "${TX}"
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
echo
|
echo
|
||||||
|
|
@ -88,7 +88,7 @@ fetchChannelConfig 1 ${CHANNEL_NAME} config.json
|
||||||
# Modify the configuration to append the new org
|
# Modify the configuration to append the new org
|
||||||
set -x
|
set -x
|
||||||
jq -s '.[0] * {"channel_group":{"groups":{"Application":{"groups": {"Org3MSP":.[1]}}}}}' config.json ./organizations/peerOrganizations/org3.example.com/org3.json > modified_config.json
|
jq -s '.[0] * {"channel_group":{"groups":{"Application":{"groups": {"Org3MSP":.[1]}}}}}' config.json ./organizations/peerOrganizations/org3.example.com/org3.json > modified_config.json
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
|
|
||||||
# Compute a config update, based on the differences between config.json and modified_config.json, write it as a transaction to org3_update_in_envelope.pb
|
# Compute a config update, based on the differences between config.json and modified_config.json, write it as a transaction to org3_update_in_envelope.pb
|
||||||
createConfigUpdate ${CHANNEL_NAME} config.json modified_config.json org3_update_in_envelope.pb
|
createConfigUpdate ${CHANNEL_NAME} config.json modified_config.json org3_update_in_envelope.pb
|
||||||
|
|
@ -107,7 +107,7 @@ echo
|
||||||
setGlobals 2
|
setGlobals 2
|
||||||
set -x
|
set -x
|
||||||
peer channel update -f org3_update_in_envelope.pb -c ${CHANNEL_NAME} -o orderer.example.com:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile ${ORDERER_CA}
|
peer channel update -f org3_update_in_envelope.pb -c ${CHANNEL_NAME} -o orderer.example.com:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile ${ORDERER_CA}
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "========= Config transaction to add org3 to network submitted! =========== "
|
echo "========= Config transaction to add org3 to network submitted! =========== "
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ joinChannelWithRetry() {
|
||||||
set -x
|
set -x
|
||||||
peer channel join -b $CHANNEL_NAME.block >&log.txt
|
peer channel join -b $CHANNEL_NAME.block >&log.txt
|
||||||
res=$?
|
res=$?
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
cat log.txt
|
cat log.txt
|
||||||
if [ $res -ne 0 -a $COUNTER -lt $MAX_RETRY ]; then
|
if [ $res -ne 0 -a $COUNTER -lt $MAX_RETRY ]; then
|
||||||
COUNTER=$(expr $COUNTER + 1)
|
COUNTER=$(expr $COUNTER + 1)
|
||||||
|
|
@ -54,7 +54,7 @@ echo "Fetching channel config block from orderer..."
|
||||||
set -x
|
set -x
|
||||||
peer channel fetch 0 $CHANNEL_NAME.block -o orderer.example.com:7050 --ordererTLSHostnameOverride orderer.example.com -c $CHANNEL_NAME --tls --cafile $ORDERER_CA >&log.txt
|
peer channel fetch 0 $CHANNEL_NAME.block -o orderer.example.com:7050 --ordererTLSHostnameOverride orderer.example.com -c $CHANNEL_NAME --tls --cafile $ORDERER_CA >&log.txt
|
||||||
res=$?
|
res=$?
|
||||||
set +x
|
{ set +x; } 2>/dev/null
|
||||||
cat log.txt
|
cat log.txt
|
||||||
verifyResult $res "Fetching config block from orderer has Failed"
|
verifyResult $res "Fetching config block from orderer has Failed"
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue