Views TZIP

Request for comments on the views proposal. The comments can be left below.

Why do we need GET_STORAGE if we have VIEW?

The existence of GET_STORAGE means that the storage type of a contract becomes definitely part of its observable behavior.

So, for example, a compiler cannot modify the storage type (perhaps optimizing things away, or adding things) while preserving semantics. Indeed, two contracts will be semantically equivalent only if they have identical storage types (presumably including annotations, unless they are eliminated someday, or the GET_STORAGE check ignores them as a special case.)

Presumably, GET_STORAGE and VIEW will be forbidden to involve ticket or any other future non-DUPable/“forged” types (for VIEW, in the return type)?

If so, GET_STORAGE will be completely unusable on any contract whose storage involves ticket?

VIEW requires the targeted contract to prepare “function” and GET_STORAGE allows us to receive storage directly from the targeted contract.

The type for GET_STORAGE is necessary and observable since Michelson is typechecked and it is a part of definitions of contract.

Currently, GET_STORAGE and VIEW aren’t forbidden that since these two instructions are read-only. They can’t modify the storage.

What’s the concern for forbidden that?

Yes. The new thing to me is that the storage type of a contract becomes observable to other contracts, like the parameter type is now, or like the types of views would (and should) be. In other words, the storage type becomes part of the on-chain “public interface” of a contract. Personally, I like that the storage type is “private.”

The most obvious implementations of GET_STORAGE and VIEW with ticket in the return type would violate the intended resource semantics of tickets. It would allow a contract to receive copies of tickets while leaving the original tickets in the other contract’s storage. For GET_STORAGE the ownership semantics would be completely destroyed, as any contract could steal copies of any other contract’s tickets.

Maybe, instead of forbidding tickets, one could walk the storage value, replacing any tickets with some kind of dummy tickets. (Maybe replace the ticketer address with a dummy address…?) This would have to be done lazily for tickets contained in big_maps too, I guess.

Please correct me if I am wrong. I think it isn’t a issue because when inspected the value of the received ticket by GET_STORAGE, VIEW or others, it will include the amount, and the address of the ticketer, i.e. the contract that created the ticket. So, we can’t really “forge” and pretend a ticket which has been created by another ticketer.

Tickets are intended to have a resource interpretation, like linear logic, or affine really; they can be DROP'd, but:

VIEW should not provide a way for a contract (or others) to effectively DUP its tickets, and GET_STORAGE definitely should not provide a way for other contracts to DUP a contract’s tickets without its consent.

Anyway, my personal recommendation is to drop GET_STORAGE and to forbid ticket (allow_forged:false) in the return type of views.

The only specific (not very convincing) motivation I have heard for GET_STORAGE is that it would provide access to the storage data of “adversarial” contracts. But if ticket is forbidden for GET_STORAGE, and such adversarial contracts could simply include a ticket in their storage type to block the use of GET_STORAGE, then it wouldn’t serve that purpose.

There could be other solutions, though…

For conservation of tickets, it also seems necessary to forbid operation in the return type of view, since tickets can be smuggled under transfers or originations. (In any case, operation in a view seems questionable…)

Other miscellaneous questions arise too: are all the various transaction-context instructions like SENDER, AMOUNT, BALANCE, SELF_ADDRESS (but not SELF), etc… allowed inside view? Do they have the same values seen by the caller? Maybe some of them (BALANCE? SELF_ADDRESS and SELF?) take values pertaining to the callee?

It is not only about adversarial contracts.

It can be about retroactively adding new views to the contract: the information is already there, but the view was not written before, and we want to use that new information.

But yeah. We will drop GET_STORAGE as a result. I do not believe we can find a good model for it (stubbing tickets? what about big maps??).
For views, yup, tickets and wrappers (big maps or operations) have to be forbidden.