Using private smart contracts

The Transparent Supply private smart contracts feature enables clients to execute their own chaincode using platform solution data.

Overview

Using private smart contracts in your platform solution ecosystem requires an understanding of the process and the data, as described in this document:

  • Process: tasks performed by the Convener organization to enable private smart contracts for Member organizations
  • Data: the required input data types, format and entitlement Attention: To use private smart contracts, the environment psc_subscriptions feature flag must be set to true.

Create an account on cloud.ibm.com

An IBM Cloud account is required to provision platform solution resources on IBM Cloud. If you do not already have one, create an IBM Cloud account.

Create an IBM Kubernetes service and IBM Blockchain Platform (IBP) instance

If you are creating a new IBM Blockchain Platform solution instance, watch the video instruction.

Persistent storage considerations

Using private smart contracts on IBM Cloud involves persistent storage considerations.

Build blockchain network

Use the following sequence to build your IBM Blockchain Platform instance:

  1. Launch IBM Blockchain Platform (IBP) console:
    • Go to the resource list.
    • Under Services, locate and click on the created IBP.
    • Click Manage in the left panel then click Launch the IBM Blockchain Platform.
  2. Watch the video on how to deploy the Peer node and Certificate Authority (CA) node. Take note of how to register the admin, as described here, because you will use the same steps to create a new user for private smart contracts. If you are prompted for the Hyperledger Fabric version, select version 1.4.x.
  3. Watch the video on how to deploy the Orderer node, which is described here.

Create a channel

Use the following sequence to create a channel on your IBM Blockchain Platform instance:

  1. Watch the video on how to create and join peer(s) to a channel.
  2. Follow the instructions to create a channel.

Install and instantiate chaincode

Installing and instantiating your private smart contract chaincode are two discrete steps. Use the following instructions to install and instantiate your chaincode (private smart contract):

  1. Follow the Deploy a smart contract instructions to install your chaincode. Keep the browser page open for the next step.
  2. Use the same Deploy a smart contract instructions to instantiate your chaincode.

Register a user or identity

Using private smart contracts presumes that a registered user or identity has submitted data to the platform blockchain on behalf of the client. The private smart contract feature will do the enrollment during the subscription initiation. Complete the following sequence to register a user or identity:

  1. Launch the IBP Console
  2. Associate CA admin identity
  3. Repeat the earlier step on registering an Organization admin, but for a new user, and set the user type as client; or follow the instructions to register an identity. ATTENTION!: You must record the assigned enrollment id gand secret, which are required in a later step to initiate a subscription.

Retrieve connection profile

The Connection profile for the IBP solution must contain profiles for the Peer, Orderer and Certificate Authority (CA) nodes, and channel information. These profiles can be retrieved from the IBP console, and along with the channel information, combined into a single JSON file:

  1. Launch the IBP console.
  2. Download the Peer, Orderer and Certificate Authority (CA) node profiles.
  3. Combine the three downloaded profiles into a single file.
  4. Add the channel information into the file. The following example Connection profile for mychannel is installed on peer0.org1.example.com, peer1.org1.example.com and orderer.example.com:
"channels": {
    "mychannel": {
        "x-status": "membership_valid",
        "orderers": [
            "orderer.example.com"
        ],
        "peers": {
            "peer0.org1.example.com": {
                "x-chaincode": {
                }
            },
            "peer1.org1.example.com": {
                "x-chaincode": {
                }
            }
        },
        "chaincodes": [
        ],
        "x-members": [
            "Org1"
        ]
    }
}

The following code is an example JSON connection profile:

  {
      "name": "first-network-org1",
      "version": "1.0.0",
      "client": {
          "organization": "Org1",
          "connection": {
              "timeout": {
                  "peer": {
                      "endorser": "300"
                  }
              }
          }
      },
      "channels": {
          "mychannel": {
              "x-status": "membership_valid",
              "orderers": [
                  "orderer.example.com"
              ],
              "peers": {
                  "peer0.org1.example.com": {
                      "x-chaincode": {
                      }
                  },
                  "peer1.org1.example.com": {
                      "x-chaincode": {
                      }
                  }
              },
              "chaincodes": [
                  "asc:v1"
              ],
              "x-members": [
                  "Org1"
              ]
          }
      },
      "organizations": {
          "Org1": {
              "mspid": "Org1MSP",
              "peers": [
                  "peer0.org1.example.com",
                  "peer1.org1.example.com"
              ],
              "certificateAuthorities": [
                  "ca.org1.example.com"
              ]
          }
      },
      "peers": {
          "peer0.org1.example.com": {
              "url": "grpcs://localhost:7051",
              "tlsCACerts": {
                  "pem": "--BEGIN CERTIFICATE--\nMIICVjCCAf2gAwIBAgIQOKgR+EFsAeA34AKRz5jhRTAKBggqhkjOPQQDAjB2MQsw\nCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy\nYW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEfMB0GA1UEAxMWdGxz\nY2Eub3JnMS5leGFtcGxlLmNvbTAeFw0yMDA5MDExMTE5MDBaFw0zMDA4MzAxMTE5\nMDBaMHYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQH\nEw1TYW4gRnJhbmNpc2NvMRkwFwYDVQQKExBvcmcxLmV4YW1wbGUuY29tMR8wHQYD\nVQQDExZ0bHNjYS5vcmcxLmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0D\nAQcDQgAERHvCR9zSIDo3IwQm8AqJ2ob5660pgvg2qDvuf4Z3PjViz9Br0oPo0VjP\nXNyKMV0Y91KbNUBsl3QVLS5Q8s+cC6NtMGswDgYDVR0PAQH/BAQDAgGmMB0GA1Ud\nJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1Ud\nDgQiBCApP/spJTh8RtpJP9b3zB4jMXbQGUQAwDqQ7YE2gx6X5TAKBggqhkjOPQQD\nAgNHADBEAiA8QDPeWZHbEongBKclru5+J6fZw0/S7eMZf+J3fp87DAIgXC9MB8rg\nKRyNkgLXTi5O9oeUklpB/EjcS8HEu/yq+c4=\n--END CERTIFICATE--\n"
              },
              "grpcOptions": {
                  "ssl-target-name-override": "peer0.org1.example.com",
                  "hostnameOverride": "peer0.org1.example.com"
              }
          },
          "peer1.org1.example.com": {
              "url": "grpcs://localhost:8051",
              "tlsCACerts": {
                  "pem": "--BEGIN CERTIFICATE--\nMIICVjCCAf2gAwIBAgIQOKgR+EFsAeA34AKRz5jhRTAKBggqhkjOPQQDAjB2MQsw\nCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy\nYW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEfMB0GA1UEAxMWdGxz\nY2Eub3JnMS5leGFtcGxlLmNvbTAeFw0yMDA5MDExMTE5MDBaFw0zMDA4MzAxMTE5\nMDBaMHYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQH\nEw1TYW4gRnJhbmNpc2NvMRkwFwYDVQQKExBvcmcxLmV4YW1wbGUuY29tMR8wHQYD\nVQQDExZ0bHNjYS5vcmcxLmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0D\nAQcDQgAERHvCR9zSIDo3IwQm8AqJ2ob5660pgvg2qDvuf4Z3PjViz9Br0oPo0VjP\nXNyKMV0Y91KbNUBsl3QVLS5Q8s+cC6NtMGswDgYDVR0PAQH/BAQDAgGmMB0GA1Ud\nJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1Ud\nDgQiBCApP/spJTh8RtpJP9b3zB4jMXbQGUQAwDqQ7YE2gx6X5TAKBggqhkjOPQQD\nAgNHADBEAiA8QDPeWZHbEongBKclru5+J6fZw0/S7eMZf+J3fp87DAIgXC9MB8rg\nKRyNkgLXTi5O9oeUklpB/EjcS8HEu/yq+c4=\n--END CERTIFICATE--\n"
              },
              "grpcOptions": {
                  "ssl-target-name-override": "peer1.org1.example.com",
                  "hostnameOverride": "peer1.org1.example.com"
              }
          }
      },
      "certificateAuthorities": {
          "ca.org1.example.com": {
              "url": "https://localhost:7054",
              "caName": "ca-org1",
              "tlsCACerts": {
                  "pem": "--BEGIN CERTIFICATE--\nMIICUjCCAfigAwIBAgIRALemeKmTXA/Ij/DwYKuTNWQwCgYIKoZIzj0EAwIwczEL\nMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG\ncmFuY2lzY28xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xHDAaBgNVBAMTE2Nh\nLm9yZzEuZXhhbXBsZS5jb20wHhcNMjAwOTAxMTExOTAwWhcNMzAwODMwMTExOTAw\nWjBzMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMN\nU2FuIEZyYW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEcMBoGA1UE\nAxMTY2Eub3JnMS5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA\nBLCgVLOmsvmR4083nbhv0MRwFqmT7hFFhC56I3mi7KN088oQ+qS6gD5EXbsorF2v\nuJVuxLXxHC2jLmrjbc/SouOjbTBrMA4GA1UdDwEB/wQEAwIBpjAdBgNVHSUEFjAU\nBggrBgEFBQcDAgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUwAwEB/zApBgNVHQ4EIgQg\nD253x5EulvJj16BCMy4cpUz5F4jNQGlOMCLwktuWgIEwCgYIKoZIzj0EAwIDSAAw\nRQIhAL3kNhSaue057Tosud/8PR9EuU38wdMXJ8Szgp00NoeVAiByk51aHwNsDyDD\nr2EXLUirzd7BNB8TTJ3i2JIaIqxloA==\n--END CERTIFICATE--\n"
              },
              "httpOptions": {
                  "verify": false
              }
          }
      }
  }

