Skip to content

Commit

Permalink
Attester section
Browse files Browse the repository at this point in the history
Signed-off-by: Chris Chinchilla <[email protected]>
  • Loading branch information
ChrisChinchilla committed Nov 11, 2023
1 parent 9f73df4 commit 024a694
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 52 deletions.
27 changes: 16 additions & 11 deletions docs/develop/03_workshop/04_attester/01_account.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,23 @@ For example, `waste frown beach save hidden bar inmate oil mind member junk famo

You use a mnemonic to generate signing keypairs.
What's great about a mnemonic is that it's **human-readable**, and a person could memorize it to later re-generate their keypairs and address.
A mnemonic is critical for security, so it;s crucial to keep it safe!

:::

## Create the Account

To generate an account, use the `addFromMnemonic()` function on the [`KiltKeyringPair`](https://kiltprotocol.github.io/sdk-js/interfaces/types_src.KiltKeyringPair.html) interface of the SDK. The function uses the underlying polkadot `mnemonicGenerate()` function to generate a 12-word mnemonic.
To generate an account, use the `addFromMnemonic()` function on the [`KiltKeyringPair`](https://kiltprotocol.github.io/sdk-js/interfaces/types_src.KiltKeyringPair.html) interface of the SDK.
The function uses the underlying polkadot `mnemonicGenerate()` function to generate a 12-word mnemonic.

:::info polkadot.js

The KILT SDK is built on top of the [polkadot.js](https://polkadot.js.org/) library, so this workshop uses several functions from the library.

The library provides tools to interact with the KILT blockchain and other substrate-based blockchains.

In addition, the polkadot.js library offers cryptographic primitives and a serialization framework to encode/decode data sent to and received from the blockchain. Read the [API documentation](https://polkadot.js.org/docs/) to learn more about the functions available.
In addition, the polkadot.js library offers cryptographic primitives and a serialization framework to encode/decode data sent to and received from the blockchain.
Read the [API documentation](https://polkadot.js.org/docs/) to learn more about the functions available.

:::

Expand All @@ -55,20 +58,22 @@ Add the following code to the `generateAccount` file.
{GenerateAccount}
</TsJsBlock>

The `generateAccount` method generates the account address and mnemonic key using the value structure definition to return the following:
The `generateAccount` method returns an object with the following two properties:

- A key `account` with the type `Kilt.KiltKeyringPair`.
- A key `account` with the type `Kilt.KiltKeyringPair`.
- A key `mnemonic` with the type `string`.

Generating the account address takes a couple of steps. First, define a `keyring` value, which is a data structure for defining the keypair type with the following parameters:
Generating these values takes two steps:

- A key `mnemonic` with the type `string`.
1. Create the `mnemonic` value using the `mnemonicGenerate()` method from the `Utils.Crypto` package.
2. The `account` value first needs a `keyring` value defined, which is a data structure for defining the keypair type with the following parameters:

The `mnemonicGenerate()` method from the `Utils.Crypto` package generates the value for the mnemonic.
1. `ss58Format`: Specifies the encoding format for the key. Substrate-based blockchains commonly use SS58.
The value "38" represents the KILT blockchain.
2. `type`: Specifies the user's cryptographic algorithm.
Substrate-based blockchains commonly use sr25519.

- `ss58Format`: Specifies the encoding format for the key. SS58 is commonly used in Substrate-based blockchains. The value "38" represents the KILT blockchain.
- `type`: Specifies the user's cryptographic algorithm. It uses sr25519, which is commonly used in Substrate-based blockchains.

The function returns the structure using the `addFromMnemonic()` method to create an address key pair using the given mnemonic passphrase and the mnemonic value.
The function then returns the value using the `addFromMnemonic()` method to create an address key pair using the given mnemonic passphrase and the mnemonic value.

The rest of the code runs the `generateAccount` function and logs the results to the console.

Expand Down
65 changes: 50 additions & 15 deletions docs/develop/03_workshop/04_attester/02_did.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import GenerateDid from '!!raw-loader!@site/code_examples/sdk_examples/src/works

The next step is to generate a KILT decentralized identifier (DID) using the account you created for the <span className="label-role attester">Attester</span> in [the previous step](./01_account.md).

<!-- TODO: Also factor into quickstart -->

A DID may represent any entity, such as a person, an organization, or a machine.

A DID is a string uniquely identifying each KILT user.
Expand All @@ -22,41 +24,68 @@ One use case is messaging.
You could store a public encryption key and a service on-chain, and a user can query both using a DID.
Other users can now encrypt messages using your public encryption key and send a message to your service.

There are two types of DIDs: **light** and **full**.
## Light and full DIDs

Kilt supports two DID types: **light** and **full**.

There are many differences between the two types, but the most crucial is that you can use a light DID offline, but a full DID needs access to the blockchain to work.
Read the [DID documentation](../../../develop/01_sdk/02_cookbook/01_dids/01_light_did_creation.md) to learn more about the difference between the light and full types.

:::info KILT DID

There are four different key types that a DID supports:

- An _authentication keypair_, used to sign claims and create authenticated credential presentations
- An _authentication keypair_, used to sign claims and present authenticated credentials
- A _key-agreement keypair_, used to encrypt/decrypt messages
- An _assertion-method keypair_, used to write CTypes and attestations on chain
- A _capability-delegation keypair_, used to write delegations on chain

You can replace keys over time, e.g., if a key is compromised.
You can replace keys over time, e.g., if a key becomes compromised.

:::

## Account vs. DID
<!-- TODO: ? -->
You need to register a full DID on the blockchain by an account submitting the DID creation transaction.
An account submits the transactions and pays the fees and the DID that authorized the call.
Because the DID and the account are not connected, DIDs do not hold any coins.
## What's the difference between a DID and an account?

A DID and an account sound quite similar, but there are some differences:

- You record both to chain
- You can have a DID without an account
- You can have an account without a DID
- Only an account can pay deposits and fees and start a DID verification process
- DIDs don't hold any coins

In summary, you register a DID on the blockchain by an account submitting the DID creation transaction and paying the fees.

## Create a DID
<!-- TODO: ?? -->
To create a DID, you use the same keyring used to generate accounts.
For the <span className="label-role attester">Attester</span> you need all four types of key.
Since three of the key types are used for signatures, you can use the same key for these using the default KILT keyring to generate them.

As an <span className="label-role attester">Attester</span> needs to interact with the chain, you must create a full DID.

### Generate keypairs

An <span className="label-role attester">Attester</span> needs all four types of key.
Since three of the key types write and sign to the chain, you can use the same key for them using the default KILT keyring to generate them, which is the same keyring used to generate accounts.

Add the following code to the `attester/generateKeypairs` file.

<TsJsBlock fileName="attester/generateKeypairs">
{GenerateKeypairs}
</TsJsBlock>

<!-- TODO: Is this enough? -->

Throughout the code are `account.derive` methods that use key derivation syntax. You can read more about this syntax in [the substrate documentation](https://docs.substrate.io/reference/command-line-tools/subkey/#working-with-derived-keys).

The `generateKeypairs` function code derives base and sub keys from a particular path relevant to the use case for each key.
It uses the sr25519 key type, which is the default key type for KILT.

This method works for three of the four key types needed, so the `generateKeyAgreement` function helps generate the key-agreement keypair using the mnemonic.
The function takes the mnemonic and creates another key pair from it using the `sr25519PairFromSeed(mnemonicToMiniSecret(mnemonic))` combination of functions.
The function then creates a secret key based on the earlier temporary key pair and a derivation path relevant to key agreement.

The function returns the key pair needed by generating one more key pair suitable for encryption and decryption using the secret key.

### Write DID to chain

Once you have created all the necessary keys for a DID, you can create the on-chain DID.
To create a DID, load the account created in the [last section](./01_account.md) and use it to pay for the DID registration.
Create and submit the extrinsic (aka transaction) that registers the DID.
Expand All @@ -65,6 +94,12 @@ Create and submit the extrinsic (aka transaction) that registers the DID.
{GenerateDid}
</TsJsBlock>

The `createFullDid` function takes the key pair generated for the submitter in the previous step and creates a full DID. It returns a mnemonic as a string and DID definition document.
Inside the function, the `getStoreTx` method creates A DID creation operation based on the four key pairs created earlier.
It returns the extrinsic (aka transaction) that registers the DID.

The `signAndSubmitTx` method takes that extrinsic and submits it to the chain, also passing the submitter's account.

## Run the code

Now run the code with:
Expand All @@ -90,11 +125,11 @@ Once you have run the script, the output should provide you with your `ATTESTER_
The output should look like the following, but not identical since the DIDs are constructed from your account:

