Better tickets UX

Currently there are two protocol limitations that introduce friction when using tickets:

  • Implicit accounts cannot call contracts with an arbitrary parameter type that contains tickets (only call entrypoints that accept just tickets, via transfer_ticket operation kind)
  • Implicit accounts cannot call smart rollups with an arbitrary parameter type that contains tickets (only smart contracts can do that, via internal inbox messages)

Relevant docs:

Sending tickets to contracts

Implicit accounts are able to send tickets to smart contracts using Transfer_ticket operation. The result of such operation is an internal transaction with restricted entrypoint type.

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

The entrypoint must have ticket a type, meaning that one cannot pass additional data alongside. However there are cases when it is necessary to do so.

Current workaround

What we can do is splitting the invocation in two parts:

  • Passing the extra info
  • Sending the ticket

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Invoked contract has to support this two-step workflow i.e. save temporary context. Ideally these two call should be done in a batch to ensure atomicity.

Improved UX

A better option would be Transaction operation with arbitrary parameter type allowing tickets. That would:

  • Simplify the smart contract design (less code => less bugs)
  • Decrease gas consumption
  • Resolve ambiguity with multiple operation kinds for interacting with smart contracts

From the wallet/indexer perspective it should not introduce any additional work as long as ticket updates are included in the operation receipt.

Invoking rollups

Implicit accounts are not allowed to call smart rollups (i.e. send internal inbox messages), they can only submit blobs (aka external inbox messages). Only smart contracts can send transactions (that can also contain tickets) to rollups.

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Current workaround

Currently if one wants to send internal inbox message he needs to use additional smart contract as a proxy.

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

A proxy should not necessarily be a standalone contract, it can also be an extra feature in the contract containing business logic (yet standalone implementation provides a more clear separation of concerns).

Better UX

A better approach would be allowing implicit account to invoke smart rollups the same way they invoke smart contracts (including the forementioned ticket UX fix). It would:

  • Simplify smart contract design (or remove the need for a proxy contract)
  • Reduce gas consumption

Conclusion

Generally this proposal is about aligning different types of accounts in terms of what they can do with tickets — and thus facilitate adoption.

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Updates

Ticket withdrawals from rollups to implicit accounts (Dec'23)

Currently smart rollups can only initiate smart contract calls on L1. On the kernel side you can specify destination address (originated contract), entrypoint, and parameters (either typed or untyped):

{ /* Atomic_transaction_batch */
  "transactions":
    [ { "parameters": $micheline.017-PtNairob.michelson_v1.expression,
        "destination": $017-PtNairob.contract_id.originated,
        "entrypoint"?: $unistring } ... ],
  "kind": "untyped" }
|| { /* Atomic_transaction_batch_typed */
     "transactions":
       [ { "parameters": $micheline.017-PtNairob.michelson_v1.expression,
           "parameters_ty": $micheline.017-PtNairob.michelson_v1.expression,
           "destination": $017-PtNairob.contract_id.originated,
           "entrypoint"?: $unistring } ... ],
     "kind": "typed" }

This restriction means that users cannot withdraw their assets (tickets) without an intermediary, which causes:

  • Extra friction: one needs to discover or deploy a proxy contract that can handle the outbox message call
  • Trust issue: one has to trust the proxy contract code and/or the shared deployment
  • Possibility of unrecoverable loss: while ticket transfer cannot fail, a smart contract call might be reverted due to a runtime error and in that case tickets will be lost (since there is no feedback to the rollup about the execution outcome)

A clean solution that would not break backward compatibility is introducing another outbox transaction type, e.g.:

{ /* Atomic_transfer_ticket_batch */
  "operations":
    [ { "ticket_contents": $micheline.017-PtNairob.michelson_v1.expression,
	"ticket_ty": $micheline.017-PtNairob.michelson_v1.expression,
	"ticket_ticketer": $017-PtNairob.contract_id.originated,
	"ticket_amount": $nat,
	"destination": $017-PtNairob.contract,
	"entrypoint"?: $unistring } ... ],
  "kind": "transfer_ticket" }

Overall, removing the current limitations on the interaction between implicit and smart rollup accounts would accelerate the ticket adoption.