Cross-action resources

In this post I will elaborate on the possibility of re-using resources. Perhaps it is something already discussed/considered. But if not, hopefully adds some value.

Just be warned, these are raw thoughts with loose ends. I did not sit on them long enough, so there may be red flags I did not realize.

The current situation

An action defines the execution context of resources. A logic associated to a resource has access only to resources of the same action. Moreover, the logic must account for all resources participating in the action.

The fundamental invariant that all resources must comply with is the following one.

Invariant:

  1. Resources can be created and consumed only once.

  2. The creation and consumption of a resource is associated to exactly one action. A resource is said to be associated with an action if its commitment or nullifier is present in the action’s created or consumed correspondingly.

The invariant is achieved by enforcing that the commitment or nullifier of a resource appears once in the corresponding public lists.

Cross-action resources

I will distinguish two cases. Depending on whether the resource is being created in the transaction (native resource) or it has been created already in a past transaction (foreign resource).

Native resources

Let’s start looking at what would happen inside transactions. Suppose we have a situation like this one:

  • create resource A,
  • create resource B if f(A,B) =1,
  • create resource C if g(A,C)=1,

where f and g are logics associated to resources B and C, respectively. With the current definition, we probably have to proceed as follows:

  • create resource A
  • create resource B if \tilde{f}(A,B,C)=1 // where \tilde{f}(A,B,C) = f(A,B)
  • create resource C if \tilde{g}(A,B,C)=1 // where \tilde{g}(A,B,C) = g(A,C)

We are now dealing with more complex logic \tilde{f} and \tilde{g}. They take extra, unneeded, resources as inputs. Even worse, we are forcing the creation of B and C to happen in the same action. If these resources belong to different users, they must “interact”, even though they don’t really need it!

To simplify and remove artificial interaction we can “re-use” resource A. Since we have a commitment to it, consistent re-use can be guaranteed (with high probability). In our example we could have three actions. One for resource A, another for resources A,B, and another for resources A,C.

The compliance invariant. It should be maintained. But instead of associating a resource to the (only) action it participates in, we now require a resource is associated to one, and at most one, of the actions appearing in the transaction.

Invariant’ (modified):

  1. Resources can be created and consumed only once.

  2. The creation and consumption of a resource is associated to exactly one action. A resource is said to be associated with an action if its commitment or nullifier is present in the action’s created or consumed correspondingly.

Resources participating in an action do not necessarily belong to any of their compliance units. But there must exist a compliance proof somewhere in the transaction. Note that it will be known what action the resource is associated to. Which is also true currently, as, trivially, a resource can be in one action only.

A major difference with respect to the current situation is that the enforcement of the modified compliance invariant is not atomic anymore (with actions being the atom). It traverses the entire transaction, necessitating all their actions. Pretty much like (transaction) delta proofs, which are not atomic neither.

Foreign reactive resources

What can we do with a resource? Once a resource is created, you can consume it. That’s it. Maybe there is a good reason for this, that I fail to see. Maybe there isn’t. But in principle, we can do more with a resource. Abstractly, resources could influence the evolution of the state reactively, i.e. more than once.

Here it is a concrete example. An application implementing a PKI. In this case, resource A includes the CA certificate for a public key in resource B. So, f(A,B)=1 iff the certificate is valid. Resource B can be used in other contexts, like signing other certs, as long as it has a valid certificate. Read the above as “as long as resource A exists”. Revoking the public key in B is straightforward: consume A --the certificate is not part of the state anymore.

What is essential above? Only created but not consumed resources can participate reactively in transactions. Which is to say that the nullifier of the resource is not in the public list of nullifiers. We need a proof of non-membership for reactive resources. To distinguish between consumed and reactive resources, probably would need to branch the compliance logic for “input/left” resources of compliance units.

A note on the reactive model. The set of created but not consumed resources defines the state of the system. So they question really is: which model offers more versatility? Perhaps is the same, I don’t know. This is very much like the UTXO versus account model, I think.

Impact on function privacy. The commitment of a reactive resource appears in several transactions. So, applications needing reactive state can be separated from applications that don’t, by simply looking at the instances (public inputs) of the compliance relation. Thus, it does not suffice to hide the logic of the resource. One may argue it is good enough to hide the application among the set of apps re-using state. But I don’t think it would be a satisfying answer to everyone. For truly function privacy something more beyond the universal verifier is needed. I am not clear what exactly would that be. Perhaps re-randomization of commitments of reactive resources would help to avoid tracing them.

1 Like

Do you have an example when we might want to make the creation of completely independent resources B and C depend on the resource A that was created in the same action? How do the owners of B and C learn about A independently if A doesn’t exist and will be created within the same transaction?

If A is a foreign resource, we can just pass it without consuming as non-linear input to the logic, and B and C do not have to be in the same action.

Generally speaking, immutable models are not limiting: everything you can achieve immutably, you can also achieve mutably. The immutability property is related to the write permissions - you cannot modify a resource, but nothing stops you from reading it. In the specification we talk about resource write properties since read properties are inherited from the general notion of data, I guess. If you are permitted to read (i.e., can decrypt), you can pass the resource as non-linear data, not as a resource. Kinda like we pass signatures in logics. In that case, resource is not considered to be associated with the action since it is not modified in the action, but it can influence other resources.

The only reason to bind resource tag to the action is to ensure its logic is executed, and we care about the logic being executed when we want to consume or create the resource. If we want to use it to influence other resources, we don’t have to trigger its own logic, and therefore don’t have to bind the resource to the action.