From ac1831c61233c80bbdb28aa335207df66b616265 Mon Sep 17 00:00:00 2001 From: "Mark S. Lewis" Date: Fri, 5 Apr 2024 12:07:54 +0100 Subject: [PATCH] Update asset-transfer-sbe/chaincode-java Signed-off-by: Mark S. Lewis --- .../chaincode-java/build.gradle | 14 +--- .../hyperledger/fabric/samples/sbe/Asset.java | 5 +- .../fabric/samples/sbe/AssetContract.java | 78 +++++++++++-------- 3 files changed, 50 insertions(+), 47 deletions(-) diff --git a/asset-transfer-sbe/chaincode-java/build.gradle b/asset-transfer-sbe/chaincode-java/build.gradle index 1f1f5b21..72510d84 100644 --- a/asset-transfer-sbe/chaincode-java/build.gradle +++ b/asset-transfer-sbe/chaincode-java/build.gradle @@ -13,17 +13,9 @@ group 'org.hyperledger.fabric.samples' version '1.0-SNAPSHOT' dependencies { - implementation 'org.hyperledger.fabric-chaincode-java:fabric-chaincode-shim:2.5.+' - implementation 'org.json:json:+' - implementation 'com.google.protobuf:protobuf-java:3.+' - 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.5.+' - testImplementation 'org.junit.jupiter:junit-jupiter:5.4.2' - testImplementation 'org.assertj:assertj-core:3.11.1' - testImplementation 'org.mockito:mockito-core:2.+' + implementation 'org.hyperledger.fabric:fabric-protos:0.3.3' + implementation 'com.owlike:genson:1.6' } repositories { @@ -79,8 +71,6 @@ test { } } -mainClassName = 'org.hyperledger.fabric.contract.ContractRouter' - shadowJar { archiveBaseName = 'chaincode' archiveVersion = '' diff --git a/asset-transfer-sbe/chaincode-java/src/main/java/org/hyperledger/fabric/samples/sbe/Asset.java b/asset-transfer-sbe/chaincode-java/src/main/java/org/hyperledger/fabric/samples/sbe/Asset.java index b49d6920..ca14959d 100644 --- a/asset-transfer-sbe/chaincode-java/src/main/java/org/hyperledger/fabric/samples/sbe/Asset.java +++ b/asset-transfer-sbe/chaincode-java/src/main/java/org/hyperledger/fabric/samples/sbe/Asset.java @@ -4,12 +4,11 @@ package org.hyperledger.fabric.samples.sbe; -import java.util.Objects; - +import com.owlike.genson.annotation.JsonProperty; import org.hyperledger.fabric.contract.annotation.DataType; import org.hyperledger.fabric.contract.annotation.Property; -import com.owlike.genson.annotation.JsonProperty; +import java.util.Objects; @DataType() public final class Asset { diff --git a/asset-transfer-sbe/chaincode-java/src/main/java/org/hyperledger/fabric/samples/sbe/AssetContract.java b/asset-transfer-sbe/chaincode-java/src/main/java/org/hyperledger/fabric/samples/sbe/AssetContract.java index 9843ee3b..62b286b0 100644 --- a/asset-transfer-sbe/chaincode-java/src/main/java/org/hyperledger/fabric/samples/sbe/AssetContract.java +++ b/asset-transfer-sbe/chaincode-java/src/main/java/org/hyperledger/fabric/samples/sbe/AssetContract.java @@ -4,6 +4,7 @@ package org.hyperledger.fabric.samples.sbe; +import com.owlike.genson.Genson; import org.hyperledger.fabric.contract.Context; import org.hyperledger.fabric.contract.ContractInterface; import org.hyperledger.fabric.contract.annotation.Contract; @@ -11,19 +12,19 @@ import org.hyperledger.fabric.contract.annotation.Default; import org.hyperledger.fabric.contract.annotation.Info; import org.hyperledger.fabric.contract.annotation.License; import org.hyperledger.fabric.contract.annotation.Transaction; -import org.hyperledger.fabric.protos.common.MspPrincipal; -import org.hyperledger.fabric.protos.common.Policies; +import org.hyperledger.fabric.protos.common.MSPPrincipal; +import org.hyperledger.fabric.protos.common.MSPRole; +import org.hyperledger.fabric.protos.common.SignaturePolicy; +import org.hyperledger.fabric.protos.common.SignaturePolicyEnvelope; import org.hyperledger.fabric.shim.ChaincodeException; import org.hyperledger.fabric.shim.ChaincodeStub; import org.hyperledger.fabric.shim.ext.sbe.StateBasedEndorsement; import org.hyperledger.fabric.shim.ext.sbe.impl.StateBasedEndorsementFactory; -import com.owlike.genson.Genson; - -import java.util.ArrayList; -import java.util.Arrays; import java.util.Comparator; import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; @Contract( name = "sbe", @@ -36,7 +37,6 @@ import java.util.List; url = "http://www.apache.org/licenses/LICENSE-2.0.html"))) @Default public final class AssetContract implements ContractInterface { - private final Genson genson = new Genson(); private enum AssetTransferErrors { @@ -71,7 +71,7 @@ public final class AssetContract implements ContractInterface { stub.putStringState(assetId, assetJSON); // Set the endorsement policy of the assetId Key, such that current owner Org is required to endorse future updates - setStateBasedEndorsement(ctx, assetId, new String[]{ownerOrg}); + setStateBasedEndorsement(ctx, assetId, List.of(ownerOrg)); // Optionally, set the endorsement policy of the assetId Key, such that any 1 Org (N) out of the specified Orgs can endorse future updates // setStateBasedEndorsementNOutOf(ctx, assetId, 1, new String[]{"Org1MSP", "Org2MSP"}); @@ -165,10 +165,10 @@ public final class AssetContract implements ContractInterface { stub.putStringState(assetId, updatedAssetJSON); // Re-Set the endorsement policy of the assetId Key, such that a new owner Org Peer is required to endorse future updates - setStateBasedEndorsement(ctx, assetId, new String[]{newOwnerOrg}); + setStateBasedEndorsement(ctx, assetId, List.of(newOwnerOrg)); // Optionally, set the endorsement policy of the assetId Key, such that any 1 Org (N) out of the specified Orgs can endorse future updates - // setStateBasedEndorsementNOutOf(ctx, assetId, 1, new String[]{"Org1MSP", "Org2MSP"}); + // setStateBasedEndorsementNOutOf(ctx, assetId, 1, List.of("Org1MSP", "Org2MSP")); return asset; } @@ -205,9 +205,9 @@ public final class AssetContract implements ContractInterface { * @param assetId the id of the asset * @param ownerOrgs the list of Owner Org MSPID's */ - private static void setStateBasedEndorsement(final Context ctx, final String assetId, final String[] ownerOrgs) { + private static void setStateBasedEndorsement(final Context ctx, final String assetId, final List ownerOrgs) { StateBasedEndorsement stateBasedEndorsement = StateBasedEndorsementFactory.getInstance().newStateBasedEndorsement(null); - stateBasedEndorsement.addOrgs(StateBasedEndorsement.RoleType.RoleTypeMember, ownerOrgs); + stateBasedEndorsement.addOrgs(StateBasedEndorsement.RoleType.RoleTypeMember, ownerOrgs.toArray(new String[0])); ctx.getStub().setStateValidationParameter(assetId, stateBasedEndorsement.policy()); } @@ -220,36 +220,50 @@ public final class AssetContract implements ContractInterface { * @param nOrgs the number of N Orgs to endorse out of the list of Orgs provided * @param ownerOrgs the list of Owner Org MSPID's */ - private static void setStateBasedEndorsementNOutOf(final Context ctx, final String assetId, final int nOrgs, final String[] ownerOrgs) { - ctx.getStub().setStateValidationParameter(assetId, policy(nOrgs, Arrays.asList(ownerOrgs))); + private static void setStateBasedEndorsementNOutOf(final Context ctx, final String assetId, final int nOrgs, final List ownerOrgs) { + ctx.getStub().setStateValidationParameter(assetId, policy(nOrgs, ownerOrgs)); } /** * Create a policy that requires a given number (N) of Org principals signatures out of the provided list of Orgs * * @param nOrgs the number of Org principals signatures required to endorse (out of the provided list of Orgs) - * @param mspids the list of Owner Org MSPID's + * @param mspIds the list of Owner Org MSPID's */ - private static byte[] policy(final int nOrgs, final List mspids) { - mspids.sort(Comparator.naturalOrder()); - final List principals = new ArrayList<>(); - final List signPolicy = new ArrayList<>(); - for (int i = 0; i < mspids.size(); i++) { - final String mspid = mspids.get(i); - principals.add(MspPrincipal.MSPPrincipal.newBuilder().setPrincipalClassification(MspPrincipal.MSPPrincipal.Classification.ROLE) - .setPrincipal(MspPrincipal.MSPRole.newBuilder().setMspIdentifier(mspid).setRole(MspPrincipal.MSPRole.MSPRoleType.MEMBER).build().toByteString()).build()); - signPolicy.add(signedBy(i)); - } - // Create the policy such that it requires any N signature's from all of the principals provided - return Policies.SignaturePolicyEnvelope.newBuilder().setVersion(0).setRule(nOutOf(nOrgs, signPolicy)) - .addAllIdentities(principals).build().toByteArray(); + private static byte[] policy(final int nOrgs, final List mspIds) { + mspIds.sort(Comparator.naturalOrder()); + + var principals = mspIds.stream() + .map(mspId -> MSPRole.newBuilder() + .setMspIdentifier(mspId) + .setRole(MSPRole.MSPRoleType.MEMBER) + .build()) + .map(role -> MSPPrincipal.newBuilder() + .setPrincipalClassification(MSPPrincipal.Classification.ROLE) + .setPrincipal(role.toByteString()) + .build()) + .collect(Collectors.toList()); + + var signPolicy = IntStream.range(0, mspIds.size()) + .mapToObj(AssetContract::signedBy) + .collect(Collectors.toList()); + + // Create the policy such that it requires any N signature's from all the principals provided + return SignaturePolicyEnvelope.newBuilder() + .setVersion(0) + .setRule(nOutOf(nOrgs, signPolicy)) + .addAllIdentities(principals) + .build() + .toByteArray(); } - private static Policies.SignaturePolicy signedBy(final int index) { - return Policies.SignaturePolicy.newBuilder().setSignedBy(index).build(); + private static SignaturePolicy signedBy(final int index) { + return SignaturePolicy.newBuilder().setSignedBy(index).build(); } - private static Policies.SignaturePolicy nOutOf(final int n, final List policies) { - return Policies.SignaturePolicy.newBuilder().setNOutOf(Policies.SignaturePolicy.NOutOf.newBuilder().setN(n).addAllRules(policies).build()).build(); + private static SignaturePolicy nOutOf(final int n, final List policies) { + return SignaturePolicy.newBuilder().setNOutOf( + SignaturePolicy.NOutOf.newBuilder().setN(n).addAllRules(policies).build() + ).build(); } }