Note: This is a deprecated of the formal Hyperledger Labs repository, where active development is ongoing. Issue tracking is handled in Issues
The Cordentity project integrates Hyperledger Indy capabilities into the Corda Platform.
Hyperledger Indy is a distributed ledger, purpose-built for decentralized identity.
Corda is a blockchain and smart contract platform. Corda allows parties to transact directly, with value. Smart contracts allow Corda to do this using complex agreements and any asset type. This capability has broad applications across industries including finance, supply chain and healthcare.
While Corda is best suited for developing decentralized applications for managing complex inter-organizational workflows, Indy is the leading open-source platform for self sovereign identity. This integration enables the development of decentralized applications on R3's best in class blockchain for business while utilizing the self-sovereign identity capabilities of Indy.
In the identity world, we are often required to prove identity assertions without necessarily wanting to reveal the underlying data. For example, an individual may need to prove that they are of a certain age without wanting to disclose their actual date of birth. Hyperledger Indy uses zero knowledge proofs to enable this functionality, allowing someone prove a statement is true while preserving confidentiality.
For full information about the processes and APIs see cordapp/README
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:
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 CreateCredentialDefinitionFlow:
val credentialDefinitionId = ministry.services.startFlow(
CreateCredentialDefinitionFlow.Authority(schemaId)).resultFuture.get()
Ministry verifies Alice's legal status and issues her a shopping credential using IssueCredentialFlow:
val credentialProposal = """
{
"NAME":{"raw":"Alice", "encoded":"119191919"},
"BORN":{"raw":"2000", "encoded":"2000"}
}
"""
ministry.services.startFlow(
IssueCredentialFlow.Issuer(
UUID.randomUUID().toString(),
credentialDefinitionId,
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 VerifyCredentialFlow:
// Alice.BORN >= currentYear - 18
val eighteenYearsAgo = LocalDateTime.now().minusYears(18).year
val legalAgePredicate = VerifyCredentialFlow.ProofPredicate(schemaId, credentialDefinitionId, ministryDID, "BORN", eighteenYearsAgo)
val verified = store.services.startFlow(
VerifyCredentialFlow.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.
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.
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.
Version cordapp 0.4.11 requires installation of indy-sdk version 1.6.4.
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
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