Actually, for receiver authorization the hash / identity of the constraint resource cannot be an argument of transfer, that’s wrong. It must be uniquely determined by I (e.g. by a field in I).
I think that this question is basically about how receiver authorization works. I would imagine that receive authorization involves sending a message to the receiver – something like authorize(sender, asset, amount) – and the receiver responds with a 0/1 bit that indicates whether the transfer is accepted (where the transfer, if not accepted, does not complete). I, in processing this receiver authorization message, would then require that the appropriate constraint resource is present. Do you think that would work?
On a high level, it makes sense. But I’m trying to think about this in terms of an actual RM implementation and how this would look like. So let me try to unpack this.
What does it mean, on the RM level, to send a message to the receiver and for the receiver to respond with a 0/1 bit?
Sending a message to the receiver could mean that the transaction which contains the transfer message transfer(Bank, A, B, asset, amount) also contains an authorization message authorize(B, asset, amount). The RL of the receiver B then contains logic to handle this authorization message and check if e.g. required transfers are performed in the same transaction. So B responding with a 0 bit could mean just that the RL of B fails for authorize, with 1 that it succeeds. This assumes that there is some resource in the transaction corresponding to B.
Now we come back to the question how to ensure that transfer and authorize are bound together, and nobody can submit a transaction with just transfer and no authorize that would go through. It seems the RL of Bank for the transfer message needs to check if appropriate authorize for B is present in the transaction. This authorize message must be uniquely determined by B, asset and amount. This is somewhat similar to transfer logic checking for the presence of a constraint resource uniquely determined by the receiver identity.
Yes, I think this would work.
Yes, that sounds like a reasonable way to implement this to me! At the AVM level, my hope is that this doesn’t require any “special” machinery – the bank object just calls “authorize” (in the body of the “transfer” method), and if authorization fails the transaction reverts.
I think this is unavoidable if we want the object system to be implemented on the application layer (which I think we want), i.e. the separation itself necessitates this.
If the object system could enforce anything on intents/resources, that do not bind to it from below, that would make the object system the lowest layer.
The core idea of any object is to have a fixed interface, i.e. for each (version) of an object, there is a clearly defined set of methods that can be invoked on this (version) of the object. Thus, an application developer may actually want to have the guarantee that only the things due to invocations according to the current interface may affect the object. This is pretty much the essence of object orientation after Allen Kay (independent of small talk).
I’m sorry that I long ago coined the term “objects” for this topic because it gets many people to focus on the lesser idea.
This idea was already present in the eden system.
It may be well worth having an explicit example for this in the final report @Lukasz .
For objects replacing smart contracts, this seems a no brainer: a smart contract has an API and you’d not want to change the state of the smart contract by anything else by the contract API. That’s the whole point here.
Then there may be wilder objects to be had, but as an end user, I’d want to know what is possible to happen in the dapp as transparently as possible.
I wonder if this is generally true. At least if you have a mixed model, this question becomes a lot dicier, since let us consider an object O
let’s say O accepts the messages: M_1 {M, N, P}.
Now let us say we can have “derived methods”, that is methods that are derived from the composition of the methods found within M_1. Let us say {MN, NP, MP} belong to this set.
Now is the extended set M_2 acceptable: M_2 {M, N, P, MN, NP, MP}.
I would argue that it is, and if you look at it from an Erlang perspective then it simply doesn’t care.
This has a lot of implications I’ve been mulling over for a while, which is to say, what is the “primitive” set, or what set of methods have any extra permissions over others? To me it’s not been very clear. As the answer depends on what kind of OO model you want. For example, for any OO model with slots, you actually don’t have primitive access to your state. Instead there is an entire protocol to access your state, meaning we could restrict access in interesting ways with a protocol around slots (typically a MOP feature).
If you have a way to do this, then you have a way to effectively add on new methods to objects without affecting any underlying assumptions, this is what extension methods in Smalltalk has and is something that has ridden Rust/Java with a lot of annoyances because it’s something you can’t do without making wrapper classes/structs.
I have opened a new thread elsewhere.[1]
This post seems to concern a notion of object that was never considered in goose, but deserves attention as what I would consider Engineering Ideation. However, if another category is more appropriate, we may want to move it elsewhere then. ↩︎
Can we have a mixed model with on demand guarantees?
If I create a set of resources for an application where it is important to have interface guarantees, each of them could bind to a specific object type/set of methods or interfaces, encoded as another resource.
If they don’t do that, then any object that is compatible with them could be derived, giving us flexibility where no restrictions are necessary.
To quickly answer this question: “yes”
Namely you can change either the meta object or the super class you inherit or mixin from that puts a damper on the declared interface for an object, you can either pass in the methods you want to see, or use reflection at times such as invocation time to properly limit the method set.
There are many strategies you can implement easily to achieve this same affect given some kind of reflection model (read MOP).