Implement TZIP16Interface

Clarification and motivation

This library is supposed to expose types matching TZIP-16 interface. We have implemented such a module in this PR in another project. We should move it here to make it reusable. Also there are some known issues that should be solved:

  1. it does not preserve the annotations of the view's parameter and return types (but the "GetCounter" and "GetDefaultExpiry" views don't have annotations anyway)
  2. I did not add support for "Rest API Views", only "Michelson Storage Views"
  3. I did not add support for dynamic errors, only static errors
  4. the json deserializers will probably fail if optional fields like authors are not present
  5. the interface should be expanded to make it easier to retrieve the contract's metadata
  6. from a dev experience point-of-view, it's possible to make the mistake of decoding the metadata json to the wrong type, or calling a view with the wrong parameter type/return type. we should look for ways to statically ensure this does not happen.
  7. check that the view's code does not contain forbidden instructions
    • The following instructions must not be used: AMOUNT, CREATE_CONTRACT, SENDER, SET_DELEGATE, SOURCE, and TRANSFER_TOKENS
    • The following instructions should be understood, as relative to the contract (and block) currently being queried: SELF, BALANCE, NOW, and CHAIN_ID.
    • To simplify adoption by various implementations, in this first version of the specification, the instruction SELF should only be used before ADDRESS (i.e. only as SELF; ADDRESS should be used).
    • All the above rules should apply to code contained in Michelson lamdas or serialized into bytes values (with PACK) but, as a recommendation, those techniques should be avoided in off-chain-views.

Acceptance criteria

There is a module or several modules with Haskell types (and maybe some functions) matching those defined in TZIP-16. All items above should be resolved.

Edited by Diogo Castro