# EVM Protocol Adapter

**URL:** <https://forum.anoma.net/t/evm-protocol-adapter/891>\
**Category:** RM\
**Created:** [December 7, 2024, 3:32pm UTC](https://forum.anoma.net/t/evm-protocol-adapter/891 "2024-12-07T15:32:13Z")\
**Posts on this page:** 1\
**Showing post:** 12

<div class="post-metadata">

**Author:** ![cwgoes](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.anoma.net/cwgoes/32/22_2.png) [@cwgoes](https://forum.anoma.net/u/cwgoes)\
**Post date:** [January 15, 2025, 10:35am UTC](https://forum.anoma.net/t/evm-protocol-adapter/891/12 "2025-01-15T10:35:29Z")

</div>

> [@Michael](#):
>
> **Protocol Adapter ¶ contract** : A solidity contract containing

As a note (which we also discussed in the call), the PA contract will also need to support “regular storage”, i.e. some way to process the fields in application data which come associated with instructions to store them for a duration beyond transaction execution. A simple first-pass implementation of this would just be to keep a content-addressed storage map of hash to bytearray.

> [@Michael](#):
>
> The difference between the three design ideas proposed in the Excalidraw image seems to be that design 1. and 3. provide previously executed EVM calls/actions as arguments to wrapper resource (WR) logics, whereas design 2. uses the initialization and finalization of ephemeral WRs and an associated wrapper contract (WC) reading from them to conduct the EVM state change call in consequence.

As a general note, it is my preference to execute all EVM state changes _before_ calling resource logics (or checking associated proofs). This way, we can also execute EVM state reads and pass those results to resource logics if desired, and guarantee that the EVM state will not change after resource logics are checked. If we execute EVM writes after or during the resource logics checks, we would be unable to support reads in this way. We might potentially want to support “pre” and “post” - EVM write execution EVM state reads (even potentially segmented per-action) – but in any case we’ll need clear segmentation here.

> [@Michael](#):
>
> The main challenge for all designs is to ensure the correspondence between WR properties such as _kind_, _owner_, or _quantity_ and the ERC20 call that must be triggered on WR initialization/finalization.

Yes. In particular, I think we can say that we want a particular resource _kind_ to correspond to a particular EVM _wrapper contract_, such that all resources of that kind “collectively” control access to EVM state (e.g. tokens) which is “owned” by the associated wrapper contract. This will work for ERC20 wrappers, and I also think that it will work well in general: we’d never want resources of another arbitrary kind to be able to control state owned by a given wrapper contract (otherwise state could be stolen), and we’d never want a wrapper contract to correspond only to a single resource (since resources are immutable).

> [@Michael](#):
>
> Furthermore, token or other contracts standards can require the receiving contracts to implement certain callback functions (e.g., `onERC721Received` or `onERC1155Received`).

This complexifies things somewhat, I can see more why you were going for “custom developer-built wrapper contracts” now.

> [@Michael](#):
>
> Here, the WC (with the `wrap(nullifier, resource, appData)` and `unwrap(nullifier, resource, appData)` function inside) gives flexibility to
> 
> - read and process data from the resource object (e.g., owner and quantity, or whatever other data the resource object contains) and
> - execute (multiple) external calls.

Here, we put the “specific correspondence”-enforcing logic inside the wrapper contract. This could work, but all else remaining the same, I think it may be easier to have the specific correspondence enforcing logic live inside the resource machine – just for the general reason that it’d be nice to have as little EVM logic and code as possible.

* * *

I have an overall proposal to simplify this system, which I’ll try to describe here – let me know if it makes sense. Forgetting the details of ERC20/ERC721/etc. and such for now, how about:

1. The basic correspondence which we’re trying to establish is between wrapper contracts (which own EVM state, execute EVM calls, etc.) and resources in the RM. Let’s further simplify and say that we represent a given wrapper contract by an “NFT” RM resource, such that only one such resource exists at any point. Let’s call this resource the “wrapper contract resource”. The correspondence which we want to enforce is that:  
a. When we create a wrapper contract, we create an associated wrapper contract resource.  
b. Any calls made by this wrapper contract can only happen in a transaction where the associated wrapper contract resource is consumed, and where the associated wrapper contract resource’s resource logic approves the calls made.
  - (in practice, we could enforce (a) with the balance check and (b) with some simple “FFICalls” field passed into resource logics, similar to app data, where we make any EVM calls from wrapper contracts requested in the transaction but enforce that the associated wrapper contracts resource logics were satisfied)

2. All further enforcement of specific connections between EVM state changes and resource machine state changes happens in these wrapper contract resource logics. For example, a wrapper contract resource logic might enforce that a CALL with certain calldata to an ERC20 contract (to call `transfer` or `transferFrom`, in practice) can be made iff. a resource of the associated denomination and quantity is consumed or created.

To some extent, this simply “pushes the complexity around” – instead of dealing with resource data in the EVM, we deal with EVM calldata in the RM – but I think that the latter might be preferable, especially in the long-term. Does this proposal make any sense? What do you think?

---

_[View the full topic](https://forum.anoma.net/t/evm-protocol-adapter/891)._
