EVM Protocol Adapter

We assume that all resources are shielded

  • protocol adapter ( PA ) contract - main RM contract
  • application contracts - exist
  • wrapper contracts (WC) - connect application contracts to the RM world; for each wrapper contract there is a corresponding wrapper resource (WR) kind and PA is aware of the mapping

Each WR is associated with an FFI call that the PA is supposed to perform. In order to do that,

  1. PA needs to know where to get these FFI calls
  2. verify that the calls are authorised by the corresponding WC

FFI calls in app data

We store FFI calls in Action.AppData in a fixed location. Currently, AppData is partitioned by tags - each partition corresponds to the public inputs of the logic of the resource with the corresponding tag:
tag -> instance, with instance represented as a list of pairs (bitstring, deletion_criterion)

One option to have a standardised location for the FFI calls is to have them the first argument in the list. Alternatively, we can change the AppData structure to be a map and use a standard FFI key to store the FFI call value.

Q: how to tell the difference between WR putting their FFI calls in appData vs non-WR having FFI calls in their AppData?
A: for that we need to verify that the resource associated with the FFI call is of the WC kind. To do that, we drop function privacy for WR (we don’t lose anything because WC are public anyway) and perform the kind check as described below

Kind check

A logic of any application must have the self resource tag as a public input and resource object as private input - this is true for any logic. In addition to that, we require WR to have an extra mandatory public input - WR kind, and a new mandatory constraint checking that the input kind is the self resource kind:

  • public\_input.kind = h_{kind}(private\_input.label, private\_input.logic)

Here is why it works:

  • bind FFI call to a kind:
    • in the new logic constraint, we bind the publicly known kind to the private resource object, proving that this is indeed the kind of the currently checked resource
    • having the logic constraints public (i.e., no function privacy for WR) allows us to verify that this constraint is checked
    • logic also probably should verify the FFI call associated with the resource
  • bind kind to WC
    • having the mapping between the kinds and WCs allows the PA to know that the logic of the corresponding WR was checked

PA can go through the AppData, find the FFI calls, verify the logic proofs associated with them, and execute the FFI calls.

TL; DR

  • no function privacy for WR
  • kind is a mandatory public input for WRL
  • an extra mandatory constraint in WRL verifying kind against the resource object
  • FFI calls are stored in a standardized location in appData

TO DO:

  • standardize the location for FFI calls in appData. I’ll think if it makes sense to turn this substructure into a map (instead of a list), and if yes, we just need to define the key for FFI calls
2 Likes