hypersign-protocol / whitepaper

2 stars 0 forks source link

Research on cheqd #26

Open Vishwas1 opened 2 years ago

Vishwas1 commented 2 years ago

Cheqd:

Vishwas1 commented 2 years ago

Running cheqd node test net

arnabghose997 commented 2 years ago

Cheqd Docs Link: https://docs.cheqd.io/node

arnabghose997 commented 2 years ago

There are operations that can be can be done from cheqd CLI:

  1. Creating a DID
  2. Updating a DID
  3. Query a DID

However, while going through cheqd docs (https://docs.cheqd.io/node/docs/identity-api), they seem to have more functionalities such as:

Creation and Querying of:

  1. Attributes
  2. Schema
  3. Credential Definition

Also, the command structure of Create, Query and Update DID are different in CLI as compared to the Docs

Vishwas1 commented 2 years ago

Create DID

What is the input?

cheqd-noded tx cheqd create-did '{
  "id": "did:cheqd:testnet:OTc5Ngo=",
  "verification_method": [{
    "id": "did:cheqd:testnet:OTc5Ngo=#key1",
    "type": "Ed25519VerificationKey2020",
    "controller": "did:cheqd:testnet:OTc5Ngo=",
    "public_key_multibase": "z9qGG3aSfagvN3e1wofSdjBQZQqNQHXfkUUA9DTXPXTH4"
  }],
  "authentication": [
    "did:cheqd:testnet:OTc5Ngo=#key1"
  ]
}' did:cheqd:testnet:OTc5Ngo=#key1 --ver-key YOSwduF/jlg4NvesrAgKpIxuBDbCBu6zwHO5ILEMRzeDOqDKf5YFJtAHHFvo2C4tc38rtTbU3ydx0GtQL4R4mw== --from alice --node http://localhost:26657 --keyring-backend test --output json --chain-id cheqdnode --gas-prices 25ncheq --yes

How this input is formed?

The input is formed out side the RPC / node. using client (it seems). Also the signatures are formed (by signing the payload usig the private key) on the client side and then sent to the RPC.

So RPC only get payload and signature as params.

What happened to this input when we call the RPC?

CreateDID definition

func NewMsgCreateDid(payload *MsgCreateDidPayload, signatures []*SignInfo) *MsgCreateDid {}
  1. Fetch the payload i.e didDoc
didMsg := msg.GetPayload()
  1. Fetch the signers from didDoc and signanatures from input message and then verify the signature
if err := k.VerifySignature(&ctx, didMsg, didMsg.GetSigners(), msg.GetSignatures()); err != nil {
  1. Form did and metadata
var did = types.Did{
        Context:              didMsg.Context,
        Id:                   didMsg.Id,
        Controller:           didMsg.Controller,
        VerificationMethod:   didMsg.VerificationMethod,
        Authentication:       didMsg.Authentication,
        AssertionMethod:      didMsg.AssertionMethod,
        CapabilityInvocation: didMsg.CapabilityInvocation,
        CapabilityDelegation: didMsg.CapabilityDelegation,
        KeyAgreement:         didMsg.KeyAgreement,
        AlsoKnownAs:          didMsg.AlsoKnownAs,
        Service:              didMsg.Service,
    }
metadata := types.NewMetadata(ctx)
  1. Store the did and metadata
id, err := k.AppendDid(ctx, did, &metadata)

What is the output?

{"height":"5","txhash":"6CCF53E4A232039956CB5C1D3E389F86F249B0CCDF17454DA37C2E13CD63353C","codespace":"","code":0,"data":"0A480A282F636865716469642E63686571646E6F64652E63686571642E76312E4D7367437265617465446964121C0A1A6469643A63686571643A746573746E65743A4F5463354E676F3D","raw_log":"[{\"events\":[{\"type\":\"message\",\"attributes\":[{\"key\":\"action\",\"value\":\"MsgCreateDid\"}]}]}]","logs":[{"msg_index":0,"log":"","events":[{"type":"message","attributes":[{"key":"action","value":"MsgCreateDid"}]}]}],"info":"","gas_wanted":"200000","gas_used":"70577","tx":null,"timestamp":"","events":[{"type":"coin_spent","attributes":[{"key":"c3BlbmRlcg==","value":"Y2hlcWQxd2o3amhrZXljd3E4NWdybGZ5N3I4dXVqcTJncGt3dnM1eHVrNXY=","index":true},{"key":"YW1vdW50","value":"NTAwMDAwMG5jaGVx","index":true}]},{"type":"coin_received","attributes":[{"key":"cmVjZWl2ZXI=","value":"Y2hlcWQxN3hwZnZha20yYW1nOTYyeWxzNmY4NHoza2VsbDhjNWw3bTBxcXY=","index":true},{"key":"YW1vdW50","value":"NTAwMDAwMG5jaGVx","index":true}]},{"type":"transfer","attributes":[{"key":"cmVjaXBpZW50","value":"Y2hlcWQxN3hwZnZha20yYW1nOTYyeWxzNmY4NHoza2VsbDhjNWw3bTBxcXY=","index":true},{"key":"c2VuZGVy","value":"Y2hlcWQxd2o3amhrZXljd3E4NWdybGZ5N3I4dXVqcTJncGt3dnM1eHVrNXY=","index":true},{"key":"YW1vdW50","value":"NTAwMDAwMG5jaGVx","index":true}]},{"type":"message","attributes":[{"key":"c2VuZGVy","value":"Y2hlcWQxd2o3amhrZXljd3E4NWdybGZ5N3I4dXVqcTJncGt3dnM1eHVrNXY=","index":true}]},{"type":"tx","attributes":[{"key":"ZmVl","value":"NTAwMDAwMG5jaGVx","index":true}]},{"type":"tx","attributes":[{"key":"YWNjX3NlcQ==","value":"Y2hlcWQxd2o3amhrZXljd3E4NWdybGZ5N3I4dXVqcTJncGt3dnM1eHVrNXYvMQ==","index":true}]},{"type":"tx","attributes":[{"key":"c2lnbmF0dXJl","value":"UXN1akZuR2tuQnV0ZURMOE5UMmVkVldaR1JqWnFDdHJ0YzR5dWZ4T3JqRkFyZDBlcEJpeGJRcEJ6UTRydXJLMVNQYkdKUW1EeEtpMGtrMU1RMEpPUnc9PQ==","index":true}]},{"type":"message","attributes":[{"key":"YWN0aW9u","value":"TXNnQ3JlYXRlRGlk","index":true}]}]}

Resolve DID

What is the input for the query RPC?

We need to pass the did as param

cheqd-noded query cheqd did did:cheqd:testnet:OTc5Ngo= --output json

What is the output?

and it returs a didDoc alng with metadata

{
  "did": {
    "context": [],
    "id": "did:cheqd:testnet:OTc5Ngo=",
    "controller": [],
    "verification_method": [
      {
        "id": "did:cheqd:testnet:OTc5Ngo=#key1",
        "type": "Ed25519VerificationKey2020",
        "controller": "did:cheqd:testnet:OTc5Ngo=",
        "public_key_jwk": [],
        "public_key_multibase": "z9qGG3aSfagvN3e1wofSdjBQZQqNQHXfkUUA9DTXPXTH4"
      }
    ],
    "authentication": [
      "did:cheqd:testnet:OTc5Ngo=#key1"
    ],
    "assertion_method": [],
    "capability_invocation": [],
    "capability_delegation": [],
    "key_agreement": [],
    "service": [],
    "also_known_as": []
  },
  "metadata": {
    "created": "2022-02-03 12:57:32.937886125 +0000 UTC",
    "updated": "2022-02-03 12:57:32.937886125 +0000 UTC",
    "deactivated": false,
    "version_id": "bM9T5KIyA5lWy1wdPjifhvJJsMzfF0VNo3wuE81jNTw="
  }
}
arnabghose997 commented 2 years ago

Update DID

While updating here means making changes in the existing DID, we will assume that the DID is already created

The input DID is:

{
      "id": "did:cheqd:testnet:OTc5Ngo=",
      "verification_method": [{
        "id": "did:cheqd:testnet:OTc5Ngo=#key1",
        "type": "Ed25519VerificationKey2020",
        "controller": "did:cheqd:testnet:OTc5Ngo=",
        "public_key_multibase": "z9qGG3aSfagvN3e1wofSdjBQZQqNQHXfkUUA9DTXPXTH4"
      }],
      "authentication": [
        "did:cheqd:testnet:OTc5Ngo=#key1"
      ]
}

Upon querying the DID

{
   "did":{
      "context":[

      ],
      "id":"did:cheqd:testnet:OTc5Ngo=",
      "controller":[

      ],
      "verification_method":[
         {
            "id":"did:cheqd:testnet:OTc5Ngo=#key1",
            "type":"Ed25519VerificationKey2020",
            "controller":"did:cheqd:testnet:OTc5Ngo=",
            "public_key_jwk":[

            ],
            "public_key_multibase":"z9qGG3aSfagvN3e1wofSdjBQZQqNQHXfkUUA9DTXPXTH4"
         }
      ],
      "authentication":[
         "did:cheqd:testnet:OTc5Ngo=#key1"
      ],
      "assertion_method":[

      ],
      "capability_invocation":[

      ],
      "capability_delegation":[

      ],
      "key_agreement":[

      ],
      "service":[

      ],
      "also_known_as":[

      ]
   },
   "metadata":{
      "created":"2022-02-03 23:43:29.188201351 +0000 UTC",
      "updated":"2022-02-03 23:43:29.188201351 +0000 UTC",
      "deactivated":false,
      "version_id":"W5Jc+DcxOcocWiz1BIhaplCff9vvNgT2EWVaSZKFiow="
   }
}

What is the input?

cheqd-noded tx cheqd update-did '{
     "id": "did:cheqd:testnet:OTc5Ngo=",
     "version_id": "W5Jc+DcxOcocWiz1BIhaplCff9vvNgT2EWVaSZKFiow=",
     "verification_method": [{
       "id": "did:cheqd:testnet:OTc5Ngo=#key1",
       "type": "Ed25519VerificationKey2020",
       "controller": "did:cheqd:testnet:OTc5Ngo=",
       "public_key_multibase": "z9qGG3aSfagvN3e1wofSdjBQZQqNQHXfkUUA9DTXPXTH4"
     }],
     "authentication": [
       "did:cheqd:testnet:OTc5Ngo=#key1"
     ],
     "capability_delegation": [
       "did:cheqd:testnet:OTc5Ngo=#key1"
     ]
   }' did:cheqd:testnet:OTc5Ngo=#key1 --ver-key YOSwduF/jlg4NvesrAgKpIxuBDbCBu6zwHO5ILEMRzeDOqDKf5YFJtAHHFvo2C4tc38rtTbU3ydx0GtQL4R4mw== --from alice --node http://localhost:26657 --keyring-backend test --output json --chain-id cheqdnode --gas-prices 25ncheq --yes

