Standardization of Resource data (`Label` and `Value`)

This post discusses resource standards similar to EIPs in Ethereum land. The standardization topic came up recently in the forum thread about connecting nullifiers and consumed resources.

Context

Resources contain the labelRef and valueRef fields that point to the respective Label and Value BLOBs. Label and Value can be used to store resource-related data.

In the Label of a resource (which affects fungibility), app devs will store kind-related information. For example, in the current Kudos implementation, we have

type TokenLabel :=
  mkTokenLabel@{
    name : String;
    symbol : String;
    decimals : Nat;
    originator : ExternalIdentity
    supply : Supply;
    transferability : Transferability;
  };

A token resource standard (similar to ERC-20 in Ethereum) could require name, symbol, decimals, and originator to be present.
In addition, there could be standard extensions that build upon or add more information to existing standards. In the example above, this would be the supply or transferability information of the token (see the similar ERC-20-capped and soulbound token extensions in Ethereum).

Likewise, the Value of a resource can contain multiple entries that can also be standardized.
A token resource might contain the owner in the Value field (and other token-related data, e.g., an expiration date).
A counter resource might contain information about its current owner and the current count in the Value field.

Proposal

Standards (tentatively named Anoma Resource Standards (ARSs) for now) could help to store and retrieve resource data in a more generic way, which helps with indexing / data discovery. For example, you could ask an indexer the following:
“Give me a list of all token resources (according to ARS-1) that are transferable (according to ARS-2) that I own (according to ARS-3).”
Projection or transaction functions could then handle standardized resources in a generic way.

To support storage of multiple standardized and non-standardized data inside Label and Value BLOBs, a key-value map as the underlying data structure would be required to enable the selective lookup by applications.
The keys of the mapping could then indicate which standards a resource supports (similar to ERC-165 in Ethereum).

An ownership standard, for example, would expect the owner ExternalIdentity information to be present under a standardized lookup key (e.g., the SHA-256 hash of the string "ARS_Ownership_v1.0.0").

Open Questions

  • Should Label and Value be required to be a map by the specs (similar to how appData is defined)?
  • Similar to Ethereum, app devs could mislead about which standards a resource supports. Is formal verification required to solve this issue?
  • Should the Logic function (or its branches) be standardized too?
  • What’s the connection between Anoma’s resource model and the RDF / semantic web?
    • It feels to me that there is a connection. RDF triplets have the form (subject, predicate, object). The subject seems to be the resource itself, the predicate the logic function (or branches therein), and object could be other resources (and properties thereof) that must be part of the same action. Constructing a knowledge graph of visible resources could help with indexing and solving.

I am curious about your thoughts @cwgoes @degregat @vveiln

Coming up with a way to define standards, and a set of initial ones makes a lot of sense!

Since the concrete data structures are up choice by the application layer (in contrast to the references, which need to be determined by the spec for the protocol), I feel like we could diverge from the default map, if there are good arguments from the application side to use, e.g. a struct.

In any case, this would be defined in the “resource standards”, which don’t need part of the spec. For applications to be interoperable developers would need to agree on the same set of standards, but it is conceivable to have different standards on top of the same network.

Could they mislead in a way that is undetectable, even after parsing the resource including all its fields (recursively), or only by proclaiming it and hoping users have lax/broken parsers? The former would be a problem, the latter we need to rule out in any case for security reasons.

There is no intentional connection, but it does seem to be compatible. The origin of our usage of the term “resource” is borrowed from the field of linear logic.

1 Like

My text was probably a bit misleading and two topics are mixed here.
There is no default map. The transparent machine defines Label and Value to be of type Nat.
This might be ok, but I think the specs should say something about the BLOB format. Otherwise, I don’t see how apps could read data from BLOBs in a generic way if they are encoded differently by different RM instantiations.

In the current Kudos implementation, I encode the TokenLabel struct from above as a Nat to store it in the Label.

Here, I proposed to encode the data as a map instead of struct and making this an requirement. E.g., the TokenLabel from above would then become something like:

# JSON
{
   "ARS-1_Token":{
      "name":"MichaelKudos",
      "symbol":"MK",
      "decimals":16,
      "originator":"0x0123...abcd"
   },
   "ARS-2_TokenSupply":{
      "supply":"Unbound"
   },
   "ARS-3_Transferability":{
      "transferable":true
   }
}

or the Value data of a counter could become

{
   "count" : 123,
   "ARS-4_Ownership": {
      "owner":"0x0123...abcd"
   }
}

These maps constituting the BLOBs could still be encoded as Nats as currently decided by engineering. However, a different underlying data type for BLOBs could make more sense. This should probably be specified by the specs people and not by engineering, since reading and decoding BLOBs in applications should be part of the general interface.

It would be detectable. You could pretend to follow a standard, but put nonsensical information into the value of the expected key, e.g.,

   "ARS-4_Ownership": {
      "owner":"This is not a public key but something else."
   }

Your post deserves a longer response which I will write later, but to just this specific point: this kind of non-compliance is easy to detect, but another kind of much more pernicious non-compliance is possible: having valid values for certain keys associated with a standard, but not actually implementing the semantics which that standard is supposed to imply. For example, what does it mean for a resource to have an owner? I would say something like: no changes can happen to the resource without the explicit consent of the owner. Determining whether a particular resource logic (an arbitrary function) implements these semantics is not even decidable (in the computer science sense), let alone detectable (which to me implies some efficient algorithm).

This “semantic compliance” is the kind of compliance which:

  1. actually matters for safe interoperability (what the fields are called does not matter), and
  2. requires some form of formal verification

In particular, let’s imagine what a kind of “semantic standard” of ownership would entail:

  1. A semantic standard is not associated with a particular named field. Rather, a semantic standard is a test that can tell us, given a defined semantics, that a particular resource logic with respect to that semantics and a particular field, either:
    a. implements those semantics (satisfies the standard in all cases)
    b. does not implement those semantics (there exists a case where the standard is not satisfied)
    c. we don’t know (no proof of either (a) or (b) was provided)
  2. Other parties who rely on correct adherence to these semantic standards would use this test (which will rely on proofs stored in various places, but we can elide those details for now) to determine what to do - for example, how to show state to the user in a UI, or how to show in an intent creation UI what certain fields “mean” (and here the word “owner” would come into play).
3 Likes

A further point here: the formal verification techniques required to prove semantic compliance are still a little ways away (at least in terms of our ability to productionise them), but I think we might be able to design these standards in a way which is both:

  1. forwards-compatible with formal proofs when they do come, and
  2. in the short-term, compatible with endorsements by particular parties that a resource logic does in fact implement the semantics of a certain standard

A generalised proof type could go a long way here, where simply assuming that a logic implements a standard when it says that it does is equivalent to a trusted delegation proof which anyone can create. All we really need is a way to clearly state semantic properties…

HOWEVER, for now, this is a research problem, and we should do something pragmatic for the devnets.

2 Likes

Right, I was thinking about “information lookup” standards (in the context of Label and Value).
General standardization of (resource) logic is not possible. Btw, this is what I had to fight against the most in my past Solidity job, where we had to work with ERC-165 and could only trust our own contracts or those created by our own infrastructure (which had to be immutable/non-upgradeable and stored in our registry contracts) to be compliant.

Hypothetically, if resource logics would contain only independent conditions/predicates connected by AND

if (!standardizedCondition1) {
  return false;
}
if (!standardizedCondition2) {
  return false;
}
...
return true;

and if the bytecode of standardizedCondition1 and standardizedCondition2 would be content-addressed and referenced in an immutable registry of standards, it could maybe work.

1 Like