Shielded Kudos Revised (no authorisation abstraction)

This version doesn’t incorporate the authorisation abstraction for KL signature constraint yet

Kudos is an application that defines kudos denomination interface and describes how different denominations work. Kudos denominations might have some meaning assigned to them (e.g., money, trust, etc), but we will ignore the meanings here.

This is a revised version of the kudos application, it aggregates the results of the discussions from these posts:

High-level description

This kudos application allows creating kudos of multiple denominations. Kudos can be issued, burned, conditionally transferred, or swapped for other denominations or resources of unrelated kinds. Denominations are created dynamically and can contain arbitrary constraints. The kudo application logic ensures that the basic and denomination constraints are enforced.

Components

1. Kudo

This application operates on kudos. Kudos are resources that are characterised by the following resource fields:

  • logic: the main kudos logic (KL)
  • label: encodes a denomination logic (DL). Can include additional parameters expected by the DL such as the issuer’s identity
  • value: encodes the owner’s identity

Currently, identities are represented by public keys.

2. The main kudos logic KL

The main kudo logic KL verifies some universal constraints and ensures that the relevant logics such as DL and receive logic are verified, when required.

Consume

  1. The DL is triggered: there is a resource R_{DL} in the same action s.t. R_DL.logic = self.label.dl_vk

Create

  1. The DL is triggered: there is a resource R_{DL} in the same action s.t. R_DL.logic = self.label.dl_vk
  2. The receive logic is triggered [1]:
    1. There is a created resource R_{receive} in the transaction s.t.: Signature.Verify(Sig,R_receive.logic, self.value.owner) = True

3. Denomination logics DL

The kudo application expects to have multiple kudos denominations. Each denomination has its own logic that is carried by an ephemeral resource. Each kudo resource specifies its denomination by encoding the relevant denomination logic. The KL then verifies that the DL of each kudo resource is verified in the same action.

A denomination might set additional constraints on the kudo resource of the corresponding denomination, for example, require what certain fields must contain.

Denomination logic itself is carried by an ephemeral resource.

DL example

This denomination logic authorises all actions by verifying signatures. The issuance/burn is authorised by the denomination owner, transfer is authorised by the kudo owner.

The kudo additional structure specified by this DL:
  • label: includes the issuer’s pk
  • value: includes the owner’s pk
Consumed kudo r
  • Ephemeral:
    • verify a signature issued by the denomination owner signing the list of cms + nfs of the action: Signature.Verify(issuer_pk, cms + nfs, Sig) = True
  • Persistent:
    • verify a signature issued by the kudo owner signing the list of cms + nfs of the action: Signature.Verify(owner_pk, cms + nfs, Sig) = True
Created kudo r
  • Ephemeral:
    • verify a signature issued by the denomination owner signing the list of cms + nfs of the action: Signature.Verify(issuer_pk, cms + nfs, Sig) = True

Proving system inputs

  • Instance: commitments, nullifiers (nothing extra)
  • Witness: resource objects (includes issuer’s pk), signatures

4. Receive logics

Receive logics are associated with users and describe when sending to this user is allowed. Receive logics must be authorised by the user they belong to and are triggered when a transfer is initiated. Receive logics are carried by ephemeral resources of the receive kind. Their verification is currently triggered by KL.

Non-trivial receive logic example

This receive logic only allows receiving tokens of non-zero quantity of the listed assets.

Receive resource fields:
  • label: includes the identity of the user it belongs to
  • logic: receive logic
Constraints:

There is a created kudo ‘r’ in the same action s.t.:

  • r.owner = self.label.owner (checking that the kudo is created for the person whose receive logic is currently being checked)
  • r.kind() is in allowedKinds. List of allowed kinds is hardcoded in the logic in this example. We can imagine that it is something like this: allowedKinds = [apple, orange, banana] (the list contains specific kinds instead of letters)
  • r.quantity > 0

The constraint is triggered for all receive logic resources (we only create ephemeral ones to trigger the logic by design, but we can just not check it since it doesn’t seem to allow any invalid behaviour)

Transaction functions

Issue and burn kudos

We start with issuing and burning kudos since they are pretty similar to each other and are the simplest action possible.

  • On the diagram, the grey resources correspond to kudos resources of denomination #n and the green resources represent the denomination #n authorisation logic.
  • KL requires a resource with a DL from the label to be present in the same action. The DL resource verifies the issuance conditions specific to that denomination.
  • The same idea works for burning, except that now we consume a persistent resource instead of creating a persistent resource.
  • The denomination resource is ephemeral and has zero value, we only need to trigger the logic verification.

Transferring kudos with conditional receive

To allow specifying receive policies, we need to require a receive logic to be verified. This implies we need a resource that carries that logic. It cannot be a part of DL since it isn’t associated with the denomination, it is associated with the receiver. Receive logic presence requirement must be a part of the kudos logic (i.e., required for all denominations), otherwise the malicious sender can always create a denomination that doesn’t require it and send it to the desired receiver.

  • As in the issue/burn case, we need to trigger the corresponding DL
  • To bind the receive authorisation logic to the action, KL requires that there is a resource in the same action that is associated with the specified receiver’s pubkey
  • To make sure the authorisation logic is indeed created by the receiver, the receive authorisation resource must contain a signature over the authorisation logic. This signature must be verified by KL
  • As for DL, receive resource only triggers the logic and therefore can be ephemeral and zero value

Swap

Swapping kudos (to kudos of other denominations or completely different resources) is not limited by the application design and works the same way as swapping any resources work.

Further work

Receive logic distribution and safety

The user is expected to share the signed version of their receive logic with whoever is going to send them the assets. It raises a few questions:

  • how to preserve the privacy of the receive logics and only reveal it to relevant parties / only reveal relevant parts of the logic
  • how to update logics and how to control which versions are used
  • how can multiple logics be maintained

We discussed these questions here and a bit here. For now we assume the simplest version: receive logics are distributed as needed, creating a new receive logic doesn’t invalidate the old one.

Validating created ephemeral kudos

The main discussion is here

What is the role of ephemeral resources in the kudos application? They are used exclusively for balancing. At the same time, if users are allowed to send ephemeral resources to other users, we must trigger their receive logic. If we don’t do that, it is still possible for users to “spam” other users with ephemeral kudos. At the same time, triggering receive logic for ephemeral kudos has no value and is costly. Sending ephemeral kudos shouldn’t be allowed.

The problem here is that we can’t just fail a transaction that contains ephemeral kudos since we do need them for balancing. My proposal is to prohibit sending ephemeral resources to anyone but the owner of the balancing consumed resources. This removes the incentive to spam since the user can only spam themselves. To enforce that, we must have the balancing consumed resource in the same transaction (which is somewhat limiting).

What if there are multiple consumed resources with different owners that correspond to such a created ephemeral resource? I don’t have a good answer for that question. Remember that the only situation when we need to create ephemeral kudos is burning, which is a somewhat special use case.

  • Do we want to allow burning multiple kudos of different owners at once?
  • Perhaps we can then call the receive logic for the group identity combining the owners of consumed resources (how to work with such an identity is out of scope of this post)

What I see as the best solution is to somehow bind the created ephemeral kudos to the creator of the kudo to remove the incentive.

Another idea I had is to remove ownership concept from ephemeral resources but this unfortunately doesn’t help since the resources themselves still are sent to someone. We need to make sure that someone can either control what they receive or the creator doesn’t have the incentive to spam the possible receiver.

Other open questions


  1. if we find another way to constrain sending ephemeral kudos, this constrain can be checked for persistent resources only ↩︎