From 124adb43f964c4ef62836c547bba851a4d10bfb3 Mon Sep 17 00:00:00 2001
From: jkneubuh <86427252+jkneubuh@users.noreply.github.com>
Date: Wed, 18 Jan 2023 11:05:40 -0500
Subject: [PATCH 01/30] run test suites with 2.5 binaries and images (#906)
* run test suites with 2.5 binaries and images
Signed-off-by: Josh Kneubuhl
* Swap to use the Helper Function to create policies (#907)
The old way used the direct protobuf functions, there is a helper function
in the chaincode does exactly that.
Signed-off-by: Matthew B White
Signed-off-by: Josh Kneubuhl
Signed-off-by: Matthew B White
Co-authored-by: Matthew B White
---
.github/actions/test-network-setup/action.yaml | 13 +++++++++++--
.github/workflows/lint.yaml | 4 ++--
.github/workflows/rest-sample.yaml | 4 ++--
.github/workflows/test-fsat.yaml | 1 +
.github/workflows/test-network-basic.yaml | 4 ++--
.github/workflows/test-network-events.yaml | 4 ++--
.github/workflows/test-network-gateway.yaml | 4 ++--
.github/workflows/test-network-hsm.yaml | 4 ++--
.github/workflows/test-network-k8s.yaml | 4 ++--
.github/workflows/test-network-ledger.yaml | 4 ++--
.github/workflows/test-network-off-chain.yaml | 4 ++--
.github/workflows/test-network-private.yaml | 4 ++--
.github/workflows/test-network-sbe.yaml | 4 ++--
.github/workflows/test-network-secured.yaml | 4 ++--
.../chaincode-typescript/package.json | 4 ++--
15 files changed, 38 insertions(+), 28 deletions(-)
diff --git a/.github/actions/test-network-setup/action.yaml b/.github/actions/test-network-setup/action.yaml
index ed6587c6..f36169b2 100644
--- a/.github/actions/test-network-setup/action.yaml
+++ b/.github/actions/test-network-setup/action.yaml
@@ -10,6 +10,12 @@ inputs:
java-version:
description: Version of JDK
default: 11.x
+ fabric-version:
+ description: Version of Hyperledger Fabric
+ default: 2.5.0-alpha3
+ ca-version:
+ description: Version of Hyperledger Fabric CA
+ default: 1.5.6-beta3
runs:
using: "composite"
@@ -35,12 +41,15 @@ runs:
- name: Install fabric CLI
shell: bash
run: |
- curl -sSL https://raw.githubusercontent.com/hyperledger/fabric/main/scripts/install-fabric.sh | bash -s -- binary
+ curl -sSL https://raw.githubusercontent.com/hyperledger/fabric/main/scripts/install-fabric.sh \
+ | bash -s -- binary --fabric-version ${{ inputs.fabric-version }} --ca-version ${{ inputs.ca-version }}
echo ${PWD}/bin >> $GITHUB_PATH
- name: Pull Fabric Docker Images
shell: bash
- run: curl -sSL https://raw.githubusercontent.com/hyperledger/fabric/main/scripts/install-fabric.sh | bash -s -- docker
+ run: |
+ curl -sSL https://raw.githubusercontent.com/hyperledger/fabric/main/scripts/install-fabric.sh \
+ | bash -s -- docker --fabric-version ${{ inputs.fabric-version }} --ca-version ${{ inputs.ca-version }}
- name: Install retry CLI
shell: bash
diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml
index 4ab1ff67..028fea68 100644
--- a/.github/workflows/lint.yaml
+++ b/.github/workflows/lint.yaml
@@ -7,9 +7,9 @@ run-name: ${{ github.actor }} is linting fabric-samples 🎉
on:
workflow_dispatch:
push:
- branches: [ "main" ]
+ branches: [ "main", "release-2.5" ]
pull_request:
- branches: [ "main" ]
+ branches: [ "main", "release-2.5" ]
env:
GO_VER: 1.18.3
diff --git a/.github/workflows/rest-sample.yaml b/.github/workflows/rest-sample.yaml
index ff8659f8..f2cae6eb 100644
--- a/.github/workflows/rest-sample.yaml
+++ b/.github/workflows/rest-sample.yaml
@@ -10,10 +10,10 @@ env:
on:
workflow_dispatch:
push:
- branches: [ "main" ]
+ branches: [ "main", "release-2.5" ]
paths: [ "asset-transfer-basic/rest-api-typescript/**" ]
pull_request:
- branches: [ "main" ]
+ branches: [ "main", "release-2.5" ]
paths: [ "asset-transfer-basic/rest-api-typescript/**" ]
jobs:
diff --git a/.github/workflows/test-fsat.yaml b/.github/workflows/test-fsat.yaml
index 934161c6..09d58ec4 100644
--- a/.github/workflows/test-fsat.yaml
+++ b/.github/workflows/test-fsat.yaml
@@ -6,6 +6,7 @@ on:
pull_request:
branches:
- "main"
+ - "release-2.5"
paths:
- "full-stack-asset-transfer-guide/**"
diff --git a/.github/workflows/test-network-basic.yaml b/.github/workflows/test-network-basic.yaml
index eb20869d..72b7c1db 100644
--- a/.github/workflows/test-network-basic.yaml
+++ b/.github/workflows/test-network-basic.yaml
@@ -7,9 +7,9 @@ run-name: ${{ github.actor }} is running the Test Network Basic tests 🔎
on:
workflow_dispatch:
push:
- branches: [ "main" ]
+ branches: [ "main", "release-2.5" ]
pull_request:
- branches: [ "main" ]
+ branches: [ "main", "release-2.5" ]
jobs:
basic:
diff --git a/.github/workflows/test-network-events.yaml b/.github/workflows/test-network-events.yaml
index a1e3e996..4a6ebd99 100644
--- a/.github/workflows/test-network-events.yaml
+++ b/.github/workflows/test-network-events.yaml
@@ -7,9 +7,9 @@ run-name: ${{ github.actor }} is running the Test Network Events tests 💡
on:
workflow_dispatch:
push:
- branches: [ "main" ]
+ branches: [ "main", "release-2.5" ]
pull_request:
- branches: [ "main" ]
+ branches: [ "main", "release-2.5" ]
jobs:
events:
diff --git a/.github/workflows/test-network-gateway.yaml b/.github/workflows/test-network-gateway.yaml
index a5f195ce..06477397 100644
--- a/.github/workflows/test-network-gateway.yaml
+++ b/.github/workflows/test-network-gateway.yaml
@@ -7,9 +7,9 @@ run-name: ${{ github.actor }} is running the Test Network Gateway tests 🖥️
on:
workflow_dispatch:
push:
- branches: [ "main" ]
+ branches: [ "main", "release-2.5" ]
pull_request:
- branches: [ "main" ]
+ branches: [ "main", "release-2.5" ]
jobs:
gateway:
diff --git a/.github/workflows/test-network-hsm.yaml b/.github/workflows/test-network-hsm.yaml
index 51093488..189a77a1 100644
--- a/.github/workflows/test-network-hsm.yaml
+++ b/.github/workflows/test-network-hsm.yaml
@@ -7,9 +7,9 @@ run-name: ${{ github.actor }} is running the Test Network HSM tests 🍏
on:
workflow_dispatch:
push:
- branches: [ "main" ]
+ branches: [ "main", "release-2.5" ]
pull_request:
- branches: [ "main" ]
+ branches: [ "main", "release-2.5" ]
jobs:
hsm:
diff --git a/.github/workflows/test-network-k8s.yaml b/.github/workflows/test-network-k8s.yaml
index cadb4376..7898e820 100644
--- a/.github/workflows/test-network-k8s.yaml
+++ b/.github/workflows/test-network-k8s.yaml
@@ -7,9 +7,9 @@ run-name: ${{ github.actor }} is testing the Kubernetes Test Network 🍒
on:
workflow_dispatch:
push:
- branches: [ "main" ]
+ branches: [ "main", "release-2.5" ]
pull_request:
- branches: [ "main" ]
+ branches: [ "main", "release-2.5" ]
jobs:
ccaas-java:
diff --git a/.github/workflows/test-network-ledger.yaml b/.github/workflows/test-network-ledger.yaml
index 60c566c9..5bc6669b 100644
--- a/.github/workflows/test-network-ledger.yaml
+++ b/.github/workflows/test-network-ledger.yaml
@@ -7,9 +7,9 @@ run-name: ${{ github.actor }} is running the Test Network Ledger tests 🥑
on:
workflow_dispatch:
push:
- branches: [ "main" ]
+ branches: [ "main", "release-2.5" ]
pull_request:
- branches: [ "main" ]
+ branches: [ "main", "release-2.5" ]
jobs:
basic:
diff --git a/.github/workflows/test-network-off-chain.yaml b/.github/workflows/test-network-off-chain.yaml
index fc10b968..1e5840d4 100644
--- a/.github/workflows/test-network-off-chain.yaml
+++ b/.github/workflows/test-network-off-chain.yaml
@@ -7,9 +7,9 @@ run-name: ${{ github.actor }} is running the Test Network Off Chain tests 🍔
on:
workflow_dispatch:
push:
- branches: [ "main" ]
+ branches: [ "main", "release-2.5" ]
pull_request:
- branches: [ "main" ]
+ branches: [ "main", "release-2.5" ]
jobs:
off-chain:
diff --git a/.github/workflows/test-network-private.yaml b/.github/workflows/test-network-private.yaml
index b8185e4d..36ec02de 100644
--- a/.github/workflows/test-network-private.yaml
+++ b/.github/workflows/test-network-private.yaml
@@ -7,9 +7,9 @@ run-name: ${{ github.actor }} is running the Test Network Private tests 🔒
on:
workflow_dispatch:
push:
- branches: [ "main" ]
+ branches: [ "main", "release-2.5" ]
pull_request:
- branches: [ "main" ]
+ branches: [ "main", "release-2.5" ]
jobs:
private:
diff --git a/.github/workflows/test-network-sbe.yaml b/.github/workflows/test-network-sbe.yaml
index 37682f5c..51a12694 100644
--- a/.github/workflows/test-network-sbe.yaml
+++ b/.github/workflows/test-network-sbe.yaml
@@ -7,9 +7,9 @@ run-name: ${{ github.actor }} is running the Test Network SBE tests 🎵
on:
workflow_dispatch:
push:
- branches: [ "main" ]
+ branches: [ "main", "release-2.5" ]
pull_request:
- branches: [ "main" ]
+ branches: [ "main", "release-2.5" ]
jobs:
SBE:
diff --git a/.github/workflows/test-network-secured.yaml b/.github/workflows/test-network-secured.yaml
index a0df52ce..df075158 100644
--- a/.github/workflows/test-network-secured.yaml
+++ b/.github/workflows/test-network-secured.yaml
@@ -7,9 +7,9 @@ run-name: ${{ github.actor }} is running the Test Network Secured tests 🔔
on:
workflow_dispatch:
push:
- branches: [ "main" ]
+ branches: [ "main", "release-2.5" ]
pull_request:
- branches: [ "main" ]
+ branches: [ "main", "release-2.5" ]
jobs:
secured:
diff --git a/asset-transfer-sbe/chaincode-typescript/package.json b/asset-transfer-sbe/chaincode-typescript/package.json
index 43be5e77..7250279f 100644
--- a/asset-transfer-sbe/chaincode-typescript/package.json
+++ b/asset-transfer-sbe/chaincode-typescript/package.json
@@ -21,8 +21,8 @@
"author": "Hyperledger",
"license": "Apache-2.0",
"dependencies": {
- "fabric-contract-api": "^2.0.0",
- "fabric-shim": "^2.0.0"
+ "fabric-contract-api": "^2.5.0",
+ "fabric-shim": "^2.5.0"
},
"devDependencies": {
"@types/chai": "^4.2.11",
From 795673dee393fe22ddc6bfef565751942defe3b2 Mon Sep 17 00:00:00 2001
From: Matthew B White
Date: Mon, 23 Jan 2023 16:40:52 +0000
Subject: [PATCH 02/30] Add in examples and notes on using PurgePrivateData
(#878)
* Add in examples and notes on using PurgePrivateData
- Update the configtx.yaml to enable the 2.5 capabillity
- Added purge into the chancode
- Added pruge into the application client code.
Signed-off-by: Matthew B White
* Temporarily remove java cc test
Signed-off-by: Matthew B White
---
.../application-gateway-typescript/src/app.ts | 15 +++++
.../chaincode-go/chaincode/asset_transfer.go | 62 +++++++++++++++++++
.../chaincode-go/go.mod | 2 +-
.../chaincode-go/go.sum | 2 +
.../chaincode-java/build.gradle | 2 +-
.../samples/privatedata/AssetTransfer.java | 50 +++++++++++++++
ci/scripts/lint-java.sh | 3 +-
interest_rate_swaps/network/configtx.yaml | 12 ++--
test-network-nano-bash/configtx.yaml | 12 ++--
test-network/configtx/configtx.yaml | 13 ++--
10 files changed, 149 insertions(+), 24 deletions(-)
diff --git a/asset-transfer-private-data/application-gateway-typescript/src/app.ts b/asset-transfer-private-data/application-gateway-typescript/src/app.ts
index 0513807d..ac292330 100644
--- a/asset-transfer-private-data/application-gateway-typescript/src/app.ts
+++ b/asset-transfer-private-data/application-gateway-typescript/src/app.ts
@@ -129,6 +129,10 @@ async function main(): Promise {
// Delete AssetID2 as Org1.
await deleteAsset(contractOrg1, assetID2);
+
+ // Trigger a purge of the private data for the asset
+ // The previous delete is optinal if purge is used
+ await purgeAsset(contractOrg1, assetID2);
} finally {
gatewayOrg1.close();
clientOrg1.close();
@@ -261,6 +265,17 @@ async function deleteAsset(contract: Contract, assetID: string): Promise {
console.log('*** Transaction committed successfully');
}
+
+async function purgeAsset(contract: Contract, assetID: string): Promise {
+ console.log('\n--> Submit Transaction: PurgeAsset, ID:', assetID);
+ const dataForPurge = { assetID };
+ await contract.submit('PurgeAsset', {
+ transientData: { asset_purge: JSON.stringify(dataForPurge) },
+ });
+
+ console.log('*** Transaction committed successfully');
+}
+
async function readAssetPrivateDetails(contract: Contract, assetID: string, collectionName: string): Promise {
console.log(`\n--> Evaluate Transaction: ReadAssetPrivateDetails from ${collectionName}, ID: ${assetID}`);
diff --git a/asset-transfer-private-data/chaincode-go/chaincode/asset_transfer.go b/asset-transfer-private-data/chaincode-go/chaincode/asset_transfer.go
index 92c10424..a377e57c 100644
--- a/asset-transfer-private-data/chaincode-go/chaincode/asset_transfer.go
+++ b/asset-transfer-private-data/chaincode-go/chaincode/asset_transfer.go
@@ -475,6 +475,68 @@ func (s *SmartContract) DeleteAsset(ctx contractapi.TransactionContextInterface)
}
+// PurgeAsset can be used by the owner of the asset to delete the asset
+// Trigger removal of the asset
+func (s *SmartContract) PurgeAsset(ctx contractapi.TransactionContextInterface) error {
+
+ transientMap, err := ctx.GetStub().GetTransient()
+ if err != nil {
+ return fmt.Errorf("Error getting transient: %v", err)
+ }
+
+ // Asset properties are private, therefore they get passed in transient field
+ transientDeleteJSON, ok := transientMap["asset_purge"]
+ if !ok {
+ return fmt.Errorf("asset to purge not found in the transient map")
+ }
+
+ type assetPurge struct {
+ ID string `json:"assetID"`
+ }
+
+ var assetPurgeInput assetPurge
+ err = json.Unmarshal(transientDeleteJSON, &assetPurgeInput)
+ if err != nil {
+ return fmt.Errorf("failed to unmarshal JSON: %v", err)
+ }
+
+ if len(assetPurgeInput.ID) == 0 {
+ return fmt.Errorf("assetID field must be a non-empty string")
+ }
+
+ // Verify that the client is submitting request to peer in their organization
+ err = verifyClientOrgMatchesPeerOrg(ctx)
+ if err != nil {
+ return fmt.Errorf("PurgeAsset cannot be performed: Error %v", err)
+ }
+
+ log.Printf("Purging Asset: %v", assetPurgeInput.ID)
+
+ // Note that there is no check here to see if the id exist; it might have been 'deleted' already
+ // so a check here is pointless. We would need to call purge irrespective of the result
+ // A delete can be called before purge, but is not essential
+
+ ownerCollection, err := getCollectionName(ctx) // Get owners collection
+ if err != nil {
+ return fmt.Errorf("failed to infer private collection name for the org: %v", err)
+ }
+
+ // delete the asset from state
+ err = ctx.GetStub().PurgePrivateData(assetCollection, assetPurgeInput.ID)
+ if err != nil {
+ return fmt.Errorf("failed to purge state from asset collection: %v", err)
+ }
+
+ // Finally, delete private details of asset
+ err = ctx.GetStub().PurgePrivateData(ownerCollection, assetPurgeInput.ID)
+ if err != nil {
+ return fmt.Errorf("failed to purge state from owner collection: %v", err)
+ }
+
+ return nil
+
+}
+
// DeleteTranferAgreement can be used by the buyer to withdraw a proposal from
// the asset collection and from his own collection.
func (s *SmartContract) DeleteTranferAgreement(ctx contractapi.TransactionContextInterface) error {
diff --git a/asset-transfer-private-data/chaincode-go/go.mod b/asset-transfer-private-data/chaincode-go/go.mod
index ba25be99..305208de 100644
--- a/asset-transfer-private-data/chaincode-go/go.mod
+++ b/asset-transfer-private-data/chaincode-go/go.mod
@@ -3,7 +3,7 @@ module github.com/hyperledger/fabric-samples/asset-transfer-private-data/chainco
go 1.17
require (
- github.com/hyperledger/fabric-chaincode-go v0.0.0-20220720122508-9207360bbddd
+ github.com/hyperledger/fabric-chaincode-go v0.0.0-20220920210243-7bc6fa0dd58b
github.com/hyperledger/fabric-contract-api-go v1.2.0
github.com/hyperledger/fabric-protos-go v0.0.0-20220613214546-bf864f01d75e
github.com/stretchr/testify v1.8.0
diff --git a/asset-transfer-private-data/chaincode-go/go.sum b/asset-transfer-private-data/chaincode-go/go.sum
index 6d35e832..f352bca5 100644
--- a/asset-transfer-private-data/chaincode-go/go.sum
+++ b/asset-transfer-private-data/chaincode-go/go.sum
@@ -165,6 +165,8 @@ github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/hyperledger/fabric-chaincode-go v0.0.0-20220720122508-9207360bbddd h1:AIa0b7UPrt8e1YN4/68vhNnPxy/Mrgq9d2bYJ6O/KTE=
github.com/hyperledger/fabric-chaincode-go v0.0.0-20220720122508-9207360bbddd/go.mod h1:OxME3M0bbgoWYHpXIVMzpbXgFqrTZnFmlH0Cpml54m0=
+github.com/hyperledger/fabric-chaincode-go v0.0.0-20220920210243-7bc6fa0dd58b h1:MGT5rdajc4zbsbU7yMzkLJmsiRwJk5gBX5OdpU117Bg=
+github.com/hyperledger/fabric-chaincode-go v0.0.0-20220920210243-7bc6fa0dd58b/go.mod h1:OxME3M0bbgoWYHpXIVMzpbXgFqrTZnFmlH0Cpml54m0=
github.com/hyperledger/fabric-contract-api-go v1.2.0 h1:BmArPRmTjiC2brHk2FNlDoJ8bOI0ExKZhj2YqWAiv5o=
github.com/hyperledger/fabric-contract-api-go v1.2.0/go.mod h1:GU2NV95E5LNkFTCL3xcPgXzi8QNLXBZhx7DGnKskuqw=
github.com/hyperledger/fabric-protos-go v0.0.0-20220613214546-bf864f01d75e h1:Ae2p0e+v5ekrl4KgkbCStBTSoV67Cg9fPkEWrv0f3nk=
diff --git a/asset-transfer-private-data/chaincode-java/build.gradle b/asset-transfer-private-data/chaincode-java/build.gradle
index bc59a38f..e5acd742 100644
--- a/asset-transfer-private-data/chaincode-java/build.gradle
+++ b/asset-transfer-private-data/chaincode-java/build.gradle
@@ -14,7 +14,7 @@ version '1.0-SNAPSHOT'
dependencies {
- implementation 'org.hyperledger.fabric-chaincode-java:fabric-chaincode-shim:2.+'
+ implementation 'org.hyperledger.fabric-chaincode-java:fabric-chaincode-shim:2.5.+'
implementation 'org.json:json:+'
testImplementation 'org.hyperledger.fabric-chaincode-java:fabric-chaincode-shim:2.+'
diff --git a/asset-transfer-private-data/chaincode-java/src/main/java/org/hyperledger/fabric/samples/privatedata/AssetTransfer.java b/asset-transfer-private-data/chaincode-java/src/main/java/org/hyperledger/fabric/samples/privatedata/AssetTransfer.java
index 94a261c4..6467f2c8 100644
--- a/asset-transfer-private-data/chaincode-java/src/main/java/org/hyperledger/fabric/samples/privatedata/AssetTransfer.java
+++ b/asset-transfer-private-data/chaincode-java/src/main/java/org/hyperledger/fabric/samples/privatedata/AssetTransfer.java
@@ -488,6 +488,9 @@ public final class AssetTransfer implements ContractInterface {
* Deletes a asset & related details from the ledger.
* Input in transient map: asset_delete
*
+ * This deletes the private data, but does not trigger an immediate cleanup
+ * of the history. To specifically force removal right now use purge
+ *
* @param ctx the transaction context
*/
@Transaction(intent = Transaction.TYPE.SUBMIT)
@@ -539,6 +542,53 @@ public final class AssetTransfer implements ContractInterface {
stub.delPrivateData(ownersCollectionName, assetID);
}
+ /**
+ * Purges the history of the asset from Private Data
+ * (delete does not need to be called as well)
+ * Input in transient map: asset_delete
+ *
+ * @param ctx the transaction context
+ */
+ @Transaction(intent = Transaction.TYPE.SUBMIT)
+ public void PurgeAsset(final Context ctx) {
+ ChaincodeStub stub = ctx.getStub();
+ Map transientMap = ctx.getStub().getTransient();
+ if (!transientMap.containsKey("asset_purge")) {
+ String errorMessage = String.format("PurgeAsset call must specify 'asset_purge' in Transient map input");
+ System.err.println(errorMessage);
+ throw new ChaincodeException(errorMessage, AssetTransferErrors.INCOMPLETE_INPUT.toString());
+ }
+
+ byte[] transientAssetJSON = transientMap.get("asset_purge");
+ final String assetID;
+
+ try {
+ JSONObject json = new JSONObject(new String(transientAssetJSON, UTF_8));
+ assetID = json.getString("assetID");
+
+ } catch (Exception err) {
+ String errorMessage = String.format("TransientMap deserialized error: %s ", err);
+ System.err.println(errorMessage);
+ throw new ChaincodeException(errorMessage, AssetTransferErrors.INCOMPLETE_INPUT.toString());
+ }
+
+ // Note that there is no check here to see if the id exist; it might have been 'deleted' already
+ // so a check here is pointless. We would need to call purge irrespective of the result
+ // A delete can be called before purge, but is not essential
+
+ String ownersCollectionName = getCollectionName(ctx);
+ verifyClientOrgMatchesPeerOrg(ctx);
+
+ // delete the key from asset collection
+ System.out.printf("PurgeAsset: collection %s, ID %s\n", ASSET_COLLECTION_NAME, assetID);
+ stub.purgePrivateData(ASSET_COLLECTION_NAME, assetID);
+
+ // Finally, delete private details of asset
+ System.out.printf("PurgeAsset: collection %s, ID %s\n", ownersCollectionName, assetID);
+ stub.purgePrivateData(ownersCollectionName, assetID);
+ }
+
+
// Used by TransferAsset to verify that the transfer is being initiated by the owner and that
// the buyer has agreed to the same appraisal value as the owner
private void verifyAgreement(final Context ctx, final String assetID, final String owner, final String buyerMSP) {
diff --git a/ci/scripts/lint-java.sh b/ci/scripts/lint-java.sh
index 327a91e7..82f3a810 100755
--- a/ci/scripts/lint-java.sh
+++ b/ci/scripts/lint-java.sh
@@ -8,7 +8,8 @@ function print() {
echo -e "${GREEN}${1}${NC}"
}
-dirs=("$(find . -name "*-java" -type d -not -path '*/.*')")
+# remove the java asset-private-data until the publishing issues have been resolved
+dirs=("$(find . -name "*-java" -type d -not -path '*/.*' -not -path '*/asset-transfer-private-data/*')")
for dir in $dirs; do
print "Linting $dir"
pushd $dir
diff --git a/interest_rate_swaps/network/configtx.yaml b/interest_rate_swaps/network/configtx.yaml
index 2d1c6cae..43948e72 100644
--- a/interest_rate_swaps/network/configtx.yaml
+++ b/interest_rate_swaps/network/configtx.yaml
@@ -269,13 +269,11 @@ Capabilities:
# used with prior release orderers.
# Set the value of the capability to true to require it.
Application: &ApplicationCapabilities
- # V2_0 application capability ensures that peers behave according
- # to v2.0 application capabilities. Peers from
- # prior releases would behave in an incompatible way, and are therefore
- # not able to participate in channels at v2.0 application capability.
- # Prior to enabling V2.0 application capabilities, ensure that all
- # peers on channel are at v2.0.0 or later.
- V2_0: true
+ # V2.5 for Application enables the new non-backwards compatible
+ # features of fabric v2.5, namely the ability to purge private data.
+ # Prior to enabling V2.5 application capabilities, ensure that all
+ # peers on a channel are at v2.5.0 or later.
+ V2_5: true
################################################################################
#
diff --git a/test-network-nano-bash/configtx.yaml b/test-network-nano-bash/configtx.yaml
index e1634014..0a0c05d6 100644
--- a/test-network-nano-bash/configtx.yaml
+++ b/test-network-nano-bash/configtx.yaml
@@ -163,13 +163,11 @@ Capabilities:
# used with prior release orderers.
# Set the value of the capability to true to require it.
Application: &ApplicationCapabilities
- # V2_0 application capability ensures that peers behave according
- # to v2.0 application capabilities. Peers from
- # prior releases would behave in an incompatible way, and are therefore
- # not able to participate in channels at v2.0 application capability.
- # Prior to enabling V2.0 application capabilities, ensure that all
- # peers on channel are at v2.0.0 or later.
- V2_0: true
+ # V2.5 for Application enables the new non-backwards compatible
+ # features of fabric v2.5, namely the ability to purge private data.
+ # Prior to enabling V2.5 application capabilities, ensure that all
+ # peers on a channel are at v2.5.0 or later.
+ V2_5: true
################################################################################
#
diff --git a/test-network/configtx/configtx.yaml b/test-network/configtx/configtx.yaml
index 48bd1d75..01fb15fb 100644
--- a/test-network/configtx/configtx.yaml
+++ b/test-network/configtx/configtx.yaml
@@ -129,6 +129,7 @@ Capabilities:
# Prior to enabling V2.0 channel capabilities, ensure that all
# orderers and peers on a channel are at v2.0.0 or later.
V2_0: true
+
# Orderer capabilities apply only to the orderers, and may be safely
# used with prior release peers.
@@ -146,13 +147,11 @@ Capabilities:
# used with prior release orderers.
# Set the value of the capability to true to require it.
Application: &ApplicationCapabilities
- # V2_0 application capability ensures that peers behave according
- # to v2.0 application capabilities. Peers from
- # prior releases would behave in an incompatible way, and are therefore
- # not able to participate in channels at v2.0 application capability.
- # Prior to enabling V2.0 application capabilities, ensure that all
- # peers on channel are at v2.0.0 or later.
- V2_0: true
+ # V2.5 for Application enables the new non-backwards compatible
+ # features of fabric v2.5, namely the ability to purge private data.
+ # Prior to enabling V2.5 application capabilities, ensure that all
+ # peers on a channel are at v2.5.0 or later.
+ V2_5: true
################################################################################
#
From 7c46fdb0871e3d092fa105498f36b7d41464812e Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 24 Jan 2023 08:47:59 -0500
Subject: [PATCH 03/30] Bump cookiejar in
/asset-transfer-basic/rest-api-typescript (#916)
Bumps [cookiejar](https://github.com/bmeck/node-cookiejar) from 2.1.2 to 2.1.4.
- [Release notes](https://github.com/bmeck/node-cookiejar/releases)
- [Commits](https://github.com/bmeck/node-cookiejar/commits)
---
updated-dependencies:
- dependency-name: cookiejar
dependency-type: indirect
...
Signed-off-by: dependabot[bot]
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
.../rest-api-typescript/package-lock.json | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/asset-transfer-basic/rest-api-typescript/package-lock.json b/asset-transfer-basic/rest-api-typescript/package-lock.json
index 42448c55..faef4417 100644
--- a/asset-transfer-basic/rest-api-typescript/package-lock.json
+++ b/asset-transfer-basic/rest-api-typescript/package-lock.json
@@ -2567,9 +2567,9 @@
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
},
"node_modules/cookiejar": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz",
- "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==",
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz",
+ "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==",
"dev": true
},
"node_modules/cors": {
@@ -9677,9 +9677,9 @@
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
},
"cookiejar": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz",
- "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==",
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz",
+ "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==",
"dev": true
},
"cors": {
From a231e12caa768519684ccc926299ae0b07705a9f Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 24 Jan 2023 09:34:28 -0500
Subject: [PATCH 04/30] Bump json5 in /asset-transfer-basic/rest-api-typescript
(#898)
Bumps [json5](https://github.com/json5/json5) from 2.2.0 to 2.2.3.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v2.2.0...v2.2.3)
---
updated-dependencies:
- dependency-name: json5
dependency-type: indirect
...
Signed-off-by: dependabot[bot]
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
.../rest-api-typescript/package-lock.json | 32 ++++---------------
1 file changed, 7 insertions(+), 25 deletions(-)
diff --git a/asset-transfer-basic/rest-api-typescript/package-lock.json b/asset-transfer-basic/rest-api-typescript/package-lock.json
index faef4417..77816d57 100644
--- a/asset-transfer-basic/rest-api-typescript/package-lock.json
+++ b/asset-transfer-basic/rest-api-typescript/package-lock.json
@@ -5272,13 +5272,10 @@
"dev": true
},
"node_modules/json5": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
- "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
"dev": true,
- "dependencies": {
- "minimist": "^1.2.5"
- },
"bin": {
"json5": "lib/cli.js"
},
@@ -5558,12 +5555,6 @@
"node": "*"
}
},
- "node_modules/minimist": {
- "version": "1.2.6",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
- "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
- "dev": true
- },
"node_modules/moment": {
"version": "2.29.4",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
@@ -11718,13 +11709,10 @@
"dev": true
},
"json5": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
- "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
- "dev": true,
- "requires": {
- "minimist": "^1.2.5"
- }
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true
},
"jsrsasign": {
"version": "10.5.26",
@@ -11943,12 +11931,6 @@
"brace-expansion": "^1.1.7"
}
},
- "minimist": {
- "version": "1.2.6",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
- "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
- "dev": true
- },
"moment": {
"version": "2.29.4",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
From 9b1de5e0b135a092bb4439afdd83ef143be2124d Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 24 Jan 2023 09:35:08 -0500
Subject: [PATCH 05/30] Bump minimatch in
/asset-transfer-basic/rest-api-typescript (#887)
Bumps [minimatch](https://github.com/isaacs/minimatch) from 3.0.4 to 3.1.2.
- [Release notes](https://github.com/isaacs/minimatch/releases)
- [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/minimatch/compare/v3.0.4...v3.1.2)
---
updated-dependencies:
- dependency-name: minimatch
dependency-type: indirect
...
Signed-off-by: dependabot[bot]
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
.../rest-api-typescript/package-lock.json | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/asset-transfer-basic/rest-api-typescript/package-lock.json b/asset-transfer-basic/rest-api-typescript/package-lock.json
index 77816d57..e0ad8046 100644
--- a/asset-transfer-basic/rest-api-typescript/package-lock.json
+++ b/asset-transfer-basic/rest-api-typescript/package-lock.json
@@ -5544,9 +5544,9 @@
"integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo="
},
"node_modules/minimatch": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
- "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dev": true,
"dependencies": {
"brace-expansion": "^1.1.7"
@@ -11923,9 +11923,9 @@
"integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo="
},
"minimatch": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
- "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dev": true,
"requires": {
"brace-expansion": "^1.1.7"
From 406d7e9d364739659983914ac09c8729e25141f6 Mon Sep 17 00:00:00 2001
From: HousniAbdellatife <37163236+HousniAbdellatife@users.noreply.github.com>
Date: Wed, 25 Jan 2023 14:48:10 +0100
Subject: [PATCH 06/30] fix java contract paperkey parameter in commercial
paper example (#905)
Signed-off-by: HousniAbdellatife
---
.../src/main/java/org/example/CommercialPaperContract.java | 4 ++--
.../src/main/java/org/example/CommercialPaperContract.java | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/commercial-paper/organization/digibank/contract-java/src/main/java/org/example/CommercialPaperContract.java b/commercial-paper/organization/digibank/contract-java/src/main/java/org/example/CommercialPaperContract.java
index a75f47e3..a46a7038 100644
--- a/commercial-paper/organization/digibank/contract-java/src/main/java/org/example/CommercialPaperContract.java
+++ b/commercial-paper/organization/digibank/contract-java/src/main/java/org/example/CommercialPaperContract.java
@@ -107,7 +107,7 @@ public class CommercialPaperContract implements ContractInterface {
String newOwner, int price, String purchaseDateTime) {
// Retrieve the current paper using key fields provided
- String paperKey = State.makeKey(new String[] { paperNumber });
+ String paperKey = State.makeKey(new String[] { issuer, paperNumber });
CommercialPaper paper = ctx.paperList.getPaper(paperKey);
// Validate current owner
@@ -146,7 +146,7 @@ public class CommercialPaperContract implements ContractInterface {
public CommercialPaper redeem(CommercialPaperContext ctx, String issuer, String paperNumber, String redeemingOwner,
String redeemDateTime) {
- String paperKey = CommercialPaper.makeKey(new String[] { paperNumber });
+ String paperKey = CommercialPaper.makeKey(new String[] { issuer, paperNumber });
CommercialPaper paper = ctx.paperList.getPaper(paperKey);
diff --git a/commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/CommercialPaperContract.java b/commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/CommercialPaperContract.java
index a781c360..a04e62db 100644
--- a/commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/CommercialPaperContract.java
+++ b/commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/CommercialPaperContract.java
@@ -107,7 +107,7 @@ public class CommercialPaperContract implements ContractInterface {
String newOwner, int price, String purchaseDateTime) {
// Retrieve the current paper using key fields provided
- String paperKey = State.makeKey(new String[] { paperNumber });
+ String paperKey = State.makeKey(new String[] { issuer, paperNumber });
CommercialPaper paper = ctx.paperList.getPaper(paperKey);
// Validate current owner
@@ -146,7 +146,7 @@ public class CommercialPaperContract implements ContractInterface {
public CommercialPaper redeem(CommercialPaperContext ctx, String issuer, String paperNumber, String redeemingOwner,
String redeemDateTime) {
- String paperKey = CommercialPaper.makeKey(new String[] { paperNumber });
+ String paperKey = CommercialPaper.makeKey(new String[] {issuer, paperNumber });
CommercialPaper paper = ctx.paperList.getPaper(paperKey);
From 5bc925a3d868205b85ba23d551782acd5f9e4ec6 Mon Sep 17 00:00:00 2001
From: Matthew B White
Date: Wed, 25 Jan 2023 14:03:46 +0000
Subject: [PATCH 07/30] Add in 2.5 java test (#917)
Signed-off-by: Matthew B White
---
.../hyperledger/fabric/samples/privatedata/AssetTransfer.java | 2 +-
ci/scripts/lint-java.sh | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/asset-transfer-private-data/chaincode-java/src/main/java/org/hyperledger/fabric/samples/privatedata/AssetTransfer.java b/asset-transfer-private-data/chaincode-java/src/main/java/org/hyperledger/fabric/samples/privatedata/AssetTransfer.java
index 6467f2c8..eac72319 100644
--- a/asset-transfer-private-data/chaincode-java/src/main/java/org/hyperledger/fabric/samples/privatedata/AssetTransfer.java
+++ b/asset-transfer-private-data/chaincode-java/src/main/java/org/hyperledger/fabric/samples/privatedata/AssetTransfer.java
@@ -490,7 +490,7 @@ public final class AssetTransfer implements ContractInterface {
*
* This deletes the private data, but does not trigger an immediate cleanup
* of the history. To specifically force removal right now use purge
- *
+ *
* @param ctx the transaction context
*/
@Transaction(intent = Transaction.TYPE.SUBMIT)
diff --git a/ci/scripts/lint-java.sh b/ci/scripts/lint-java.sh
index 82f3a810..472b8571 100755
--- a/ci/scripts/lint-java.sh
+++ b/ci/scripts/lint-java.sh
@@ -9,7 +9,7 @@ function print() {
}
# remove the java asset-private-data until the publishing issues have been resolved
-dirs=("$(find . -name "*-java" -type d -not -path '*/.*' -not -path '*/asset-transfer-private-data/*')")
+dirs=("$(find . -name "*-java" -type d -not -path '*/.*')")
for dir in $dirs; do
print "Linting $dir"
pushd $dir
From c986c8d22706a7e98f2e3863d5cc3e310b0f61dc Mon Sep 17 00:00:00 2001
From: jkneubuh <86427252+jkneubuh@users.noreply.github.com>
Date: Fri, 27 Jan 2023 09:49:52 -0500
Subject: [PATCH 08/30] Run FSAT tests with 2.5 images, binaries, and trigger
on all builds for regression coverage (#919)
Signed-off-by: Josh Kneubuhl
---
.github/actions/fsat-setup/action.yaml | 9 ++-
.github/workflows/test-fsat.yaml | 2 -
.../chaincode-java/build.gradle | 6 +-
.../chaincode-typescript/package.json | 5 +-
.../asset-tx-typescript-contract-image.yaml | 24 ------
.../.github/workflows/docker-build.yaml | 78 -------------------
.../.github/workflows/test-ansible.yaml | 49 ------------
.../.github/workflows/test-chaincode.yaml | 49 ------------
.../.github/workflows/test-cloud.yaml | 49 ------------
.../.github/workflows/test-console.yaml | 49 ------------
.../trader-typescript/src/contract.ts | 6 +-
.../asset-transfer-typescript/package.json | 4 +-
.../infrastructure/sample-network/network | 4 +-
.../tests/20-cloud-e2e.sh | 6 +-
14 files changed, 24 insertions(+), 316 deletions(-)
delete mode 100644 full-stack-asset-transfer-guide/.github/workflows/asset-tx-typescript-contract-image.yaml
delete mode 100644 full-stack-asset-transfer-guide/.github/workflows/docker-build.yaml
delete mode 100644 full-stack-asset-transfer-guide/.github/workflows/test-ansible.yaml
delete mode 100644 full-stack-asset-transfer-guide/.github/workflows/test-chaincode.yaml
delete mode 100644 full-stack-asset-transfer-guide/.github/workflows/test-cloud.yaml
delete mode 100644 full-stack-asset-transfer-guide/.github/workflows/test-console.yaml
diff --git a/.github/actions/fsat-setup/action.yaml b/.github/actions/fsat-setup/action.yaml
index 0ea48959..f5477a79 100644
--- a/.github/actions/fsat-setup/action.yaml
+++ b/.github/actions/fsat-setup/action.yaml
@@ -10,6 +10,12 @@ inputs:
k9s-version:
description: k9s Version
default: v0.25.3
+ fabric-version:
+ description: Version of Hyperledger Fabric
+ default: 2.5.0-alpha3
+ ca-version:
+ description: Version of Hyperledger Fabric CA
+ default: 1.5.6-beta3
runs:
using: "composite"
@@ -42,5 +48,6 @@ runs:
shell: bash
working-directory: full-stack-asset-transfer-guide
run: |
- curl -sSL https://raw.githubusercontent.com/hyperledger/fabric/main/scripts/install-fabric.sh | bash -s -- binary
+ curl -sSL https://raw.githubusercontent.com/hyperledger/fabric/main/scripts/install-fabric.sh \
+ | bash -s -- binary --fabric-version ${{ inputs.fabric-version }} --ca-version ${{ inputs.ca-version }}
echo ${PWD}/bin >> $GITHUB_PATH
diff --git a/.github/workflows/test-fsat.yaml b/.github/workflows/test-fsat.yaml
index 09d58ec4..60ccef46 100644
--- a/.github/workflows/test-fsat.yaml
+++ b/.github/workflows/test-fsat.yaml
@@ -7,8 +7,6 @@ on:
branches:
- "main"
- "release-2.5"
- paths:
- - "full-stack-asset-transfer-guide/**"
jobs:
ansible:
diff --git a/asset-transfer-sbe/chaincode-java/build.gradle b/asset-transfer-sbe/chaincode-java/build.gradle
index 44f29319..899d403f 100644
--- a/asset-transfer-sbe/chaincode-java/build.gradle
+++ b/asset-transfer-sbe/chaincode-java/build.gradle
@@ -14,13 +14,13 @@ version '1.0-SNAPSHOT'
dependencies {
- implementation 'org.hyperledger.fabric-chaincode-java:fabric-chaincode-shim:2.+'
+ implementation 'org.hyperledger.fabric-chaincode-java:fabric-chaincode-shim:2.4.1'
implementation 'org.json:json:+'
implementation 'com.google.protobuf:protobuf-java:3.+'
- implementation 'org.hyperledger.fabric-chaincode-java:fabric-chaincode-protos:2.+'
+ implementation 'org.hyperledger.fabric-chaincode-java:fabric-chaincode-protos:2.4.1'
implementation 'com.owlike:genson:1.5'
- testImplementation 'org.hyperledger.fabric-chaincode-java:fabric-chaincode-shim:2.+'
+ testImplementation 'org.hyperledger.fabric-chaincode-java:fabric-chaincode-shim:2.4.1'
testImplementation 'org.junit.jupiter:junit-jupiter:5.4.2'
testImplementation 'org.assertj:assertj-core:3.11.1'
testImplementation 'org.mockito:mockito-core:2.+'
diff --git a/asset-transfer-sbe/chaincode-typescript/package.json b/asset-transfer-sbe/chaincode-typescript/package.json
index 7250279f..7f458aae 100644
--- a/asset-transfer-sbe/chaincode-typescript/package.json
+++ b/asset-transfer-sbe/chaincode-typescript/package.json
@@ -21,8 +21,9 @@
"author": "Hyperledger",
"license": "Apache-2.0",
"dependencies": {
- "fabric-contract-api": "^2.5.0",
- "fabric-shim": "^2.5.0"
+ "@grpc/grpc-js": "1.8.1",
+ "fabric-contract-api": "~2.5.2",
+ "fabric-shim": "~2.5.2"
},
"devDependencies": {
"@types/chai": "^4.2.11",
diff --git a/full-stack-asset-transfer-guide/.github/workflows/asset-tx-typescript-contract-image.yaml b/full-stack-asset-transfer-guide/.github/workflows/asset-tx-typescript-contract-image.yaml
deleted file mode 100644
index c65bb790..00000000
--- a/full-stack-asset-transfer-guide/.github/workflows/asset-tx-typescript-contract-image.yaml
+++ /dev/null
@@ -1,24 +0,0 @@
-name: Asset Tx Contract Image CI
-
-on:
- push:
- branches:
- - 'main'
- tags:
- - 'v*'
- paths:
- - 'contracts/asset-transfer-typescript/**'
- pull_request:
- branches:
- - 'main'
- paths:
- - 'contracts/asset-transfer-typescript/**'
-
-jobs:
- docker_build:
- name: Docker build
- uses: ./.github/workflows/docker-build.yaml
- with:
- imagename: full-stack-asset-transfer-guide/contracts/asset-transfer-typescript
- path: contracts/asset-transfer-typescript
- chaincode-label: asset-transfer-typescript
diff --git a/full-stack-asset-transfer-guide/.github/workflows/docker-build.yaml b/full-stack-asset-transfer-guide/.github/workflows/docker-build.yaml
deleted file mode 100644
index 894aedc2..00000000
--- a/full-stack-asset-transfer-guide/.github/workflows/docker-build.yaml
+++ /dev/null
@@ -1,78 +0,0 @@
-name: Docker CI
-
-on:
- workflow_call:
- inputs:
- imagename:
- description: 'A Docker image name passed from the caller workflow'
- required: true
- type: string
- path:
- description: 'A path containing a Dockerfile passed from the caller workflow'
- required: true
- type: string
- chaincode-label:
- description: 'An optional chaincode package label passed from the caller workflow. If present, will prepare a chaincode package.'
- required: false
- type: string
-
-jobs:
- build:
- runs-on: ubuntu-latest
- outputs:
- image_digest: ${{ steps.publish_image.outputs.image_digest }}
-
- steps:
- - uses: actions/checkout@v3
- - name: Build Docker image
- run: |
- docker build ${DOCKER_BUILD_PATH} --file ${DOCKER_BUILD_PATH}/Dockerfile --label "org.opencontainers.image.revision=${GITHUB_SHA}" --tag ${IMAGE_NAME}
- docker tag ${IMAGE_NAME} ghcr.io/hyperledgendary/${IMAGE_NAME}:${GITHUB_SHA}
- if [ "${GITHUB_REF:0:10}" = "refs/tags/" ]; then
- docker tag ${IMAGE_NAME} ghcr.io/hyperledgendary/${IMAGE_NAME}:${GITHUB_REF_NAME}
- docker tag ${IMAGE_NAME} ghcr.io/hyperledgendary/${IMAGE_NAME}:latest
- fi
- env:
- DOCKER_BUILD_PATH: ${{ inputs.path }}
- IMAGE_NAME: ${{ inputs.imagename }}
- - name: Publish Docker image
- id: publish_image
- if: github.event_name != 'pull_request'
- run: |
- echo ${DOCKER_PW} | docker login ghcr.io -u ${DOCKER_USER} --password-stdin
- docker push ghcr.io/hyperledgendary/${IMAGE_NAME}:${GITHUB_SHA}
- if [ "${GITHUB_REF:0:10}" = "refs/tags/" ]; then
- docker push ghcr.io/hyperledgendary/${IMAGE_NAME}:${GITHUB_REF_NAME}
- docker push ghcr.io/hyperledgendary/${IMAGE_NAME}:latest
- fi
- echo ::set-output name=image_digest::$(docker inspect --format='{{index .RepoDigests 0}}' ghcr.io/hyperledgendary/${IMAGE_NAME}:${GITHUB_SHA} | cut -d'@' -f2)
- env:
- IMAGE_NAME: ${{ inputs.imagename }}
- DOCKER_USER: ${{ github.actor }}
- DOCKER_PW: ${{ secrets.GITHUB_TOKEN }}
-
- package:
- if: inputs.chaincode-label != '' && needs.build.outputs.image_digest != ''
- needs: build
- runs-on: ubuntu-latest
-
- steps:
- - name: Create package
- uses: hyperledgendary/package-k8s-chaincode-action@ba10aea43e3d4f7991116527faf96e3c2b07abc7
- with:
- chaincode-label: ${{ inputs.chaincode-label }}
- chaincode-image: ghcr.io/hyperledgendary/${{ inputs.imagename }}
- chaincode-digest: ${{ needs.build.outputs.image_digest }}
-
- - name: Rename package
- if: startsWith(github.ref, 'refs/tags/v')
- run: mv ${{ inputs.chaincode-label }}.tgz ${{ inputs.chaincode-label }}-${CHAINCODE_VERSION}.tgz
- env:
- IMAGE_NAME: ${{ inputs.imagename }}
- CHAINCODE_VERSION: ${{ github.ref_name }}
-
- - name: Release package
- if: startsWith(github.ref, 'refs/tags/v')
- uses: softprops/action-gh-release@v1
- with:
- files: ${{ inputs.chaincode-label }}-${{ github.ref_name }}.tgz
\ No newline at end of file
diff --git a/full-stack-asset-transfer-guide/.github/workflows/test-ansible.yaml b/full-stack-asset-transfer-guide/.github/workflows/test-ansible.yaml
deleted file mode 100644
index e82f8739..00000000
--- a/full-stack-asset-transfer-guide/.github/workflows/test-ansible.yaml
+++ /dev/null
@@ -1,49 +0,0 @@
-name: test-ansible
-
-on:
- pull_request:
- branches:
- - main
-
-jobs:
- test-ansible:
- runs-on: ubuntu-latest
-
- steps:
- - name: checkout
- uses: actions/checkout@v3
-
- - name: k9s
- env:
- K9S_VERSION: v0.25.3
- run: |
- curl --fail --silent --show-error -L https://github.com/derailed/k9s/releases/download/${K9S_VERSION}/k9s_Linux_x86_64.tar.gz -o /tmp/k9s_Linux_x86_64.tar.gz
- tar -zxf /tmp/k9s_Linux_x86_64.tar.gz -C /usr/local/bin k9s
- sudo chown root /usr/local/bin/k9s
- sudo chmod 755 /usr/local/bin/k9s
-
- - name: just
- env:
- JUST_VERSION: 1.2.0
- run: |
- curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --tag ${JUST_VERSION} --to /usr/local/bin
-
- - name: weft
- run: |
- npm install -g @hyperledger-labs/weft
-
- - name: fabric
- run: |
- curl -sSL https://raw.githubusercontent.com/hyperledger/fabric/main/scripts/install-fabric.sh | bash -s -- binary
-
- - name: check prereqs
- run: |
- export WORKSHOP_PATH="${PWD}"
- export PATH="${WORKSHOP_PATH}/bin:${PATH}"
- export FABRIC_CFG_PATH="${WORKSHOP_PATH}/config"
-
- ./check.sh
-
- - name: just test-ansible
- run: |
- just test-ansible
\ No newline at end of file
diff --git a/full-stack-asset-transfer-guide/.github/workflows/test-chaincode.yaml b/full-stack-asset-transfer-guide/.github/workflows/test-chaincode.yaml
deleted file mode 100644
index 459b0711..00000000
--- a/full-stack-asset-transfer-guide/.github/workflows/test-chaincode.yaml
+++ /dev/null
@@ -1,49 +0,0 @@
-name: test-chaincode
-
-on:
- pull_request:
- branches:
- - main
-
-jobs:
- test-chaincode:
- runs-on: ubuntu-latest
-
- steps:
- - name: checkout
- uses: actions/checkout@v3
-
- - name: k9s
- env:
- K9S_VERSION: v0.25.3
- run: |
- curl --fail --silent --show-error -L https://github.com/derailed/k9s/releases/download/${K9S_VERSION}/k9s_Linux_x86_64.tar.gz -o /tmp/k9s_Linux_x86_64.tar.gz
- tar -zxf /tmp/k9s_Linux_x86_64.tar.gz -C /usr/local/bin k9s
- sudo chown root /usr/local/bin/k9s
- sudo chmod 755 /usr/local/bin/k9s
-
- - name: just
- env:
- JUST_VERSION: 1.2.0
- run: |
- curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --tag ${JUST_VERSION} --to /usr/local/bin
-
- - name: weft
- run: |
- npm install -g @hyperledger-labs/weft
-
- - name: fabric
- run: |
- curl -sSL https://raw.githubusercontent.com/hyperledger/fabric/main/scripts/install-fabric.sh | bash -s -- binary
-
- - name: check prereqs
- run: |
- export WORKSHOP_PATH="${PWD}"
- export PATH="${WORKSHOP_PATH}/bin:${PATH}"
- export FABRIC_CFG_PATH="${WORKSHOP_PATH}/config"
-
- ./check.sh
-
- - name: just test-chaincode
- run: |
- just test-chaincode
\ No newline at end of file
diff --git a/full-stack-asset-transfer-guide/.github/workflows/test-cloud.yaml b/full-stack-asset-transfer-guide/.github/workflows/test-cloud.yaml
deleted file mode 100644
index ce9a2c9d..00000000
--- a/full-stack-asset-transfer-guide/.github/workflows/test-cloud.yaml
+++ /dev/null
@@ -1,49 +0,0 @@
-name: test-cloud
-
-on:
- pull_request:
- branches:
- - main
-
-jobs:
- test-cloud:
- runs-on: ubuntu-latest
-
- steps:
- - name: checkout
- uses: actions/checkout@v3
-
- - name: k9s
- env:
- K9S_VERSION: v0.25.3
- run: |
- curl --fail --silent --show-error -L https://github.com/derailed/k9s/releases/download/${K9S_VERSION}/k9s_Linux_x86_64.tar.gz -o /tmp/k9s_Linux_x86_64.tar.gz
- tar -zxf /tmp/k9s_Linux_x86_64.tar.gz -C /usr/local/bin k9s
- sudo chown root /usr/local/bin/k9s
- sudo chmod 755 /usr/local/bin/k9s
-
- - name: just
- env:
- JUST_VERSION: 1.2.0
- run: |
- curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --tag ${JUST_VERSION} --to /usr/local/bin
-
- - name: weft
- run: |
- npm install -g @hyperledger-labs/weft
-
- - name: fabric
- run: |
- curl -sSL https://raw.githubusercontent.com/hyperledger/fabric/main/scripts/install-fabric.sh | bash -s -- binary
-
- - name: check prereqs
- run: |
- export WORKSHOP_PATH="${PWD}"
- export PATH="${WORKSHOP_PATH}/bin:${PATH}"
- export FABRIC_CFG_PATH="${WORKSHOP_PATH}/config"
-
- ./check.sh
-
- - name: just test-cloud
- run: |
- just test-cloud
\ No newline at end of file
diff --git a/full-stack-asset-transfer-guide/.github/workflows/test-console.yaml b/full-stack-asset-transfer-guide/.github/workflows/test-console.yaml
deleted file mode 100644
index c3969a99..00000000
--- a/full-stack-asset-transfer-guide/.github/workflows/test-console.yaml
+++ /dev/null
@@ -1,49 +0,0 @@
-name: test-console
-
-on:
- pull_request:
- branches:
- - main
-
-jobs:
- test-console:
- runs-on: ubuntu-latest
-
- steps:
- - name: checkout
- uses: actions/checkout@v3
-
- - name: k9s
- env:
- K9S_VERSION: v0.25.3
- run: |
- curl --fail --silent --show-error -L https://github.com/derailed/k9s/releases/download/${K9S_VERSION}/k9s_Linux_x86_64.tar.gz -o /tmp/k9s_Linux_x86_64.tar.gz
- tar -zxf /tmp/k9s_Linux_x86_64.tar.gz -C /usr/local/bin k9s
- sudo chown root /usr/local/bin/k9s
- sudo chmod 755 /usr/local/bin/k9s
-
- - name: just
- env:
- JUST_VERSION: 1.2.0
- run: |
- curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --tag ${JUST_VERSION} --to /usr/local/bin
-
- - name: weft
- run: |
- npm install -g @hyperledger-labs/weft
-
- - name: fabric
- run: |
- curl -sSL https://raw.githubusercontent.com/hyperledger/fabric/main/scripts/install-fabric.sh | bash -s -- binary
-
- - name: check prereqs
- run: |
- export WORKSHOP_PATH="${PWD}"
- export PATH="${WORKSHOP_PATH}/bin:${PATH}"
- export FABRIC_CFG_PATH="${WORKSHOP_PATH}/config"
-
- ./check.sh
-
- - name: just test-console
- run: |
- just test-console
\ No newline at end of file
diff --git a/full-stack-asset-transfer-guide/applications/trader-typescript/src/contract.ts b/full-stack-asset-transfer-guide/applications/trader-typescript/src/contract.ts
index e14ffd57..2e210c68 100644
--- a/full-stack-asset-transfer-guide/applications/trader-typescript/src/contract.ts
+++ b/full-stack-asset-transfer-guide/applications/trader-typescript/src/contract.ts
@@ -76,8 +76,10 @@ export class AssetTransfer {
}
async transferAsset(id: string, newOwner: string, newOwnerOrg: string): Promise {
- // TODO: Implement me!
- // Submit a 'TransferAsset' transaction, which requires [id, newOwner, newOwnerOrg] arguments.
+ console.log(`transferring asset '${id}' to ${newOwner}, ${newOwnerOrg}`);
+ // TODO: implement the transferAsset() function.
+ // TODO: submit a 'TransferAsset' transaction, requiring [id, newOwner, newOwnerOrg] arguments.
+ return Promise.reject(new Error('TODO: implement the contract.ts transferAsset() function.'));
}
}
diff --git a/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/package.json b/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/package.json
index 1b6f63ff..ebf36efa 100644
--- a/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/package.json
+++ b/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/package.json
@@ -26,8 +26,8 @@
"author": "Hyperledger",
"license": "Apache-2.0",
"dependencies": {
- "fabric-contract-api": "^2.4.0",
- "fabric-shim": "^2.4.0",
+ "fabric-contract-api": "~2.5.2",
+ "fabric-shim": "~2.5.2",
"json-stringify-deterministic": "^1.0.7",
"sort-keys-recursive": "^2.1.7"
},
diff --git a/full-stack-asset-transfer-guide/infrastructure/sample-network/network b/full-stack-asset-transfer-guide/infrastructure/sample-network/network
index bab91ed6..0e1f9373 100755
--- a/full-stack-asset-transfer-guide/infrastructure/sample-network/network
+++ b/full-stack-asset-transfer-guide/infrastructure/sample-network/network
@@ -78,13 +78,13 @@ context CA_IMAGE_LABEL ${FABRIC_CA_VERSION}
#context PEER_IMAGE ${FABRIC_CONTAINER_REGISTRY}/fabric-peer
#context PEER_IMAGE_LABEL ${FABRIC_VERSION}
context PEER_IMAGE ghcr.io/hyperledger-labs/k8s-fabric-peer
-context PEER_IMAGE_LABEL v0.7.2 # FROM fabric-peer 2.4
+context PEER_IMAGE_LABEL v0.8.0
context ORDERER_IMAGE ${FABRIC_CONTAINER_REGISTRY}/fabric-orderer
context ORDERER_IMAGE_LABEL ${FABRIC_VERSION}
context TOOLS_IMAGE ${FABRIC_CONTAINER_REGISTRY}/fabric-tools
context TOOLS_IMAGE_LABEL ${FABRIC_VERSION}
context OPERATOR_IMAGE ghcr.io/hyperledger-labs/fabric-operator
-context OPERATOR_IMAGE_LABEL latest-amd64
+context OPERATOR_IMAGE_LABEL 1.0.4
context INIT_IMAGE registry.access.redhat.com/ubi8/ubi-minimal
context INIT_IMAGE_LABEL latest
context GRPCWEB_IMAGE ghcr.io/hyperledger-labs/grpc-web
diff --git a/full-stack-asset-transfer-guide/tests/20-cloud-e2e.sh b/full-stack-asset-transfer-guide/tests/20-cloud-e2e.sh
index a747ea69..f6f3d384 100755
--- a/full-stack-asset-transfer-guide/tests/20-cloud-e2e.sh
+++ b/full-stack-asset-transfer-guide/tests/20-cloud-e2e.sh
@@ -32,8 +32,6 @@ trap exitHook SIGINT SIGTERM EXIT
# 00-setup
###############################################################################
-curl -sSL https://raw.githubusercontent.com/hyperledger/fabric/main/scripts/install-fabric.sh | bash -s -- binary
-
export WORKSHOP_PATH="${PWD}"
export PATH="${WORKSHOP_PATH}/bin:${PATH}"
export FABRIC_CFG_PATH="${WORKSHOP_PATH}/config"
@@ -188,8 +186,8 @@ function build_cc() {
CHAINCODE_IMAGE=$CONTAINER_REGISTRY/$CHAINCODE_NAME
# Build the chaincode image
- # TODO: configure buildx builders on the CI runners to ensure target arch and os are automatically set.
- docker build --build-arg TARGETARCH=amd64 -t $CHAINCODE_IMAGE contracts/$CHAINCODE_NAME-typescript
+ ARCH=$(uname -m | sed 's/x86_64/amd64/g' | sed 's/aarch64/arm64/g')
+ docker build --build-arg TARGETARCH=${ARCH} -t $CHAINCODE_IMAGE contracts/$CHAINCODE_NAME-typescript
# Push the image to the insecure container registry
docker push $CHAINCODE_IMAGE
From cb886be4668a9cbafdde3253b844a78823e24106 Mon Sep 17 00:00:00 2001
From: Matthew B White
Date: Mon, 30 Jan 2023 15:12:15 +0000
Subject: [PATCH 09/30] Commercial Paper
The Commercial Paper example code hasn't kept pace with the state-of-the-art of writing applications and chaincode
Whilst the scenario is still a valid usecase, the example itself is not helping - in fact causing confusion.
Signed-off-by: Matthew B White
---
commercial-paper/.gitignore | 4 -
commercial-paper/README.md | 646 ------------------
commercial-paper/img/overview.png | Bin 122143 -> 0 bytes
commercial-paper/img/transaction-flow.png | Bin 21986 -> 0 bytes
commercial-paper/network-clean.sh | 26 -
commercial-paper/network-starter.sh | 36 -
.../organization/digibank/.gitignore | 1 -
.../digibank/application-java/.gitignore | 1 -
.../.settings/org.eclipse.jdt.core.prefs | 6 -
.../.settings/org.eclipse.m2e.core.prefs | 4 -
.../digibank/application-java/pom.xml | 96 ---
.../src/org/digibank/AddToWallet.java | 68 --
.../src/org/digibank/Buy.java | 74 --
.../src/org/digibank/Redeem.java | 73 --
.../src/org/papernet/CommercialPaper.java | 183 -----
.../src/org/papernet/ledgerapi/State.java | 60 --
.../digibank/application/.eslintrc.js | 37 -
.../digibank/application/.gitignore | 1 -
.../digibank/application/addToWallet.js | 55 --
.../organization/digibank/application/buy.js | 105 ---
.../digibank/application/buy_request.js | 105 ---
.../digibank/application/enrollUser.js | 56 --
.../digibank/application/package.json | 20 -
.../digibank/application/queryapp.js | 155 -----
.../digibank/application/redeem.js | 106 ---
.../configuration/cli/docker-compose.yml | 37 -
.../configuration/cli/monitordocker.sh | 31 -
.../contract-go/commercial-paper/paper.go | 139 ----
.../commercial-paper/paper_test.go | 125 ----
.../commercial-paper/papercontext.go | 35 -
.../commercial-paper/papercontext_test.go | 31 -
.../commercial-paper/papercontract.go | 96 ---
.../commercial-paper/papercontract_test.go | 185 -----
.../contract-go/commercial-paper/paperlist.go | 55 --
.../commercial-paper/paperlist_test.go | 103 ---
.../organization/digibank/contract-go/go.mod | 39 --
.../organization/digibank/contract-go/go.sum | 486 -------------
.../digibank/contract-go/ledger-api/state.go | 27 -
.../contract-go/ledger-api/statelist.go | 61 --
.../organization/digibank/contract-go/main.go | 35 -
.../digibank/contract-java/.gitignore | 10 -
.../digibank/contract-java/build.gradle | 37 -
.../gradle/wrapper/gradle-wrapper.jar | Bin 55616 -> 0 bytes
.../gradle/wrapper/gradle-wrapper.properties | 5 -
.../digibank/contract-java/gradlew | 188 -----
.../digibank/contract-java/gradlew.bat | 100 ---
.../digibank/contract-java/settings.gradle | 2 -
.../contract-java/shadow-build.gradle | 49 --
.../java/org/example/CommercialPaper.java | 183 -----
.../org/example/CommercialPaperContext.java | 15 -
.../org/example/CommercialPaperContract.java | 170 -----
.../src/main/java/org/example/PaperList.java | 31 -
.../java/org/example/ledgerapi/State.java | 60 --
.../example/ledgerapi/StateDeserializer.java | 6 -
.../java/org/example/ledgerapi/StateList.java | 48 --
.../example/ledgerapi/impl/StateListImpl.java | 100 ---
.../digibank/contract/.editorconfig | 16 -
.../digibank/contract/.eslintignore | 5 -
.../digibank/contract/.eslintrc.js | 37 -
.../organization/digibank/contract/.npmignore | 77 ---
.../organization/digibank/contract/index.js | 10 -
.../digibank/contract/ledger-api/state.js | 105 ---
.../digibank/contract/ledger-api/statelist.js | 74 --
.../digibank/contract/lib/paper.js | 121 ----
.../digibank/contract/lib/papercontract.js | 339 ---------
.../digibank/contract/lib/paperlist.js | 35 -
.../digibank/contract/lib/queries.js | 217 ------
.../digibank/contract/package.json | 49 --
.../digibank/contract/test/contract.js | 43 --
.../organization/digibank/digibank.sh | 38 --
.../organization/digibank/gateway/.gitkeep | 0
.../organization/magnetocorp/.gitignore | 1 -
.../magnetocorp/application-java/.gitignore | 1 -
.../org.eclipse.core.resources.prefs | 3 -
.../.settings/org.eclipse.m2e.core.prefs | 4 -
.../magnetocorp/application-java/pom.xml | 96 ---
.../src/org/magnetocorp/AddToWallet.java | 68 --
.../src/org/magnetocorp/Issue.java | 75 --
.../src/org/papernet/CommercialPaper.java | 185 -----
.../src/org/papernet/ledgerapi/State.java | 60 --
.../magnetocorp/application/.eslintrc.js | 37 -
.../magnetocorp/application/.gitignore | 1 -
.../magnetocorp/application/addToWallet.js | 55 --
.../magnetocorp/application/cpListener.js | 103 ---
.../magnetocorp/application/enrollUser.js | 56 --
.../magnetocorp/application/issue.js | 103 ---
.../magnetocorp/application/package.json | 20 -
.../magnetocorp/application/transfer.js | 103 ---
.../configuration/cli/docker-compose.yml | 37 -
.../configuration/cli/monitordocker.sh | 31 -
.../contract-go/commercial-paper/paper.go | 139 ----
.../commercial-paper/paper_test.go | 125 ----
.../commercial-paper/papercontext.go | 35 -
.../commercial-paper/papercontext_test.go | 31 -
.../commercial-paper/papercontract.go | 96 ---
.../commercial-paper/papercontract_test.go | 185 -----
.../contract-go/commercial-paper/paperlist.go | 55 --
.../commercial-paper/paperlist_test.go | 103 ---
.../magnetocorp/contract-go/go.mod | 39 --
.../magnetocorp/contract-go/go.sum | 486 -------------
.../contract-go/ledger-api/state.go | 27 -
.../contract-go/ledger-api/statelist.go | 61 --
.../magnetocorp/contract-go/main.go | 35 -
.../magnetocorp/contract-java/build.gradle | 49 --
.../gradle/wrapper/gradle-wrapper.jar | Bin 55616 -> 0 bytes
.../gradle/wrapper/gradle-wrapper.properties | 5 -
.../magnetocorp/contract-java/gradlew | 188 -----
.../magnetocorp/contract-java/gradlew.bat | 100 ---
.../magnetocorp/contract-java/settings.gradle | 2 -
.../java/org/example/CommercialPaper.java | 183 -----
.../org/example/CommercialPaperContext.java | 15 -
.../org/example/CommercialPaperContract.java | 170 -----
.../src/main/java/org/example/PaperList.java | 31 -
.../java/org/example/ledgerapi/State.java | 60 --
.../example/ledgerapi/StateDeserializer.java | 6 -
.../java/org/example/ledgerapi/StateList.java | 48 --
.../example/ledgerapi/impl/StateListImpl.java | 100 ---
.../magnetocorp/contract/.editorconfig | 16 -
.../magnetocorp/contract/.eslintignore | 5 -
.../magnetocorp/contract/.eslintrc.js | 37 -
.../magnetocorp/contract/.npmignore | 77 ---
.../magnetocorp/contract/index.js | 10 -
.../magnetocorp/contract/ledger-api/state.js | 105 ---
.../contract/ledger-api/statelist.js | 74 --
.../magnetocorp/contract/lib/paper.js | 121 ----
.../magnetocorp/contract/lib/papercontract.js | 339 ---------
.../magnetocorp/contract/lib/paperlist.js | 35 -
.../magnetocorp/contract/lib/queries.js | 216 ------
.../magnetocorp/contract/package.json | 49 --
.../magnetocorp/contract/test/contract.js | 43 --
.../organization/magnetocorp/gateway/.gitkeep | 0
.../organization/magnetocorp/magnetocorp.sh | 38 --
.../organization/magnetocorp/t.js | 1 -
133 files changed, 10152 deletions(-)
delete mode 100644 commercial-paper/.gitignore
delete mode 100644 commercial-paper/README.md
delete mode 100644 commercial-paper/img/overview.png
delete mode 100644 commercial-paper/img/transaction-flow.png
delete mode 100755 commercial-paper/network-clean.sh
delete mode 100755 commercial-paper/network-starter.sh
delete mode 100644 commercial-paper/organization/digibank/.gitignore
delete mode 100644 commercial-paper/organization/digibank/application-java/.gitignore
delete mode 100644 commercial-paper/organization/digibank/application-java/.settings/org.eclipse.jdt.core.prefs
delete mode 100644 commercial-paper/organization/digibank/application-java/.settings/org.eclipse.m2e.core.prefs
delete mode 100644 commercial-paper/organization/digibank/application-java/pom.xml
delete mode 100644 commercial-paper/organization/digibank/application-java/src/org/digibank/AddToWallet.java
delete mode 100644 commercial-paper/organization/digibank/application-java/src/org/digibank/Buy.java
delete mode 100644 commercial-paper/organization/digibank/application-java/src/org/digibank/Redeem.java
delete mode 100644 commercial-paper/organization/digibank/application-java/src/org/papernet/CommercialPaper.java
delete mode 100644 commercial-paper/organization/digibank/application-java/src/org/papernet/ledgerapi/State.java
delete mode 100644 commercial-paper/organization/digibank/application/.eslintrc.js
delete mode 100644 commercial-paper/organization/digibank/application/.gitignore
delete mode 100644 commercial-paper/organization/digibank/application/addToWallet.js
delete mode 100644 commercial-paper/organization/digibank/application/buy.js
delete mode 100644 commercial-paper/organization/digibank/application/buy_request.js
delete mode 100644 commercial-paper/organization/digibank/application/enrollUser.js
delete mode 100644 commercial-paper/organization/digibank/application/package.json
delete mode 100644 commercial-paper/organization/digibank/application/queryapp.js
delete mode 100644 commercial-paper/organization/digibank/application/redeem.js
delete mode 100644 commercial-paper/organization/digibank/configuration/cli/docker-compose.yml
delete mode 100755 commercial-paper/organization/digibank/configuration/cli/monitordocker.sh
delete mode 100644 commercial-paper/organization/digibank/contract-go/commercial-paper/paper.go
delete mode 100644 commercial-paper/organization/digibank/contract-go/commercial-paper/paper_test.go
delete mode 100644 commercial-paper/organization/digibank/contract-go/commercial-paper/papercontext.go
delete mode 100644 commercial-paper/organization/digibank/contract-go/commercial-paper/papercontext_test.go
delete mode 100644 commercial-paper/organization/digibank/contract-go/commercial-paper/papercontract.go
delete mode 100644 commercial-paper/organization/digibank/contract-go/commercial-paper/papercontract_test.go
delete mode 100644 commercial-paper/organization/digibank/contract-go/commercial-paper/paperlist.go
delete mode 100644 commercial-paper/organization/digibank/contract-go/commercial-paper/paperlist_test.go
delete mode 100644 commercial-paper/organization/digibank/contract-go/go.mod
delete mode 100644 commercial-paper/organization/digibank/contract-go/go.sum
delete mode 100644 commercial-paper/organization/digibank/contract-go/ledger-api/state.go
delete mode 100644 commercial-paper/organization/digibank/contract-go/ledger-api/statelist.go
delete mode 100644 commercial-paper/organization/digibank/contract-go/main.go
delete mode 100644 commercial-paper/organization/digibank/contract-java/.gitignore
delete mode 100644 commercial-paper/organization/digibank/contract-java/build.gradle
delete mode 100644 commercial-paper/organization/digibank/contract-java/gradle/wrapper/gradle-wrapper.jar
delete mode 100644 commercial-paper/organization/digibank/contract-java/gradle/wrapper/gradle-wrapper.properties
delete mode 100755 commercial-paper/organization/digibank/contract-java/gradlew
delete mode 100644 commercial-paper/organization/digibank/contract-java/gradlew.bat
delete mode 100644 commercial-paper/organization/digibank/contract-java/settings.gradle
delete mode 100644 commercial-paper/organization/digibank/contract-java/shadow-build.gradle
delete mode 100644 commercial-paper/organization/digibank/contract-java/src/main/java/org/example/CommercialPaper.java
delete mode 100644 commercial-paper/organization/digibank/contract-java/src/main/java/org/example/CommercialPaperContext.java
delete mode 100644 commercial-paper/organization/digibank/contract-java/src/main/java/org/example/CommercialPaperContract.java
delete mode 100644 commercial-paper/organization/digibank/contract-java/src/main/java/org/example/PaperList.java
delete mode 100644 commercial-paper/organization/digibank/contract-java/src/main/java/org/example/ledgerapi/State.java
delete mode 100644 commercial-paper/organization/digibank/contract-java/src/main/java/org/example/ledgerapi/StateDeserializer.java
delete mode 100644 commercial-paper/organization/digibank/contract-java/src/main/java/org/example/ledgerapi/StateList.java
delete mode 100644 commercial-paper/organization/digibank/contract-java/src/main/java/org/example/ledgerapi/impl/StateListImpl.java
delete mode 100755 commercial-paper/organization/digibank/contract/.editorconfig
delete mode 100644 commercial-paper/organization/digibank/contract/.eslintignore
delete mode 100644 commercial-paper/organization/digibank/contract/.eslintrc.js
delete mode 100644 commercial-paper/organization/digibank/contract/.npmignore
delete mode 100644 commercial-paper/organization/digibank/contract/index.js
delete mode 100644 commercial-paper/organization/digibank/contract/ledger-api/state.js
delete mode 100644 commercial-paper/organization/digibank/contract/ledger-api/statelist.js
delete mode 100644 commercial-paper/organization/digibank/contract/lib/paper.js
delete mode 100644 commercial-paper/organization/digibank/contract/lib/papercontract.js
delete mode 100644 commercial-paper/organization/digibank/contract/lib/paperlist.js
delete mode 100644 commercial-paper/organization/digibank/contract/lib/queries.js
delete mode 100644 commercial-paper/organization/digibank/contract/package.json
delete mode 100644 commercial-paper/organization/digibank/contract/test/contract.js
delete mode 100755 commercial-paper/organization/digibank/digibank.sh
delete mode 100644 commercial-paper/organization/digibank/gateway/.gitkeep
delete mode 100644 commercial-paper/organization/magnetocorp/.gitignore
delete mode 100644 commercial-paper/organization/magnetocorp/application-java/.gitignore
delete mode 100644 commercial-paper/organization/magnetocorp/application-java/.settings/org.eclipse.core.resources.prefs
delete mode 100644 commercial-paper/organization/magnetocorp/application-java/.settings/org.eclipse.m2e.core.prefs
delete mode 100644 commercial-paper/organization/magnetocorp/application-java/pom.xml
delete mode 100644 commercial-paper/organization/magnetocorp/application-java/src/org/magnetocorp/AddToWallet.java
delete mode 100644 commercial-paper/organization/magnetocorp/application-java/src/org/magnetocorp/Issue.java
delete mode 100644 commercial-paper/organization/magnetocorp/application-java/src/org/papernet/CommercialPaper.java
delete mode 100644 commercial-paper/organization/magnetocorp/application-java/src/org/papernet/ledgerapi/State.java
delete mode 100644 commercial-paper/organization/magnetocorp/application/.eslintrc.js
delete mode 100644 commercial-paper/organization/magnetocorp/application/.gitignore
delete mode 100644 commercial-paper/organization/magnetocorp/application/addToWallet.js
delete mode 100644 commercial-paper/organization/magnetocorp/application/cpListener.js
delete mode 100644 commercial-paper/organization/magnetocorp/application/enrollUser.js
delete mode 100644 commercial-paper/organization/magnetocorp/application/issue.js
delete mode 100644 commercial-paper/organization/magnetocorp/application/package.json
delete mode 100644 commercial-paper/organization/magnetocorp/application/transfer.js
delete mode 100644 commercial-paper/organization/magnetocorp/configuration/cli/docker-compose.yml
delete mode 100755 commercial-paper/organization/magnetocorp/configuration/cli/monitordocker.sh
delete mode 100644 commercial-paper/organization/magnetocorp/contract-go/commercial-paper/paper.go
delete mode 100644 commercial-paper/organization/magnetocorp/contract-go/commercial-paper/paper_test.go
delete mode 100644 commercial-paper/organization/magnetocorp/contract-go/commercial-paper/papercontext.go
delete mode 100644 commercial-paper/organization/magnetocorp/contract-go/commercial-paper/papercontext_test.go
delete mode 100644 commercial-paper/organization/magnetocorp/contract-go/commercial-paper/papercontract.go
delete mode 100644 commercial-paper/organization/magnetocorp/contract-go/commercial-paper/papercontract_test.go
delete mode 100644 commercial-paper/organization/magnetocorp/contract-go/commercial-paper/paperlist.go
delete mode 100644 commercial-paper/organization/magnetocorp/contract-go/commercial-paper/paperlist_test.go
delete mode 100644 commercial-paper/organization/magnetocorp/contract-go/go.mod
delete mode 100644 commercial-paper/organization/magnetocorp/contract-go/go.sum
delete mode 100644 commercial-paper/organization/magnetocorp/contract-go/ledger-api/state.go
delete mode 100644 commercial-paper/organization/magnetocorp/contract-go/ledger-api/statelist.go
delete mode 100644 commercial-paper/organization/magnetocorp/contract-go/main.go
delete mode 100644 commercial-paper/organization/magnetocorp/contract-java/build.gradle
delete mode 100644 commercial-paper/organization/magnetocorp/contract-java/gradle/wrapper/gradle-wrapper.jar
delete mode 100644 commercial-paper/organization/magnetocorp/contract-java/gradle/wrapper/gradle-wrapper.properties
delete mode 100755 commercial-paper/organization/magnetocorp/contract-java/gradlew
delete mode 100644 commercial-paper/organization/magnetocorp/contract-java/gradlew.bat
delete mode 100644 commercial-paper/organization/magnetocorp/contract-java/settings.gradle
delete mode 100644 commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/CommercialPaper.java
delete mode 100644 commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/CommercialPaperContext.java
delete mode 100644 commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/CommercialPaperContract.java
delete mode 100644 commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/PaperList.java
delete mode 100644 commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/ledgerapi/State.java
delete mode 100644 commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/ledgerapi/StateDeserializer.java
delete mode 100644 commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/ledgerapi/StateList.java
delete mode 100644 commercial-paper/organization/magnetocorp/contract-java/src/main/java/org/example/ledgerapi/impl/StateListImpl.java
delete mode 100755 commercial-paper/organization/magnetocorp/contract/.editorconfig
delete mode 100644 commercial-paper/organization/magnetocorp/contract/.eslintignore
delete mode 100644 commercial-paper/organization/magnetocorp/contract/.eslintrc.js
delete mode 100644 commercial-paper/organization/magnetocorp/contract/.npmignore
delete mode 100644 commercial-paper/organization/magnetocorp/contract/index.js
delete mode 100644 commercial-paper/organization/magnetocorp/contract/ledger-api/state.js
delete mode 100644 commercial-paper/organization/magnetocorp/contract/ledger-api/statelist.js
delete mode 100644 commercial-paper/organization/magnetocorp/contract/lib/paper.js
delete mode 100644 commercial-paper/organization/magnetocorp/contract/lib/papercontract.js
delete mode 100644 commercial-paper/organization/magnetocorp/contract/lib/paperlist.js
delete mode 100644 commercial-paper/organization/magnetocorp/contract/lib/queries.js
delete mode 100644 commercial-paper/organization/magnetocorp/contract/package.json
delete mode 100644 commercial-paper/organization/magnetocorp/contract/test/contract.js
delete mode 100644 commercial-paper/organization/magnetocorp/gateway/.gitkeep
delete mode 100755 commercial-paper/organization/magnetocorp/magnetocorp.sh
delete mode 100644 commercial-paper/organization/magnetocorp/t.js
diff --git a/commercial-paper/.gitignore b/commercial-paper/.gitignore
deleted file mode 100644
index 65971ce8..00000000
--- a/commercial-paper/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-cp.tar.gz
-**/.gradle
-**/gateway/connection-org1.yaml
-**/gateway/connection-org2.yaml
diff --git a/commercial-paper/README.md b/commercial-paper/README.md
deleted file mode 100644
index b3e513ca..00000000
--- a/commercial-paper/README.md
+++ /dev/null
@@ -1,646 +0,0 @@
-
-
-# Commercial Paper Tutorial & Samples
-
-## Introduction
-
-This folder contains a structured set of smart contracts and application clients (ie. in a choice of languages, eg Node.js, Java, Go etc) relating to *Commercial Paper*, a finance 'instrument' (in Global Finance). At present, the Node.js sample contract in particular has further added functionality: an optional two-step authority check (see diagram below), when redeeming a commercial paper instance - and a range of sample ledger queries, to help consolidate your learning; both can be explored using the Node.js application client.
-
-While a more detailed 'explainer' of the Commercial Paper scenario (including use case analysis, code walkthrough & practices, logical/physical representation of ledger data etc) can be found in the [Hyperledger Fabric Commercial Paper Tutorial](https://hyperledger-fabric.readthedocs.io/en/latest/tutorial/commercial_paper.html), you don't have to read through this, just to try out this sample. There's also a [Wikipedia page](https://en.wikipedia.org/wiki/Commercial_paper)
-
-Key Objectives
-
- * see a Commercial Paper use case in action
-
- * explore the key 'takeaways': understand differences between asset _state_ changes ('e.g. 'lifecycle') and transaction _inputs_* (e.g. 'inputs' during lifecycle)
-
- * try out a number of different query types: asset history, asset state, ownership, partial key, named query (criteria-based), ad-hoc queries (you supply a query string) - presently available in the Node.js sample only.
-
- \* the smart contract uses these (along with business logic) to decide outcomes; some inputs change the asset _state_ (like 'ownership') ; some don't.
-
-
-
-
-Blockchain: benefits to Commercial Paper marketplaces?
-
- * replace long-winded, time consuming processing between multiple organisations - the network makes it one centralized hub and helps simplify workflow.
-
- * full transparency, traceability and ownership of issued papers
-
- * speed up a process that can take days - e. make same-day issuance a reality, or even a market paradigm.
-
- * in asset-backed commercial paper markets, blockchain can help increase accessibility (to a marketplace) to SMEs to partake in issuance, where otherwise it was inaccessible.
-
- * integration to other areas, like supply chain finance
-
-
-
-
-
- Expand the twisty below to see an overview diagram of a 'sample' Commercial paper marketplace - transactions, queries being executed by different organisations (we'll focus on two of these organisations)
-
-PaperNet Overview diagram - The sample commercial paper marketplace
-
-
-
-
-
-
-But first, it might useful to explain Commercial Paper, an unsecured promissory note issued to obtain capital, and operates in global financial markets. A Commercial Paper instance is represented as an asset with a lifecycle, recorded on the blockchain - transactions change its _state_ (over time) and those transactions, naturally - have _inputs_.
-
-
-#### Explainers
-
-Commercial Paper - what is it briefly?
-
-
-It is a type of unsecured promissory note, issued by established companies (eg big manufacturers, blue chip corporations) to gain short-term capital - usually no more than 6-9 months. Why? To meet short-term financial obligations. Commercial paper is generally purchased by money market funds and banks - in fact, it becomes a more important investment strategy during financial recessions :-) . A corporation issues a paper (in the form of a promissory note) for specific projects, such as big capital investments, to pay contractors or even to exercise debt restructuring. The tutorial describes MagnetoCorp (car manufacturer) who have landed a huge contract, and will need approx. $5m in capital (payroll obligations), to hire 1000 car workers for at least 6 months (with no car revenues yet - its a financial strain). Underpinning this, of course, is that MagnetoCorp, has every confidence that (say, in 6 months time) it will be in a position to pay out the face value ($5m in this case) when the commercial paper is redeemd by an owner of the paper, upon maturity :-).
-
-
-
-Ins and Outs, Attractions of Commercial Paper Investment?
-
-
-Investors (who buy Commercial Paper) are attracted as they agree to buy them at a discount (say $4.94m) on the face value (eg $5m) and moreso, they obtain a higher yield than if they were simply gaining interest in a bank (eg. 2% interest on $4.95m today = $5m in 6 months time). But there is a 'premium' attached, with carrying the risk of a debt/loan that is essentially unsecured (unlike a bank) - which is where credit risk and ratings comes in. As a result, the actual yield from the investment chosen is in effect $10k greater (than pure interest, in the example given).
-
-Once an issuing corporation becomes established in the commercial paper marketplace, it builds a high credit rating (risk affects how much of a premium investors seek and therefore discount accordingly) - in fact, it is often cheaper (for a blue chip company) to draw on a commercial paper than on a bank line of credit. But that rating reflects the issuer's ability to pay back on maturity.
-
-I mentioned marketplace: even during the typical 6-9 month period, a commercial paper can be bought and sold multiple times (its quoted, at the discounted price on money markets), before the Commercial Paper reaches its maturity date. On that date, the current investor (or owner) 'redeems' the paper bond with MagnetoCorp, the issuer and gets the face value of $5m.
-
-
-
-[_back to top_](#top)
-
-## Scenario Overview
-
-
-
-In this tutorial two organizations, MagnetoCorp and DigiBank, trade commercial paper with each other on 'PaperNet', the marketplace represented by a Hyperledger Fabric blockchain network. Note that there are two alternative transaction flows - one which mirrors the [Commercial Paper Tutorial](https://hyperledger-fabric.readthedocs.io/en/latest/tutorial/commercial_paper.html) as described in Fabric documentation, and one which requires the authorised owner of the paper to complete a transfer following a request to buy the commercial paper - the latter example features an authorization check in the smart contract that ensures the transactor is from the organization that currently owns the commercial paper - they approve and complete the buy request. These are the commercial paper transaction lifecycles you can try out:
-
-
-
-The tutorial exercises the commercial paper asset lifecycle: _issue_, _buy_ ( 1 to _n_ ) (or _buy_request_ / _transfer_ alternative), and _redeem_ transactions: the key 'takeaways' from the scenario are:
-
-- understanding the _changes in state_ in the commercial paper asset (reflected in the ledger world state) which reaches maturity after 6 months.
-- understanding the _transaction inputs_ for each transaction (some inputs change the asset _state_ - eg. ownership) and some _don't_ (e.g. purchase price) and not part of the asset - but importantly, the _inputs_ for a given transaction are recorded on the blockchain).
-- understanding the importance of _queries_ such as: asset history, rich queries (criteria matching etc), transaction history (where the inputs are recorded)
-
-Client applications (CLI based) are used:
-
-- to perform the transactions
-- run queries (Node.js sample only)
-- examine the transaction inputs (as opposed to _states_) that are written to the ledger after you perform a transaction (using the Node.js listener).
-
-This sample uses the `test-network` . You’ll act as Isabella, an employee of MagnetoCorp (Org2), who will issue a commercial paper on its behalf. You’ll then 'switch hats' to take the role of Balaji, an employee of DigiBank (Org1), who will buy this commercial paper, hold it for a period of time, and then redeem it with MagnetoCorp for a small profit or yield. Note that the smart contract sample doesn't enforce the actual hold period ; the user can, in fact, redeem the paper immediately.
-
-
-## Quick Start
-
-Below are the quick start instructions for running the tutorial. As mentioned, if you're interested in a 'deeper dive' analysis and importance of the concepts, design, structure and implementation of the smart contract, they can be found in the [Hyperledger Fabric Commercial Paper Tutorial](https://hyperledger-fabric.readthedocs.io/en/latest/tutorial/commercial_paper.html). Suffice to say, you DON'T have to have read this, to do this tutorial.
-
-This `README.md` file is in the `commercial-paper` directory, the source code for client applications and the contracts is in the `organization` directory.
-
-### High-Level Overview of Steps
-
-1) Install Binaries, Start the Hyperledger Fabric infrastructure
-
- The Fabric 'test-network' will be used - this has two organizations 'Org1' and 'Org2' DigiBank will be Org1, and MagnetoCorp will be Org2.
-
-2) Install and Instantiate the Contracts
-
-3) Run client applications in the roles of MagnetoCorp and DigiBank to trade the commercial paper
-
- - Issue the Paper as Magnetocorp (org2)
- - Buy the paper as DigiBank (org1)
- - Redeem the paper as DigiBank (org1)
-
- See also the transaction flow and alternatives in the Scenario Overview below.
-
-[_back to top_](#top)
-
-## Setup
-
-You will need a machine with the following
-
-- Docker and docker-compose installed
-- Node.js v12 if you want to run JavaScript client applications
-- Java v8 if you want to run Java client applications
-- Maven to build the Java applications
-
-You will need to install the `peer` cli binaries and cloned the `fabric-samples` repository. For more information see
-[Install the Samples, Binaries and Docker Images](https://hyperledger-fabric.readthedocs.io/en/latest/install.html) in the Hyperledger Fabric documentation. Once you have installed the cli binaries, ensure you have added the `bin` directory (for your `peer` commands used by scripts below) to your exported `PATH` variable in your `.bashrc` or `.profile` directory (per below). This is important as you will be opening a number of windows which will need PATH set. Finally, check that it finds the `peer` command in your PATH using the `which` command eg.
-
-```
-export PATH=:$PATH
-which peer
-```
-
-
-It is advised to have 3 terminal windows (consoles) open;
-
-* one to monitor the infrastructure
-* one for MagnetoCorp
-* one for DigiBank.
-
-Once you've cloned the `fabric-samples` - change to the `commercial-paper` directory in each window.
-
-```
-git clone https://github.com/hyperledger/fabric-samples.git
-```
-
-```
-cd fabric-samples/commercial-paper
-```
-
-## Running the Infrastructure
-
-In one console window, run the network starter script - this will start the two organization `test-network` blockchain network.
-
-```
-./network-starter.sh
-```
-
-You can re-use this console window if you wish, but it is recommended to run a docker container monitoring script in its own window. This will let you view what Fabric is doing and help diagnose any failures.
-
-```bash
-./organization/magnetocorp/configuration/cli/monitordocker.sh fabric_test
-```
-
-### Setup the Organizations' environments
-
-The contract code is available as either JavaScript, Java or Go. You can use either one, and the choice of contract language does not affect the choice of client language. With the v2.0 Fabric chaincode lifecycle, this requires operations for both MagnetoCorp and Digibank admin. Open two windows in the fabric-samples/commercial paper directory, one for each organization.
-
-In your 'MagnetoCorp' window run the following commands, to set the shell environment variables needed to act as that organization. The leading '.' in the command sequence sets in your current environment - if you do not run this, you will not be able to package the chaincode.
-
-```
-cd fabric-samples/commercial-paper/organization/magnetocorp
-. ./magnetocorp.sh
-```
-
-You can either copy and paste them directly into the terminal, or invoke directly in your own command shell. For example if you are using bash or zsh on Linux you can use this command.
-
-```
-source <(./magnetocorp.sh)
-```
-
-Similarly in your 'DigiBank' window run the following commands as shown:
-
-```
-cd fabric-samples/commercial-paper/organization/digibank
-. ./digibank.sh
-```
-
-[_back to top_](#top)
-
-
-### Deploy the smart contract to the channel
-
-You need to perform similar operations for _both_ organizations and for your language choice from the instructions below. For the different contract languages, the steps are very similar - the full set of steps are actually shown in the JavaScript section (see twisty). However, you will perform one or two different initial steps for Java or Go before completing the remaining common steps as instructed in those language sections.
-
-Note that the commands below make use of the `jq` utility for parsing output - download and install it from [the jq download page](https://stedolan.github.io/jq/download/).
-
-
-**For a JavaScript Contract
**
-
-
-Running in MagnetoCorp directory:
-
-```
-# MAGNETOCORP
-
-peer lifecycle chaincode package cp.tar.gz --lang node --path ./contract --label cp_0
-peer lifecycle chaincode install cp.tar.gz
-
-export PACKAGE_ID=$(peer lifecycle chaincode queryinstalled --output json | jq -r '.installed_chaincodes[0].package_id')
-echo $PACKAGE_ID # FYI may look like this: 'cp_0:nnnxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
-```
-
-```
-
-peer lifecycle chaincode approveformyorg --orderer localhost:7050 --ordererTLSHostnameOverride orderer.example.com \
- --channelID mychannel \
- --name papercontract \
- -v 0 \
- --package-id $PACKAGE_ID \
- --sequence 1 \
- --tls \
- --cafile "$ORDERER_CA"
-
-peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name papercontract -v 0 --sequence 1
-```
-
-Running in Digibank directory:
-
-```
-
-# DIGIBANK
-
-peer lifecycle chaincode package cp.tar.gz --lang node --path ./contract --label cp_0
-peer lifecycle chaincode install cp.tar.gz
-
-export PACKAGE_ID=$(peer lifecycle chaincode queryinstalled --output json | jq -r '.installed_chaincodes[0].package_id')
-echo $PACKAGE_ID
-
-peer lifecycle chaincode approveformyorg --orderer localhost:7050 --ordererTLSHostnameOverride orderer.example.com \
- --channelID mychannel \
- --name papercontract \
- -v 0 \
- --package-id $PACKAGE_ID \
- --sequence 1 \
- --tls \
- --cafile "$ORDERER_CA"
-
-peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name papercontract -v 0 --sequence 1
-
-```
-
-Once both organizations have installed, and approved the chaincode, it can be committed.
-
-```
-# MAGNETOCORP
-
-peer lifecycle chaincode commit -o localhost:7050 \
- --peerAddresses localhost:7051 --tlsRootCertFiles "${PEER0_ORG1_CA}" \
- --peerAddresses localhost:9051 --tlsRootCertFiles "${PEER0_ORG2_CA}" \
- --ordererTLSHostnameOverride orderer.example.com \
- --channelID mychannel --name papercontract -v 0 \
- --sequence 1 \
- --tls --cafile "$ORDERER_CA" --waitForEvent
-
-```
-
-To test, try sending some simple transactions.
-
-```
-
-peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com \
- --peerAddresses localhost:7051 --tlsRootCertFiles "${PEER0_ORG1_CA}" \
- --peerAddresses localhost:9051 --tlsRootCertFiles "${PEER0_ORG2_CA}" \
- --channelID mychannel --name papercontract \
- -c '{"Args":["org.papernet.commercialpaper:instantiate"]}' ${PEER_ADDRESS_ORG1} ${PEER_ADDRESS_ORG2} \
- --tls --cafile "$ORDERER_CA" --waitForEvent
-
-peer chaincode query -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com \
- --channelID mychannel \
- --name papercontract \
- -c '{"Args":["org.hyperledger.fabric:GetMetadata"]}' \
- --peerAddresses localhost:9051 --tlsRootCertFiles "${PEER0_ORG2_CA}" \
- --tls --cafile "$ORDERER_CA" | jq '.' -C | more
-```
-
-
-
-
-**For a Java Contract:
**
-
-
-Before the `peer lifecycle chaincode package` command below, you will first need to change into each organization's `contract-java` directory and issue
-
-```
-./gradlew build
-```
-
-Then complete the steps below.
-
-
-Running in MagnetoCorp contract directory:
-
-```
-# MAGNETOCORP
-
-peer lifecycle chaincode package cp.tar.gz --lang java --path ./contract-java --label cp_0
-peer lifecycle chaincode install cp.tar.gz
-
-export PACKAGE_ID=$(peer lifecycle chaincode queryinstalled --output json | jq -r '.installed_chaincodes[0].package_id')
-echo $PACKAGE_ID # FYI may look like this: 'cp_0:nnnxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
-```
-
-```
-
-peer lifecycle chaincode approveformyorg --orderer localhost:7050 --ordererTLSHostnameOverride orderer.example.com \
- --channelID mychannel \
- --name papercontract \
- -v 0 \
- --package-id $PACKAGE_ID \
- --sequence 1 \
- --tls \
- --cafile "$ORDERER_CA"
-
-peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name papercontract -v 0 --sequence 1
-```
-
-Running in Digibank
-
-```
-
-# DIGIBANK
-
-peer lifecycle chaincode package cp.tar.gz --lang java --path ./contract-java --label cp_0
-peer lifecycle chaincode install cp.tar.gz
-
-export PACKAGE_ID=$(peer lifecycle chaincode queryinstalled --output json | jq -r '.installed_chaincodes[0].package_id')
-echo $PACKAGE_ID
-
-peer lifecycle chaincode approveformyorg --orderer localhost:7050 --ordererTLSHostnameOverride orderer.example.com \
- --channelID mychannel \
- --name papercontract \
- -v 0 \
- --package-id $PACKAGE_ID \
- --sequence 1 \
- --tls \
- --cafile "$ORDERER_CA"
-
-peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name papercontract -v 0 --sequence 1
-
-```
-
-Once both organizations have installed, and approved the chaincode, it can be committed.
-
-```
-# MAGNETOCORP
-
-peer lifecycle chaincode commit -o localhost:7050 \
- --peerAddresses localhost:7051 --tlsRootCertFiles "${PEER0_ORG1_CA}" \
- --peerAddresses localhost:9051 --tlsRootCertFiles "${PEER0_ORG2_CA}" \
- --ordererTLSHostnameOverride orderer.example.com \
- --channelID mychannel --name papercontract -v 0 \
- --sequence 1 \
- --tls --cafile "$ORDERER_CA" --waitForEvent
-
-```
-
-To test, try sending some simple transactions.
-
-```
-
-peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com \
- --peerAddresses localhost:7051 --tlsRootCertFiles "${PEER0_ORG1_CA}" \
- --peerAddresses localhost:9051 --tlsRootCertFiles "${PEER0_ORG2_CA}" \
- --channelID mychannel --name papercontract \
- -c '{"Args":["org.papernet.commercialpaper:instantiate"]}' ${PEER_ADDRESS_ORG1} ${PEER_ADDRESS_ORG2} \
- --tls --cafile "$ORDERER_CA" --waitForEvent
-
-peer chaincode query -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com \
- --channelID mychannel \
- --name papercontract \
- -c '{"Args":["org.hyperledger.fabric:GetMetadata"]}' \
- --peerAddresses localhost:9051 --tlsRootCertFiles "${PEER0_ORG2_CA}" \
- --tls --cafile "$ORDERER_CA" | jq '.' -C | more
-```
-
-
-
-
-**For a Go Contract
**
-
-
-Before the `peer lifecycle chaincode package` command step, you will need to change into each organization's `contract-go` directory and issue
-
-```
-go mod vendor
-```
-
-Then complete the steps below.
-
-
-Running in MagnetoCorp contract directory:
-
-```
-# MAGNETOCORP
-
-peer lifecycle chaincode package cp.tar.gz --lang golang --path ./contract-go --label cp_0
-peer lifecycle chaincode install cp.tar.gz
-
-export PACKAGE_ID=$(peer lifecycle chaincode queryinstalled --output json | jq -r '.installed_chaincodes[0].package_id')
-echo $PACKAGE_ID # FYI may look like this: 'cp_0:nnnxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
-```
-
-```
-
-peer lifecycle chaincode approveformyorg --orderer localhost:7050 --ordererTLSHostnameOverride orderer.example.com \
- --channelID mychannel \
- --name papercontract \
- -v 0 \
- --package-id $PACKAGE_ID \
- --sequence 1 \
- --tls \
- --cafile "$ORDERER_CA"
-
-peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name papercontract -v 0 --sequence 1
-```
-
-Running in Digibank
-
-```
-
-# DIGIBANK
-
-peer lifecycle chaincode package cp.tar.gz --lang golang --path ./contract-go --label cp_0
-peer lifecycle chaincode install cp.tar.gz
-
-export PACKAGE_ID=$(peer lifecycle chaincode queryinstalled --output json | jq -r '.installed_chaincodes[0].package_id')
-echo $PACKAGE_ID
-
-peer lifecycle chaincode approveformyorg --orderer localhost:7050 --ordererTLSHostnameOverride orderer.example.com \
- --channelID mychannel \
- --name papercontract \
- -v 0 \
- --package-id $PACKAGE_ID \
- --sequence 1 \
- --tls \
- --cafile "$ORDERER_CA"
-
-peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name papercontract -v 0 --sequence 1
-
-```
-
-Once both organizations have installed, and approved the chaincode, it can be committed.
-
-```
-# MAGNETOCORP
-
-peer lifecycle chaincode commit -o localhost:7050 \
- --peerAddresses localhost:7051 --tlsRootCertFiles "${PEER0_ORG1_CA}" \
- --peerAddresses localhost:9051 --tlsRootCertFiles "${PEER0_ORG2_CA}" \
- --ordererTLSHostnameOverride orderer.example.com \
- --channelID mychannel --name papercontract -v 0 \
- --sequence 1 \
- --tls --cafile "$ORDERER_CA" --waitForEvent
-
-```
-
-To test, try sending some simple transactions.
-
-```
-
-peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com \
- --peerAddresses localhost:7051 --tlsRootCertFiles "${PEER0_ORG1_CA}" \
- --peerAddresses localhost:9051 --tlsRootCertFiles "${PEER0_ORG2_CA}" \
- --channelID mychannel --name papercontract \
- -c '{"Args":["org.papernet.commercialpaper:instantiate"]}' ${PEER_ADDRESS_ORG1} ${PEER_ADDRESS_ORG2} \
- --tls --cafile "$ORDERER_CA" --waitForEvent
-
-peer chaincode query -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com \
- --channelID mychannel \
- --name papercontract \
- -c '{"Args":["org.hyperledger.fabric:GetMetadata"]}' \
- --peerAddresses localhost:9051 --tlsRootCertFiles "${PEER0_ORG2_CA}" \
- --tls --cafile "$ORDERER_CA" | jq '.' -C | more
-```
-
-
-
-
-
-
-
-[_back to top_](#top)
-
-
-## Client Applications
-
-Note for Java applications, you will need to compile the Java Code using `maven`. Use this command in each application-java directory
-
-```
-mvn clean package
-```
-
-Note for JavaScript applications, you will need to install the dependencies first. Use this command in each application directory
-
-```
-npm install
-```
-> Note that there is NO dependency between the language of any one client application and any contract. Mix and match as you wish!
-
-The docker containers don't contain the node or Java runtimes; so it is best to exit the docker containers - but keep the windows open and run the applications locally.
-
-As mentioned earlier in the Sample introduction section, transaction _inputs_ are recorded on the ledger, as well as any asset _state_ changes. Just *before* you run the _issue_ application script below - you need to launch a block 'listener' application that will show you these _inputs_, as you complete each transaction in the commercial paper lifecycle (eg. Paper Number: 00001, 00002 etc) .
-
-For the listener, its best to open a *new* terminal for this in the `commercial-paper/organization/magnetocorp/application` directory (javascript). Next, run the `addToWallet` step in the `issue` transaction below, to add Isabella's identity to the wallet - the listener will use this wallet. Once the listener is launched, it will show the inputs for transactions you will perform and which are committed to blocks (ie part of the ledger). Note: initially, the listener may show a spurious message, and then go into a _listening_ or 'wait' state. As transactions complete below, messages will be displayed by the listener - so keep an eye out. *After* adding Isabella's wallet, you can then launch the listener as follows:
-
-```
-node cpListener.js
-```
-
-**Issue the commercial paper
**
-
-The paper is issued by *MagnetoCorp*
-
-You can now run the applications to issue the commercial paper. Change to either the
-`commercial-paper/organization/magnetocorp/application` directory (javascript) or `commercial-paper/organization/magnetocorp/application-java` directory (java)
-
-*Add the Identity to be used to the wallet*
-
-```
-node addToWallet.js
-# or
-java -cp target/commercial-paper-0.0.1-SNAPSHOT.jar org.magnetocorp.AddToWallet
-```
-
-*Issue the Commercial Paper*
-
-```
-node issue.js
-# or
-java -cp target/commercial-paper-0.0.1-SNAPSHOT.jar org.magnetocorp.Issue
-```
-
-Don't forget to check the application listener for messages above!
-
-
-
-
-
-**Buy the commercial paper
**
-
-_Buy_ is performed as *Digibank*;
-
-You can now run the applications to buy the paper. Change to either the
-`commercial-paper/organization/digibank/application` directory or `commercial-paper/organization/digibank/application-java`
-
-*Add the Identity to be used*
-
-```
-node addToWallet.js
-# or
-java -cp target/commercial-paper-0.0.1-SNAPSHOT.jar org.digibank.AddToWallet
-```
-
-*Buy the paper*
-
-```
-node buy.js
-# or
-java -cp target/commercial-paper-0.0.1-SNAPSHOT.jar org.digibank.Buy
-```
-
-If you have just executed a `buy` transaction above - jump to the `redeem` transaction below - otherwise execute the _buy_/_transfer_ sequence as described earlier.
-
-*Alternative: Request to Buy the paper (buy/transfer)*
-
-```
-node buy_request.js
-```
-
-Now complete the _request_ by switching to the `MagnetoCorp` application directory (javascript) and execute a `transfer` transaction as MagnetoCorp:
-
-```
-cd ../../magnetocorp/application
-
-node transfer.js
-```
-
-
-
-
-**Redeem the commercial paper
**
-
-_Redeem_ is performed as *Digibank* - the current owner (buyer) in the lifecycle.
-
-You can now run the applications to redeem the paper. Change to either the
-`commercial-paper/organization/digibank/application` directory or `commercial-paper/organization/digibank/application-java`
-
-
-*Redeem*
-
-```
-node redeem.js
-# or
-java -cp target/commercial-paper-0.0.1-SNAPSHOT.jar org.digibank.Redeem
-```
-
-
-
-
-
-**Perform Queries: Ownership, Asset History etc (Node.js sample only)
**
-
- Having completed the full commercial paper lifecycle for one paper (paper number: 00001) some queries below won't show a lot of data - as an optional exercise, you can change the scripts above (paper number: 00002) to create another paper lifecycle and run the `queryapp` application below (change query 1 to the new CP number FYI), with more data available. As indicated, the query transactions mentioned are presently only available in the Node.js sample.
-
- Execute the Node.js application client script, which will run the following 5 queries, in order:
-
- - History of Commercial Paper (Note: the paper state is shown more descriptively eg. 'ISSUED', 'TRADING' and based on currentState values on ledger)
- - Ownership of Commercial Papers
- - Partial Key query, for Commercial papers in org.papernet.papers namespace belonging to MagnetoCorp
- - Named Query: all redeemed papers in a state of 'redeemed' (currentState = 4)
- - Named Query: all commercial papers with a face value > $4m
-
- From the `digibank/application` subdirectory run:
-
- ```
- node queryapp.js
- ```
-
-
-
-
-When you're done with this section, return to the terminal where your Node.js _listener_ application is running, and terminate the process.
-
-## Clean up
-When you are finished using the Fabric test network and the commercial paper smart contract and applications, you can use the following command to clean up the network:
-
-```
-./network-clean.sh
-```
-
-[_back to top_](#top)
diff --git a/commercial-paper/img/overview.png b/commercial-paper/img/overview.png
deleted file mode 100644
index 9da7aced3a6f91968535c95aa52433bff87881cd..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 122143
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%0AM-pdkFTW=ixLJa?v{5dpI0M
z%O2MMcD(CL(lZW%RqSELF&Lcyhq}(hS6zaOp59EejKX_=QCGh2wog;mraIAL_UF)$
zjp!#GVMBUA?U}!^uKesVOvq1$>HaRfo=hM_X7G3w8e!Z3WU#7gTJ`rw)x}$&J4eUl%}o*qD;+cA;&+Vi
zOpiQJ|GN^(Kc}`VJRyP0J}wr#n^(8`2ZknkXlF508Lh3Y83B;0ql2EI{-d&wV%R&g
z3lEfkfA}YpZv|2{92>iUnpLNdPO#os(2MrCFl?(Yfj@N2=j3EpD<>R&oGFRp3BD$B
ztMR4$^Jldcpf0LrFZWuLZf(E=Z0L75V;)w~_xp9N8>#
zcbiV?2#c&(Nl2*u_VUGxfjrCMJ8%&|kHTM1;TL3A>zx<%wco@1dsq8T{$#B0DzJyu
z)qFH#M#_Z*MDnML-`&YCZEiN+up4A$o0-~+dng2dmCd?-3fz+k@88n`Kvr_{IuQ~;
z)6>&4xd~83Kr7$VQ^PtEe6g2(6#8eY{i8e31%7dJ#!21fed?S9U5FpTs{mo(
zrWO3@51eWs6oh$jYiJo8#_W&F)&K`BaHzN+x`W#u(vV#_`j(xFYF3{kCw`ATjEnzu+woE0q6p--@ib`F3&KoceFJq
zr`>sb-wv=9Ko0SPVH>$qCZ{t2B_ba`e>MGpFR+@!=H-CMA^*hlzgS}poI*MHQ6%&V
z2TZX34ijr9tP_6#U6^b0HwFzTOJGKS)H4$uH7UG_?JX-CWF=4VfPj&WPZf|I)_x=v
zF9Ve~z@oqaUF$`rh_f8BI++6GTo9#L6}P7~3z_XW&{dFTFm}#0oJPlr`VSeCKCBxK
zhGPy;VjW`Xp%ep_4=O4u^k9A2IBD(qZ;TdH08A@r_-GIxAOG}{eSjV6<1=Uk}#i~jAU;QYzSsUp1G43+^#LpJ0I
z+@2G;742YJ$h*dTuiyb-im9p^;oHLVn+zZaV>8=mS^fFG^YGetUpyLj;YOy~idicw
z5sR2BA~rVm9{GDYru);liPCZ>s%mNlA3i7!B1%}exbzIgK_Y6k0c-U&CBjQ1huV$(
zXt#zUwjhh2KpAQ1YV86bPd-SWf^5uIaFlR>yuJ#G->c|Bw6Y8kC8()f>MQsaKL{EXjHKBywX*f#_awKGiZ0R08AuSAJu&ajU_gY9c%Ti}IDN
zguqrW+?H=*}i_8ZdLcsAcT}$A4_lgNn(J1*W*q-!i
zZ4P^S=$#~^iQNkWi8~;rtqrWP&kPeRpRrZokY+xtHs9a;_;uqM`|FMqK3MH^n&Iwd
z1S;RI!>-Hzf@H7J>1#XLWFpIYi}ho3J);l9FaDe>kN%u1%@8k)jRfw7o)<4LG>7rZ
zf~cATju0OOIET15Me0g%=AbKcXDAAWmIgMd>RJwS3U}sF?gqckZ!8|%a;*ThMPn>8
zv5m%7gNrf)WCy-
zo9&)>2b5HG(swswq6ETo4|05~nlyu9V@{TsamDB2m?#|n$NS&v(?>;Qzq#B6iBUAqo-
zHaR6p&CNd34I5k3p9|n->WH5Wkqyv{r}jMAkn7xTZ!b3oV#FGWi3jCKg4MJw!%3aW
z(&l!vZ!;Na0U=RapDMNG9_xr)tsm)_ws>g+V*!a1F^RnAY9Br;E93Luh-?<;?-Y<_c4q293Bz8-Q
zy|0HVuqcxZ7uV^eQHmkBImC*F;k
zSXGz7i*Xlb=80%2ZEUAFSCJeUUOMUD5d+5(?Lv&P&qw>h;fpOpnRs#@^cbxUIy@8m
z|K%nCAq3K0f`?$rANqMb&8kc4_unt?
zKMayiW?tXsT=so}g3aq50
zL_hiALX*21^Jv)1m5sOkWAgHH-GKOYz2ooa_jHv;Z6w60_>1VljA9txymCLzm&>^<
z?E1lplmJzJJ8CH}UfzpvEvo*NLx#qS?(D?yaptv7ap6^Gvs4MLC>MJRiDITFd)eo9
z-a09Hi_-12G_h*St6$d22ZPnjnd9CUPk|UE%ZhM!l
zxm%D9D+2etnYUGg8Yu#Z*#MA1SsUS0SiZ5GEyZ-y&}+t(S97gMX4
z6J;`gHApRZf!ZH_y4RPts^)U@&3esZ8O1x%Lw7IxtVSYA;sa#zv6c7f6KMvu#j{6^
zPS8DP!(99_w#L)e#YAh!{Nd79W_D7^>d`zmbMI6)?LGeu_|rWahuHX5%Pn^4!sXKj
z9;4*w%X!}$&$Z6kp-lq0zGh^t08ru9h=^4_iNa@-eH}t8-Wyv24qc{%w+_IhU`PV8rg>WFmti+3G(S_+UlH^eDAmlZyuA(iMTQkwG9{7Gg3TU@Y0EYS`mkg|
z$9n-;2%IV_VnJV;PNT<-`28N-<5
zJ$k0VzQ;!P!xHK^wRN=o3CJIW1Vsx9VnEUu!&r_AkcFKfNqMF_hO;C6Q|AM=VM9IV
zyubd>Fmrw5!q~0OjS)5eI8w)tPGfME&f%pMdR|`MnCy@*0~P*Tg->gyj%v!a_gZg!
z4{3g0MTc_o%TO_83Y*_V3@n0hFwt;&9NRZPdigO~-KgWFrodq6t^8@A&^D&hwwl9()uZXR*^cZxaUFJ_)fW^nZp3DMdB(Fq
z3ldYxeLmyS$q#HQo3^h1^&7JY>yFGej;+XqH_Pq}Gts=pU&7bX)h*bNAy$sk?u1kB
zQpRw?s|+pf>X(}&P0XZoX1{d+Zel(Q00ad5ID9>N{GnzKyMtuNR`C}D;hL-ZuKSFz
zN!>|45uT5Rx^|*He40`1rmmTuD2!QWIk#4}$MCvI&uE@m`6x2aS~W;N=4*X(?k!1a
zpU@n5Of8V`Ar;QZfMXdQtM&l8yrPSWdcnwx)_#{T
zrWKA!-t<&%Z|n?ubq$Q}J=NoySJ&Deu(|d#Lc`w!fpOui3o&`6>g#(uy!^mUKC1vK
zn+(j1gX8qv3#WBte-EJ#gys?<1W>5lOa5qQ2#ax-hFAbA&xaicz&m+jcyw|yMScqK
zD4Z$s$=H^*Pn-vh%Rq{hH(MG
zk=WxqZ#CnSQ0!oXMNLlJ4YWZat~iQSKWr4^D6>`4XX*DVr7
z%7(T9&rf>K_pZLzuXTnGR{4F0G;xl+jUr!nl#g7Mbk!6ep%MlZi589T`|MJ$3M%4S
zdvK^a^*C6Iikt+(u!V;=*F6ur`X@7N@2Sqvy!5*J>hs$A>cGT2W3O2T+DbMc`#l|_
zL2H$4o%wtxJ14LBdojba>W(m+MA#QAR|#umFd6hc+2Z+d2w;V)1wPHk6Y{h%hN*<5B3g=mVKNr7!l^Y_;C4*ns|<
z(M#%3RT50{X}cW*3-;2Ywo|jMjmo8DRP(G(tcW1n1^M|oVDFM=#
zD&jHq)rV>EIar<@qvJBI10GLcVBoGug!fd%oZ)xkLqI(>5)$Q;SQeQXq{$18?@P|2
zLT+fCT=p=uJ`B}co-Q&`prTTnPbVT`0FJ4(tl`~b-(glp2RBxqkM1<(m&3L@f89b*StgeaRV*1eI5_-9n6SQvVtHSyXDzldX^9orG_T~H
zxgO@TX;A6slkolykx&&W&!8PV$#1o{%$URTPJB?pc{ARi0OwvDABiO~K4AedcUWN7
z%F!n)k-5|@DwA}|;r9A7dBcK{ZYvr3c;@KyLzaW(fos#rbPayHs4>ZJyza5C@`Cgc
zJM-0%Qc0p<)5olnM>t9utV`HKX8~3=tm^a2BRL=g@yNWIe5Q`?nCiR|bzb|@)xH4k
zd>7ZEQ-iZdOhZ%iQ^^tZ9}dr*umi&68lRxKs!>Hp|PB=sN@$DqXej-EWFNQ#f4T
zzCAIuvEYs1VZ5DAFT>_34+wVlwND8Nf`uPl&dnIj)^y=dmkqxrFly1{5H+SgYXscP
zGOPKYVjQ6MaKFrSj)|G+7#HtEHUXw@30X|Oz781XS~=GAz#GkaasED;LCQNn{+GRn
zLY9Vcn%5B--|PHYi56~ZDZbn9tF-*ChAJ24+)Dbs4Q%gqD&gwYb$bb5(Z4|u-ITwM
zS8@%QUu@+0U2~b(Sdh289cIlv!H)Sx_58fO|2uu*e*sXa-}PMTdrsVNzFx=?E9s
zUe|`&rI${ql*VSm&KkVDK_qD-rKt|fn3WI5+49O2MiE{naS8+CXe*YtZbTx?18Y35
zh=i|2ZWJwD`|gAR5MZxNI}$xwDb+E!-G3{K_@&2~;Wk
zs7Dxz76eD_w&^{99;VM>j-(g|HF9_O1#;J`WR0}8^^Z4KC2BL*zdl?&k3ZV7M4txY
z^*%GpUd-9=-||h4k0;5;q6b=j$|)t&v$3i6zPfE6yG{ucxs0upZ)jBPC;Lo(r^*l}
znyB68Ku<8|wqnq?Ac`drB!gk)?0mq!VN?A?PmhWB;9x?M?{ea3=?6jsg5XHr=Pa&)
z{0Ifb=*D(G^FXOvPEmj=77s|`i|rU^hPmJHvDL=x?~w{e$%}jLWqRP$u3~Mx?u(6y
zdBN`KhTFZ3Mfr%<876p%-%;B@294vD!YzLkCrtuaPu
z^o}mb>}ct7A^9Ia8t{{he2x|fxo;WS$73Ko!h$8QLNTxcDoDRlZXbqa*kfJhJ|ueh
zX~!aSLhqH1Xw6l4gTp!#B_GT--{qN0$JWu(00Qh_@Y{Tqo8Kcp(7+Ck<8dv*DlDzr
zB@7R&KHC9(n5qNqxy^1YJo#8Q2<7_wGx9!)CONs8gWtgw!0g`gO>m4bXA4^j_L*TJ
zV=1k%XW~Hi{N0(%xt>K+)S{VN2@+T^$hgb*t6Yk`+Wc3twP&(mmii)WyO037X?~Mr
zB2C3iE#*Fsm^@a$9_J;!43x^-2&ss^Jkwuw)T#BBj1i*Xe<7+}#yXGt}sa`EmG9
zep>_bTS67N=gaKkk8*2vfWB)6+SO#+b0!!;>KNmk5aq0{$4YixFSfPBL`_Lf>w%At
z-!wGY5?Qg-r0tnDG?MG(Z`2Wni$7L{7`SZ2L}%^kS%YqfB)6oe6^Ofhq|*xE+KJEn#G1U-Tt6&H
z>GT8Lo0!8Q5Z|J=Y;?Q>^Jup6>^(e2yNRl0
zX^+n-zibz`l?BLK_#W=0L2-}!l=A#mSNbg`c=%~YrTog;u|i;;okbO-PZ0r|t}a&w
zC2uB&-`esWX1CF;w4by^U3GX`Ug|HV_$Jh5Kt@fTEP&rNW1sokU0R
zV`gUPFY9*3&YNqeRlUzsPgC#?>+HiTDodq-WT>VhdT7LEB`!Uktgz#5|CeE&o^r$O
z@n5&6qtdoWyWl9m3#mtL@Incv`y0>Yhr57t#=Y#S?LqoSxMK6BcCi2{$)8!2=p-p(}
zeJ3t0_@il)mx{S>3YX~ws^I>cm__#TF?c3Fa6k^iF?Ci8<+wMQBkQTkI9C`#TF8?t
zG)Tr@C(@Sf#_~-3${M;{6ZQVaPg|d-X1PP$&Rj2t6{R4VRCrVmy%v|{yC`5k{OF`Z
z)J9GBHE@d&x4B36JJFSk+aj7qFqqAKTmaR7TUiDfL^e{(KxbJF!(|L
z4(A3sAIqxgoEm`iDD>P{?eHel#GrZ@v6~T7%YOOwE!tGcO??|Pg`Hl5bD;O|@0+b5
zTsMw)-Fenpj0Nqk!$N)NGqMSZu1KT#&B3|b2zI?pU*cLDsQ*O??w}yDtk3l
z=%2y8${;dT@+x~N@<*=Vtk-1g+_Uw!R?-(jhQaIW3q9ou7l0`6YH0Snedq{k-hM6U
zy}cAHxE=WICK33Ke|+eL+Xusw-ldkU3vT06Czf8#OK6+2+#F3)mz1?nJY|e^Xoq~)
z(&>Ox&X1*$oWD2v5K3*#M~Xv^X3CSPzt5aWf4^^^Qm3eT
zDKC8~ns)Xs`1i4nW1d8-v(g~xM%z-osD*2k#S@FS!ou%k9F(q)-~!u1N8N))MCUoS
zGEyd|er1KAUwf%ol6@J_F#~5`5Z)Q>FZ`Nk>0!H@D5%7SHD&LbBjGu`kJDy;W2P;2
z@O(t(C-Ii{A?|2vy;Vk|uifYo?ns-#jdVtNb6M%t&-;vvCszkY)n6sVi^?r7gtA8>
zJW5PyT`P>Q-`#9Y9%m1}NdV*r@xXv)7XM-1pJ(v)sQ_`VXTw4cM|Oi-2NE;XxXVEf
z3!R1Q`(am}XW3~RxJd*aO=ZJn(>KhoTYjC6Yr2?Uq&u{kRq#FSqAO^Zzn1?@Dr&pn
zIydZrPQKtL`}QV%!#@=^qsLJuuM4J{tex;8{xBO7G}0z
zUracE)acD9|3TV+M7bcYKJZGP?~2$u&4Ql05+35vj1*Rjn<4PV6+3ivbOavMX05J5
zfk7+!(NiQU>$lmr1}Ci295zSm$Xe^Nl7fRsCES`w7QOS3u|F
zXzYF@mK0Ro+fG;+S7BlDb#phvB}YO_D)}MOkQ^f@PTV3y(*v50PVc&X2tla_DJ4P<
zfeBa5E|w|=)YRo@TwF6xO}8Y4EpAo6gPAWiw@8|8M`s-FRds`5LFJs~U4^6B!%<1*
z=4j;~R(r_=R#h*yU(d6YOGm#Pzy7$$Y3%QfiWqcc-{x8>>q7QTWl;&&V$aUy
z>q>BM|4gT#B=u+IZ^8E(&QZZW>89owDm@YViTLRwZ_8cfSHAKkftg@-o~<3v*-$D0
zzt~dL=12?O+t-ZM9)pk%s<1utMLDUo2pnFvq{TVwSJ+%cFEZMsCBl_zZ?t_y(mK2CY-))h9>NtN!vW
zFF|owP5+`e13b3tBZZ_rS^T*ZYTubsTd^sHlUG4sLVuF#{RsGR!U5m)ICURl)bGiM
zn_u}>aE_uT!c^u5?Uh=JH(&KFPs+Ily2>-k1DA`NZicK!x8YhFdh1VH>bN^hM&Xv1
zDFHdyntSl$!6Ea^afcr1=Uw~7ZN^e*!n95U9_X_P8>4Q1e@&3hiinwui?#Ur`Wmt?
zGUut3QA&U^u45~YVFXlP$y#*ALFVZ99A7bmb9NZzG;YnM(~B1_6ko1ro*3xpe1gD@
ze0?*e)=Td?F9lC*xzfVp+|)~%bmbJE_)H#kIE>
z@OLF#$%$<^rl(9YC*z5E4IdGeUGB&sYihK#c3`-Jm~dvZ4BAlo53+vc(U%<45_lGu
zl~sd+px<0Y2{OzzoKuzK)sO$A5nyZ-Eb{OacZ{#^*wP9nG#3SV{(MdV(gD^V4-tzP
zn@??YQ&Obs8ij$=8%)r-zIX4QDnQuX9~}|#Z!sqI00X}6Tf(GCUCau0x6g}~tyc#Y
z9Jaxcb0%oGxl)e4srZp%w1Qy{Ig!|fAz*1SNI!g9OD
z