mirror of
https://github.com/hyperledger/fabric-samples.git
synced 2026-06-23 01:55:10 +00:00
Merge branch 'main' into feature/linty
Signed-off-by: jkneubuh <86427252+jkneubuh@users.noreply.github.com>
This commit is contained in:
commit
8cb40d5de3
26 changed files with 206 additions and 90 deletions
13
.github/actions/test-network-setup/action.yaml
vendored
13
.github/actions/test-network-setup/action.yaml
vendored
|
|
@ -10,6 +10,12 @@ inputs:
|
||||||
java-version:
|
java-version:
|
||||||
description: Version of JDK
|
description: Version of JDK
|
||||||
default: 11.x
|
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:
|
runs:
|
||||||
using: "composite"
|
using: "composite"
|
||||||
|
|
@ -35,12 +41,15 @@ runs:
|
||||||
- name: Install fabric CLI
|
- name: Install fabric CLI
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
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
|
echo ${PWD}/bin >> $GITHUB_PATH
|
||||||
|
|
||||||
- name: Pull Fabric Docker Images
|
- name: Pull Fabric Docker Images
|
||||||
shell: bash
|
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
|
- name: Install retry CLI
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
|
||||||
4
.github/workflows/lint.yaml
vendored
4
.github/workflows/lint.yaml
vendored
|
|
@ -7,9 +7,9 @@ run-name: ${{ github.actor }} is linting fabric-samples 🎉
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
branches: [ "main" ]
|
branches: [ "main", "release-2.5" ]
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [ "main" ]
|
branches: [ "main", "release-2.5" ]
|
||||||
|
|
||||||
env:
|
env:
|
||||||
GO_VER: 1.18.3
|
GO_VER: 1.18.3
|
||||||
|
|
|
||||||
4
.github/workflows/rest-sample.yaml
vendored
4
.github/workflows/rest-sample.yaml
vendored
|
|
@ -10,10 +10,10 @@ env:
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
branches: [ "main" ]
|
branches: [ "main", "release-2.5" ]
|
||||||
paths: [ "asset-transfer-basic/rest-api-typescript/**" ]
|
paths: [ "asset-transfer-basic/rest-api-typescript/**" ]
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [ "main" ]
|
branches: [ "main", "release-2.5" ]
|
||||||
paths: [ "asset-transfer-basic/rest-api-typescript/**" ]
|
paths: [ "asset-transfer-basic/rest-api-typescript/**" ]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
|
||||||
4
.github/workflows/test-network-basic.yaml
vendored
4
.github/workflows/test-network-basic.yaml
vendored
|
|
@ -7,9 +7,9 @@ run-name: ${{ github.actor }} is running the Test Network Basic tests 🔎
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
branches: [ "main" ]
|
branches: [ "main", "release-2.5" ]
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [ "main" ]
|
branches: [ "main", "release-2.5" ]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
basic:
|
basic:
|
||||||
|
|
|
||||||
4
.github/workflows/test-network-events.yaml
vendored
4
.github/workflows/test-network-events.yaml
vendored
|
|
@ -7,9 +7,9 @@ run-name: ${{ github.actor }} is running the Test Network Events tests 💡
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
branches: [ "main" ]
|
branches: [ "main", "release-2.5" ]
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [ "main" ]
|
branches: [ "main", "release-2.5" ]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
events:
|
events:
|
||||||
|
|
|
||||||
4
.github/workflows/test-network-gateway.yaml
vendored
4
.github/workflows/test-network-gateway.yaml
vendored
|
|
@ -7,9 +7,9 @@ run-name: ${{ github.actor }} is running the Test Network Gateway tests 🖥️
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
branches: [ "main" ]
|
branches: [ "main", "release-2.5" ]
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [ "main" ]
|
branches: [ "main", "release-2.5" ]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
gateway:
|
gateway:
|
||||||
|
|
|
||||||
4
.github/workflows/test-network-hsm.yaml
vendored
4
.github/workflows/test-network-hsm.yaml
vendored
|
|
@ -7,9 +7,9 @@ run-name: ${{ github.actor }} is running the Test Network HSM tests 🍏
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
branches: [ "main" ]
|
branches: [ "main", "release-2.5" ]
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [ "main" ]
|
branches: [ "main", "release-2.5" ]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
hsm:
|
hsm:
|
||||||
|
|
|
||||||
4
.github/workflows/test-network-k8s.yaml
vendored
4
.github/workflows/test-network-k8s.yaml
vendored
|
|
@ -7,9 +7,9 @@ run-name: ${{ github.actor }} is testing the Kubernetes Test Network 🍒
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
branches: [ "main" ]
|
branches: [ "main", "release-2.5" ]
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [ "main" ]
|
branches: [ "main", "release-2.5" ]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
ccaas-java:
|
ccaas-java:
|
||||||
|
|
|
||||||
4
.github/workflows/test-network-ledger.yaml
vendored
4
.github/workflows/test-network-ledger.yaml
vendored
|
|
@ -7,9 +7,9 @@ run-name: ${{ github.actor }} is running the Test Network Ledger tests 🥑
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
branches: [ "main" ]
|
branches: [ "main", "release-2.5" ]
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [ "main" ]
|
branches: [ "main", "release-2.5" ]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
basic:
|
basic:
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,9 @@ run-name: ${{ github.actor }} is running the Test Network Off Chain tests 🍔
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
branches: [ "main" ]
|
branches: [ "main", "release-2.5" ]
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [ "main" ]
|
branches: [ "main", "release-2.5" ]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
off-chain:
|
off-chain:
|
||||||
|
|
|
||||||
4
.github/workflows/test-network-private.yaml
vendored
4
.github/workflows/test-network-private.yaml
vendored
|
|
@ -7,9 +7,9 @@ run-name: ${{ github.actor }} is running the Test Network Private tests 🔒
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
branches: [ "main" ]
|
branches: [ "main", "release-2.5" ]
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [ "main" ]
|
branches: [ "main", "release-2.5" ]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
4
.github/workflows/test-network-sbe.yaml
vendored
4
.github/workflows/test-network-sbe.yaml
vendored
|
|
@ -7,9 +7,9 @@ run-name: ${{ github.actor }} is running the Test Network SBE tests 🎵
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
branches: [ "main" ]
|
branches: [ "main", "release-2.5" ]
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [ "main" ]
|
branches: [ "main", "release-2.5" ]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
SBE:
|
SBE:
|
||||||
|
|
|
||||||
4
.github/workflows/test-network-secured.yaml
vendored
4
.github/workflows/test-network-secured.yaml
vendored
|
|
@ -7,9 +7,9 @@ run-name: ${{ github.actor }} is running the Test Network Secured tests 🔔
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
branches: [ "main" ]
|
branches: [ "main", "release-2.5" ]
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [ "main" ]
|
branches: [ "main", "release-2.5" ]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
secured:
|
secured:
|
||||||
|
|
|
||||||
|
|
@ -2567,9 +2567,9 @@
|
||||||
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
|
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
|
||||||
},
|
},
|
||||||
"node_modules/cookiejar": {
|
"node_modules/cookiejar": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz",
|
||||||
"integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==",
|
"integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/cors": {
|
"node_modules/cors": {
|
||||||
|
|
@ -5272,13 +5272,10 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/json5": {
|
"node_modules/json5": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
|
||||||
"integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
|
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
|
||||||
"minimist": "^1.2.5"
|
|
||||||
},
|
|
||||||
"bin": {
|
"bin": {
|
||||||
"json5": "lib/cli.js"
|
"json5": "lib/cli.js"
|
||||||
},
|
},
|
||||||
|
|
@ -5547,9 +5544,9 @@
|
||||||
"integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo="
|
"integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo="
|
||||||
},
|
},
|
||||||
"node_modules/minimatch": {
|
"node_modules/minimatch": {
|
||||||
"version": "3.0.4",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"brace-expansion": "^1.1.7"
|
"brace-expansion": "^1.1.7"
|
||||||
|
|
@ -5558,12 +5555,6 @@
|
||||||
"node": "*"
|
"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": {
|
"node_modules/moment": {
|
||||||
"version": "2.29.4",
|
"version": "2.29.4",
|
||||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
|
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
|
||||||
|
|
@ -9677,9 +9668,9 @@
|
||||||
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
|
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
|
||||||
},
|
},
|
||||||
"cookiejar": {
|
"cookiejar": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz",
|
||||||
"integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==",
|
"integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"cors": {
|
"cors": {
|
||||||
|
|
@ -11718,13 +11709,10 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"json5": {
|
"json5": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
|
||||||
"integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
|
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"requires": {
|
|
||||||
"minimist": "^1.2.5"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"jsrsasign": {
|
"jsrsasign": {
|
||||||
"version": "10.5.26",
|
"version": "10.5.26",
|
||||||
|
|
@ -11935,20 +11923,14 @@
|
||||||
"integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo="
|
"integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo="
|
||||||
},
|
},
|
||||||
"minimatch": {
|
"minimatch": {
|
||||||
"version": "3.0.4",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"brace-expansion": "^1.1.7"
|
"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": {
|
"moment": {
|
||||||
"version": "2.29.4",
|
"version": "2.29.4",
|
||||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
|
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
|
||||||
|
|
|
||||||
|
|
@ -129,6 +129,10 @@ async function main(): Promise<void> {
|
||||||
|
|
||||||
// Delete AssetID2 as Org1.
|
// Delete AssetID2 as Org1.
|
||||||
await deleteAsset(contractOrg1, assetID2);
|
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 {
|
} finally {
|
||||||
gatewayOrg1.close();
|
gatewayOrg1.close();
|
||||||
clientOrg1.close();
|
clientOrg1.close();
|
||||||
|
|
@ -261,6 +265,17 @@ async function deleteAsset(contract: Contract, assetID: string): Promise<void> {
|
||||||
|
|
||||||
console.log('*** Transaction committed successfully');
|
console.log('*** Transaction committed successfully');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function purgeAsset(contract: Contract, assetID: string): Promise<void> {
|
||||||
|
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<boolean> {
|
async function readAssetPrivateDetails(contract: Contract, assetID: string, collectionName: string): Promise<boolean> {
|
||||||
console.log(`\n--> Evaluate Transaction: ReadAssetPrivateDetails from ${collectionName}, ID: ${assetID}`);
|
console.log(`\n--> Evaluate Transaction: ReadAssetPrivateDetails from ${collectionName}, ID: ${assetID}`);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
// DeleteTranferAgreement can be used by the buyer to withdraw a proposal from
|
||||||
// the asset collection and from his own collection.
|
// the asset collection and from his own collection.
|
||||||
func (s *SmartContract) DeleteTranferAgreement(ctx contractapi.TransactionContextInterface) error {
|
func (s *SmartContract) DeleteTranferAgreement(ctx contractapi.TransactionContextInterface) error {
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ module github.com/hyperledger/fabric-samples/asset-transfer-private-data/chainco
|
||||||
go 1.17
|
go 1.17
|
||||||
|
|
||||||
require (
|
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-contract-api-go v1.2.0
|
||||||
github.com/hyperledger/fabric-protos-go v0.0.0-20220613214546-bf864f01d75e
|
github.com/hyperledger/fabric-protos-go v0.0.0-20220613214546-bf864f01d75e
|
||||||
github.com/stretchr/testify v1.8.0
|
github.com/stretchr/testify v1.8.0
|
||||||
|
|
|
||||||
|
|
@ -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/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 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-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 h1:BmArPRmTjiC2brHk2FNlDoJ8bOI0ExKZhj2YqWAiv5o=
|
||||||
github.com/hyperledger/fabric-contract-api-go v1.2.0/go.mod h1:GU2NV95E5LNkFTCL3xcPgXzi8QNLXBZhx7DGnKskuqw=
|
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=
|
github.com/hyperledger/fabric-protos-go v0.0.0-20220613214546-bf864f01d75e h1:Ae2p0e+v5ekrl4KgkbCStBTSoV67Cg9fPkEWrv0f3nk=
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ version '1.0-SNAPSHOT'
|
||||||
|
|
||||||
dependencies {
|
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:+'
|
implementation 'org.json:json:+'
|
||||||
|
|
||||||
testImplementation 'org.hyperledger.fabric-chaincode-java:fabric-chaincode-shim:2.+'
|
testImplementation 'org.hyperledger.fabric-chaincode-java:fabric-chaincode-shim:2.+'
|
||||||
|
|
|
||||||
|
|
@ -488,6 +488,9 @@ public final class AssetTransfer implements ContractInterface {
|
||||||
* Deletes a asset & related details from the ledger.
|
* Deletes a asset & related details from the ledger.
|
||||||
* Input in transient map: asset_delete
|
* 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
|
* @param ctx the transaction context
|
||||||
*/
|
*/
|
||||||
@Transaction(intent = Transaction.TYPE.SUBMIT)
|
@Transaction(intent = Transaction.TYPE.SUBMIT)
|
||||||
|
|
@ -539,6 +542,53 @@ public final class AssetTransfer implements ContractInterface {
|
||||||
stub.delPrivateData(ownersCollectionName, assetID);
|
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<String, byte[]> 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
|
// 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
|
// 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) {
|
private void verifyAgreement(final Context ctx, final String assetID, final String owner, final String buyerMSP) {
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ function print() {
|
||||||
echo -e "${GREEN}${1}${NC}"
|
echo -e "${GREEN}${1}${NC}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# remove the java asset-private-data until the publishing issues have been resolved
|
||||||
dirs=("$(find . -name "*-java" -type d -not -path '*/.*')")
|
dirs=("$(find . -name "*-java" -type d -not -path '*/.*')")
|
||||||
for dir in $dirs; do
|
for dir in $dirs; do
|
||||||
print "Linting $dir"
|
print "Linting $dir"
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ public class CommercialPaperContract implements ContractInterface {
|
||||||
String newOwner, int price, String purchaseDateTime) {
|
String newOwner, int price, String purchaseDateTime) {
|
||||||
|
|
||||||
// Retrieve the current paper using key fields provided
|
// 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);
|
CommercialPaper paper = ctx.paperList.getPaper(paperKey);
|
||||||
|
|
||||||
// Validate current owner
|
// Validate current owner
|
||||||
|
|
@ -146,7 +146,7 @@ public class CommercialPaperContract implements ContractInterface {
|
||||||
public CommercialPaper redeem(CommercialPaperContext ctx, String issuer, String paperNumber, String redeemingOwner,
|
public CommercialPaper redeem(CommercialPaperContext ctx, String issuer, String paperNumber, String redeemingOwner,
|
||||||
String redeemDateTime) {
|
String redeemDateTime) {
|
||||||
|
|
||||||
String paperKey = CommercialPaper.makeKey(new String[] { paperNumber });
|
String paperKey = CommercialPaper.makeKey(new String[] { issuer, paperNumber });
|
||||||
|
|
||||||
CommercialPaper paper = ctx.paperList.getPaper(paperKey);
|
CommercialPaper paper = ctx.paperList.getPaper(paperKey);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ public class CommercialPaperContract implements ContractInterface {
|
||||||
String newOwner, int price, String purchaseDateTime) {
|
String newOwner, int price, String purchaseDateTime) {
|
||||||
|
|
||||||
// Retrieve the current paper using key fields provided
|
// 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);
|
CommercialPaper paper = ctx.paperList.getPaper(paperKey);
|
||||||
|
|
||||||
// Validate current owner
|
// Validate current owner
|
||||||
|
|
@ -146,7 +146,7 @@ public class CommercialPaperContract implements ContractInterface {
|
||||||
public CommercialPaper redeem(CommercialPaperContext ctx, String issuer, String paperNumber, String redeemingOwner,
|
public CommercialPaper redeem(CommercialPaperContext ctx, String issuer, String paperNumber, String redeemingOwner,
|
||||||
String redeemDateTime) {
|
String redeemDateTime) {
|
||||||
|
|
||||||
String paperKey = CommercialPaper.makeKey(new String[] { paperNumber });
|
String paperKey = CommercialPaper.makeKey(new String[] {issuer, paperNumber });
|
||||||
|
|
||||||
CommercialPaper paper = ctx.paperList.getPaper(paperKey);
|
CommercialPaper paper = ctx.paperList.getPaper(paperKey);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -269,13 +269,11 @@ Capabilities:
|
||||||
# used with prior release orderers.
|
# used with prior release orderers.
|
||||||
# Set the value of the capability to true to require it.
|
# Set the value of the capability to true to require it.
|
||||||
Application: &ApplicationCapabilities
|
Application: &ApplicationCapabilities
|
||||||
# V2_0 application capability ensures that peers behave according
|
# V2.5 for Application enables the new non-backwards compatible
|
||||||
# to v2.0 application capabilities. Peers from
|
# features of fabric v2.5, namely the ability to purge private data.
|
||||||
# prior releases would behave in an incompatible way, and are therefore
|
# Prior to enabling V2.5 application capabilities, ensure that all
|
||||||
# not able to participate in channels at v2.0 application capability.
|
# peers on a channel are at v2.5.0 or later.
|
||||||
# Prior to enabling V2.0 application capabilities, ensure that all
|
V2_5: true
|
||||||
# peers on channel are at v2.0.0 or later.
|
|
||||||
V2_0: true
|
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
#
|
#
|
||||||
|
|
|
||||||
|
|
@ -163,13 +163,11 @@ Capabilities:
|
||||||
# used with prior release orderers.
|
# used with prior release orderers.
|
||||||
# Set the value of the capability to true to require it.
|
# Set the value of the capability to true to require it.
|
||||||
Application: &ApplicationCapabilities
|
Application: &ApplicationCapabilities
|
||||||
# V2_0 application capability ensures that peers behave according
|
# V2.5 for Application enables the new non-backwards compatible
|
||||||
# to v2.0 application capabilities. Peers from
|
# features of fabric v2.5, namely the ability to purge private data.
|
||||||
# prior releases would behave in an incompatible way, and are therefore
|
# Prior to enabling V2.5 application capabilities, ensure that all
|
||||||
# not able to participate in channels at v2.0 application capability.
|
# peers on a channel are at v2.5.0 or later.
|
||||||
# Prior to enabling V2.0 application capabilities, ensure that all
|
V2_5: true
|
||||||
# peers on channel are at v2.0.0 or later.
|
|
||||||
V2_0: true
|
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
#
|
#
|
||||||
|
|
|
||||||
|
|
@ -130,6 +130,7 @@ Capabilities:
|
||||||
# orderers and peers on a channel are at v2.0.0 or later.
|
# orderers and peers on a channel are at v2.0.0 or later.
|
||||||
V2_0: true
|
V2_0: true
|
||||||
|
|
||||||
|
|
||||||
# Orderer capabilities apply only to the orderers, and may be safely
|
# Orderer capabilities apply only to the orderers, and may be safely
|
||||||
# used with prior release peers.
|
# used with prior release peers.
|
||||||
# Set the value of the capability to true to require it.
|
# Set the value of the capability to true to require it.
|
||||||
|
|
@ -146,13 +147,11 @@ Capabilities:
|
||||||
# used with prior release orderers.
|
# used with prior release orderers.
|
||||||
# Set the value of the capability to true to require it.
|
# Set the value of the capability to true to require it.
|
||||||
Application: &ApplicationCapabilities
|
Application: &ApplicationCapabilities
|
||||||
# V2_0 application capability ensures that peers behave according
|
# V2.5 for Application enables the new non-backwards compatible
|
||||||
# to v2.0 application capabilities. Peers from
|
# features of fabric v2.5, namely the ability to purge private data.
|
||||||
# prior releases would behave in an incompatible way, and are therefore
|
# Prior to enabling V2.5 application capabilities, ensure that all
|
||||||
# not able to participate in channels at v2.0 application capability.
|
# peers on a channel are at v2.5.0 or later.
|
||||||
# Prior to enabling V2.0 application capabilities, ensure that all
|
V2_5: true
|
||||||
# peers on channel are at v2.0.0 or later.
|
|
||||||
V2_0: true
|
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
#
|
#
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue