/cordentity

This project combines Hyperledger's Indy ledger for decentralized identity with the Corda platform

Primary LanguageKotlinApache License 2.0Apache-2.0

Cordentity

logo

The basis project combining Hyperledger Indy Ledger with Corda Platform.

It is often required to share parts of private data and prove assertions based on such data. For example, a person can prove that her age is above the legal age without disclosing how old she is. Indy makes it possible to prove a statement is true while preserving confidentiality. Cordentity project integrates Indy capabilities into a Corda-based environment.

Usage

For full information about the processes and APIs see cordapp/README

Business Case "Legal Age Verification"

In many countries a person must be above the legal age to purchase alcohol drinks. Using services and flows provided by Indy-Codrapp it is possible to create a system that proves that the age of a customer is above the legal limit without exposing their actual age or other personal details.

Lets assume that those 3 nodes are connected as a part of a Corda network:

  • ministry - the Ministry of Home Affairs service

  • store - a grocery store payment center

  • alice - Alice's mobile device

    val ministry: StartedNode<> val alice: StartedNode<> val store: StartedNode<*>

Each Corda node has a X500 name:

val ministryX500 = ministry.info.singleIdentity().name
val aliceX500 = alice.info.singleIdentity().name

And each Indy node has a DID, a.k.a Decentralized ID, which can be obtained using GetDidFlow:

val ministryDID = store.services.startFlow(
        GetDidFlow.Initiator(ministryX500)).resultFuture.get()

To allow customers and shops to communicate, Ministry issues a shopping scheme using CreateSchemaFlow:

val schemaId = ministry.services.startFlow(
        CreateSchemaFlow.Authority(
                "shopping scheme",
                "1.0",
                listOf("NAME", "BORN"))).resultFuture.get()

Ministry creates a credential definition for the shopping scheme using CreateClaimDefFlow:

val credDefId = ministry.services.startFlow(
        CreateClaimDefFlow.Authority(schemaId)).resultFuture.get()

Ministry verifies Alice's legal status and issues her a shopping credential using IssueClaimFlow:

val credentialProposal = """
    {
    "NAME":{"raw":"Alice", "encoded":"119191919"},
    "BORN":{"raw":"2000",  "encoded":"2000"}
    }
    """

ministry.services.startFlow(
        IssueClaimFlow.Issuer(
                UUID.randomUUID().toString(),
                credDefId,
                credentialProposal,
                aliceX500)).resultFuture.get()

When Alice comes to grocery store, the store asks Alice to verify that she is legally allowed to buy drinks using VerifyClaimFlow:

// Alice.BORN >= currentYear - 18
val eighteenYearsAgo = LocalDateTime.now().minusYears(18).year
val legalAgePredicate = VerifyClaimFlow.ProofPredicate(schemaId, credDefId, ministryDID, "BORN", eighteenYearsAgo)

val verified = store.services.startFlow(
        VerifyClaimFlow.Verifier(
                UUID.randomUUID().toString(),
                emptyList(),
                listOf(legalAgePredicate),
                aliceX500)).resultFuture.get()

If the verification succeeds, the store can be sure that Alice's age is above 18.

println("You can buy drinks: $verified")

You can run the whole example as a test in ReadmeExampleTest file.

Business Cases "Personalized Health Care Supply Chain"

Another use case for Indy CorDapp is a Personalized Health Care Supply Chain project (in early development).

This system allows sharing private patients' information while providing extensive control over the usage of that information.

The connected parties in this case would usually be Insurance Providers, Patients, Hospitals, Personal Medicine Manufacturers and Government Agencies. The sensitive information may include patient’s age, nationality, results of medical analyses or guarantee of insurance coverage.

Thanks to our Indy CorDapp solution, patient’s personal data is disclosed only to the eligible parties and only to the extent required in each particular business case.

Installation

repositories {
    maven { url 'https://jitpack.io' }
}

dependencies {
    cordapp "com.github.Luxoft.cordentity:cordapp:0.4.11"
    cordapp "com.github.Luxoft.cordentity:cordapp-contracts-states:0.4.11"
}

On all machines that are going to run IndyService install the libindy package:

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 68DB5E88
sudo add-apt-repository "deb https://repo.sovrin.org/sdk/deb xenial stable"
sudo apt-get update
sudo apt-get install -y libindy=1.6.4

Please follow to the official indy-sdk repo for installation instructions for Windows, iOS, Android and MacOS.

Development

Subprojects

External dependancies

Version cordapp 0.4.11 requires installation of indy-sdk version 1.6.4.

Build

To run the tests you need to install the libindy package:

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 68DB5E88
sudo add-apt-repository "deb https://repo.sovrin.org/sdk/deb xenial stable"
sudo apt-get update
sudo apt-get install -y libindy=1.6.4

Make sure that Docker is installed:

sudo apt update
sudo apt install docker

After that use the standard Gradle build procedure:

gradle clean build

Troubleshooting

Before every test run it is recommended to clean local pool and wallets data, which by default are stored in ~/.indy_client/:

gradle cleanDefaultPool

Also re-creating the indypool docker container is needed to get a clean system:

gradle dockerCleanRun

To manually start the indy-pool container on ports 9701-9708:

docker pull teamblockchain/indy-pool:1.6.4
docker create -p 9701-9708:9701-9708 --name indypool --rm teamblockchain/indy-pool:1.6.4
docker start indypool

Contributors