```
ATTESTER_DID_MNEMONIC="beyond large galaxy...
ATTESTER_DID_URI="did:kilt:4ohMvUHsyeD..."
ATTESTER_DID_MNEMONIC="beyond large galaxy
ATTESTER_DID_URI="did:kilt:4ohMvUHsyeD"
```

Save it in the `.env` file, which should now look similar to the following:
Save it in the `.env` file, which should now look like the following:

```env title=".env"
WSS_ADDRESS=wss://peregrine.kilt.io
Expand Down
57 changes: 35 additions & 22 deletions docs/develop/03_workshop/04_attester/03_ctype.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,72 +15,85 @@ import GenerateCtype from '!!raw-loader!@site/code_examples/sdk_examples/src/wor
import Ctype from '@site/scripts/out/ctype.json.raw!=!raw-loader!@site/scripts/out/ctype.json';

A claim type (CType) is a KILT-specific term, but the concept is simple:
A CType defines the structure of a claim and you can think of it as the data model for your claim.

Before the <span className="label-role attester">Attester</span> can attest credentials, they need to decide which CType they support.
For example, a traffic authority will only issue driver's licenses (=> CType for drivers license) and not trade register excerpts.
Since CTypes enable interoperability between Attesters, it is highly recommended to use existing CTypes rather than creating new ones.
However, for this workshop we will create our own CType.
A CType is a JSON schema that defines the structure of a claim, and you can think of it as the data model for your claim.

:::info CType

A CType ensures that a credential contains all required attributes, e.g., a driver's license has to contain a name, date of birth, the type of vehicle that can be driven by the claimer.
The CType is especially important since a Verifier would request credentials for a specific CType (e.g., the traffic police want to see your driver's license and not your gym membership).
A CType ensures that a credential contains all required attributes, e.g., a driver's license has to contain a name, date of birth, and the vehicle types that the claimer can drive.
The CType is important since a Verifier requests credentials for a specific CType. For example, the traffic police want to see your driver's license, not your gym membership.

If you want to learn more about CTypes take a look at our [in depth CType documentation](../../../concepts/05_credentials/02_ctypes.md).
You can also [read through existing CTypes in our CType-index](https://github.com/KILTprotocol/ctype-index).
To learn more about CTypes, read the [in-depth CType documentation](../../../concepts/05_credentials/02_ctypes.md).
You can also [read through existing CTypes in the CType-index](https://github.com/KILTprotocol/ctype-index).
:::

Before the <span className="label-role attester">Attester</span> can attest credentials, they must decide which CType they support.
For example, a traffic authority only issues driver's licenses (A CType for driver's license), not trade register excerpts.

Since CTypes enable interoperability between Attesters, using existing CTypes rather than creating new ones is highly recommended.
However, this workshop creates a new CType to show the process.

Creating CTypes requires an account and a full DID.
Make sure your account holds KILT tokens so that you can pay the fees for creating a CType.

For example, a very basic CType for a driver's license could look like this:
For example, a basic CType for a driver's license could look like this:

<CodeBlock className="language-json">
{Ctype}
</CodeBlock>

Let's have a look at these attributes.
The CType has the following attributes:

| Key | Value |
| -------------| ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `$id` | The KILT id of this CType. It is the most important property as it represents the **digital footprint** of the CType. |
| `$id` | The KILT id of this CType. It's the most important property as it represents the **digital footprint** of the CType. |
| `$schema` | A reference to the meta-schema describing what a CType may look like. There are two versions. |
| `title` | The title of the CType. |
| `properties` | The properties that a claim conforming to this CType may have. |
| `type` | Type is an object for all CTypes. |
| `additionalProperties` | The default is set to false. This restricts unwanted properties in a claim. |
| `additionalProperties` | The default is false. This restricts unwanted properties in a claim. |

A CType is stored on the KILT blockchain.

In a real-life setup, a user would simply retrieve an existing CType from the chain or a repository of CTypes for example via a Credential Registry's REST API.
<!-- TODO: What is a Credential Registry's REST API? -->
In a real-world situation, a user would retrieve an existing CType from the chain or a repository of CTypes.
For example, via a Credential Registry's REST API.

In this tutorial, we'll have the <span className="label-role attester">Attester</span> create and attempt to store a CType on the KILT test blockchain.
In this tutorial, the <span className="label-role attester">Attester</span> creates and attempts to store a CType on the KILT test blockchain.

## Create CType

Copy the following to create a `CType` with a given schema:
Copy the following that defines a `CType` with a given schema:

<TsJsBlock fileName="attester/ctypeSchema">
{CtypeSchema}
</TsJsBlock>

## Get CType

Copy the following to create a `CType` on the chain:

<TsJsBlock fileName="attester/generateCtype">
{GenerateCtype}
</TsJsBlock>

We'll use this to check if the `CType` is on-chain already.
If yes we'll return it, otherwise we'll store it on-chain.
<!-- TODO: Already exists and code hangs -->
The `ensureStoredCType` function takes the Attester's account, DID, and a callback to sign the function and checks if the CType is already on-chain.
It uses the `verifyStored` method to pass the CType to the KILT blockchain and make the check.
If it does not exist, it stores it on-chain, using the `toChain` method to encode the CType into a unique hash and the `add` method to create a new CType from the given unique hash and associate it with the Attester.
The function then uses the `authorizeTx` to authorize the transaction and `signAndSubmitTx` to sign and submit the transaction containing the new CType.

:::warning

Remember, an account must have the required amount of tokens to pay the transaction fee and deposit.

:::

## Run

<Tabs groupId="ts-js-choice">
<TabItem value='ts' label='Typescript' default>

To run it, just execute the `attester/generateCtype.ts` file.
Run the `attester/generateCtype.ts` file.

```bash
yarn ts-node attester/generateCtype.ts
Expand All @@ -89,7 +102,7 @@ Remember, an account must have the required amount of tokens to pay the transact
</TabItem>
<TabItem value='js' label='Javascript' default>