Initiate Private smart contract subscription

The Convener organization must now initiate its private smart contract subscription:

  1. Authenticate to the solution with your IBMid— if necessary, contact your devOps representative for your solution authentication link. For IBM-managed solutions, use the IBM Blockchain Solution Manager login page.
  2. Log in to your organization and copy your token.
  3. Go to the private smart contracts Swagger page https:////ift/api/provenance/api-docs/ (if necessary, hostname can be provided by from your devOps representative).
  4. Click on the Authorize button and enter the token prefix with Bearer - for example, Bearer XXXXXX where XXXXXX is the token; then click on the pop-up window Authorize button
  5. Click on the /subscription/initiate/private_smart_contract endpoint and enter the following information:
    • name: human readable text for easy reference
    • channel: the channel where the intended chaincode is deployed
    • network: can be left blank
    • organization_ids: list of all the participant organization IDs
    • chaincode – name: the intended chaincode name
    • chaincode – function: the shim invoke function to be invoked in the intended chaincode
    • enrollment_id: the registered user ID created in the previous step
    • enrollment_secret: the registered user secret created in the previous step
    • connection_profile: the connection profile file name created in previous step
  6. Click on Execute.
  • Note the new subscription id returned, which must be provided to each participant organization that will join this newly initiated subscription. Or click on /subscription/private_smart_contract to list all the initiated subscriptions.

Invite participant organizations to join

Inform all participating organizations to log in to the Swagger page https:////ift/api/provenance/api-docs/ to join the subscription using the new subscription ID.

Participant organizations join the subscription

Each participant organization joining the private smart contract subscription must complete the following sequence:

  1. Get a token (contact your devOps contact for the link to BDS Login page to obtain a token)
  2. Connect to the Swagger web page https:////ift/api/provenance/api-docs/ - getting the hostname from their devOps representative.
  3. Click on the Authorize button and enter the BSM token prefix with Bearer - for example Bearer XXXXXX - where XXXXXX is the token; then click the pop-up Authorize button.
  4. Click the /subscription/join/private_smart_contract/ endpoint.
  5. Enter the subscription id received from the Initiator organization.
  6. Click on Execute.

Validate that all participants orgs have joined

Data will not be sent to the private smart contract chaincode until all specified participant organizations have joined the subscription. Once all organizations have joined, the subscription will be in Active state. To check the subscription state:

  1. The Initiator organization gets a token (contact devOps for the link to BDS Login page to obtain a token)
  2. Connect to the Swagger page https:////ift/api/provenance/api-docs/ - get hostname from your devOps representative.
  3. Click on the Authorize button, enter the BSM token prefix with Bearer - for example Bearer XXXXXX - where XXXXXX is the token; then click on the pop-up window Authorize button
  4. Click on the /subscription/private_smart_contract/ endpoint.
  5. Active subscriptions have had all specified participating organizations join the subscription.

Submit data

Use the Connector API to upload data to the solution.

Data

Note the following important format and access information, in the sections below, about data being submitted to private smart contract chaincode.

Data format

Private smart contract chaincode developers must account for the following input data formats:

  1. The format sent is a JSON string.
  2. See JSON data type and syntax for details on JSON that is submitted to chaincode.
  3. See the following Purchase Order transaction document example

Data entitlement and access control

The following conditions control whether specific asset data is submitted to a subscription private smart contract (chaincode). There are two stages of filtering which are performed in the following order:

  1. First stage filtering - only considers assets owned by a subscription participant organization
  2. Second stage filtering - only considers assets that pass the data entitlement check. First stage filtering can be skipped by setting the feature flag psc-require-owner-subscription to false, which means all assets will be considered for second stage filtering data entitlement check, for all subscriptions. For information on data sharing and access in Transparent Supply, refer to Data entitlement and access control �