What we are updating in this existing DID is that the capability_delegation field is being updated from null to ["did:cheqd:testnet:OTc5Ngo=#key1"]

How the input is formed?

It is similar to the Create DID scenario, where the payload is formed outside of RPC side, and the signatures are formed on the client side.

What happened to this input when we called the RPC?

UpdateDID definition

func NewMsgUpdateDid(payload *MsgUpdateDidPayload, signatures []*SignInfo) *MsgUpdateDid
  1. Fetch the payload i.e., didDoc
didMsg := msg.GetPayload()
  1. Check if the DID is already present
if !k.HasDid(ctx, didMsg.Id) {return nil, sdkerrors.Wrap(sdkerrors.ErrKeyNotFound, fmt.Sprintf("key %s doesn't exist", didMsg.Id))}
  1. Get the existing didDoc from the store
oldStateValue, err := k.GetDid(&ctx, didMsg.Id)
if err != nil {
    return nil, err
}

oldDIDDoc, err := oldStateValue.UnpackDataAsDid()
if err != nil {
   return nil, err
}
  1. Fetch the signers from didDoc and signanatures from input message and then verify the signature
if err := k.VerifySignatureOnDidUpdate(&ctx, oldDIDDoc, didMsg, msg.Signatures); err != nil {
    return nil, err
}
  1. Replay Protection (Checks whether version_id is passed)
if oldStateValue.Metadata.VersionId != didMsg.VersionId {
    errMsg := fmt.Sprintf("Ecpected %s with version %s. Got version %s", didMsg.Id, oldStateValue.Metadata.VersionId, didMsg.VersionId)
    return nil, sdkerrors.Wrap(types.ErrUnexpectedDidVersion, errMsg)
}
  1. New Did and Metadata structure is formed
var did = types.Did{
  Context:              didMsg.Context,
  Id:                   didMsg.Id,
  Controller:           didMsg.Controller,
  VerificationMethod:   didMsg.VerificationMethod,
  Authentication:       didMsg.Authentication,
  AssertionMethod:      didMsg.AssertionMethod,
  CapabilityInvocation: didMsg.CapabilityInvocation,
  CapabilityDelegation: didMsg.CapabilityDelegation,
  KeyAgreement:         didMsg.KeyAgreement,
  AlsoKnownAs:          didMsg.AlsoKnownAs,
  Service:              didMsg.Service,
  }

metadata := types.NewMetadata(ctx)
metadata.Created = oldStateValue.Metadata.Created
metadata.Deactivated = oldStateValue.Metadata.Deactivated
  1. Updates did and metadata in the store
if err = k.SetDid(ctx, did, &metadata); err != nil {
    return nil, err
}

What is the output?

{
  "did": {
    "context": [],
    "id": "did:cheqd:testnet:OTc5Ngo=",
    "controller": [],
    "verification_method": [
      {
        "id": "did:cheqd:testnet:OTc5Ngo=#key1",
        "type": "Ed25519VerificationKey2020",
        "controller": "did:cheqd:testnet:OTc5Ngo=",
        "public_key_jwk": [],
        "public_key_multibase": "z9qGG3aSfagvN3e1wofSdjBQZQqNQHXfkUUA9DTXPXTH4"
      }
    ],
    "authentication": [
      "did:cheqd:testnet:OTc5Ngo=#key1"
    ],
    "assertion_method": [],
    "capability_invocation": [],
    "capability_delegation": [
      "did:cheqd:testnet:OTc5Ngo=#key1"
    ],
    "key_agreement": [],
    "service": [],
    "also_known_as": []
  },
  "metadata": {
    "created": "2022-02-03 23:43:29.188201351 +0000 UTC",
    "updated": "2022-02-04 00:04:58.460013461 +0000 UTC",
    "deactivated": false,
    "version_id": "RGRbYXzapMPTqz4wlCQxTB6fxvmrd50WzvKET1JJlbM="
  }
}