To run it, just execute the `attester/generateCtype.js` file.
Run the `attester/generateCtype.js` file.

```bash
node attester/generateCtype.js
Expand All @@ -98,4 +111,4 @@ Remember, an account must have the required amount of tokens to pay the transact
</TabItem>
</Tabs>

OK, now before we can attest Credentials, we need a <span className="label-role claimer">Claimer</span> to request it! Let's move on!
Before you can attest Credentials, you need a <span className="label-role claimer">Claimer</span> to request it
8 changes: 4 additions & 4 deletions docs/develop/03_workshop/04_attester/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ This section of the workshop covers creating the <span className="label-role att
1. [Create an account](./01_account.md) to pay for all transactions and storage deposits.
2. [Create a DID](./02_did.md), which is the identity used to create attestations.

While you can always switch the KILT account and pay deposits and fees with any , your DID stays the same and is the way Claimers identify you and put trust in you.
While you can always switch the KILT account and pay deposits and fees with any account you like, your DID stays the same and is the way Claimers identify and trust you.

3. Before you can attest claims, [you need a CType](./03_ctype.md) which describes and gives context to what you attest.
4. Once you have a way to pay fees and deposits, have an identity and a CType, [you can create attestations](../06_attestation.md).
1. Before you can attest claims, [you need a CType](./03_ctype.md) that describes and gives context to what you attest.
2. Once you have a way to pay fees and deposits, have an identity, and a CType, [you can create attestations](../06_attestation.md).

## Folder Structure

Create the following files in the `attester`` folder.
This folders serves to mimic an <span className="label-role attester">Attester</span> service.
These folders mimics an <span className="label-role attester">Attester</span> service.

<Tabs groupId="ts-js-choice">
<TabItem value='ts' label='Typescript' default>
Expand Down

0 comments on commit 024a694

Please sign in to comment.