Skip to content

Instantly share code, notes, and snippets.

@opsuperchain
Last active February 25, 2025 21:08
Show Gist options
  • Save opsuperchain/6f46504e84e37318e66466553dcceb4c to your computer and use it in GitHub Desktop.
Save opsuperchain/6f46504e84e37318e66466553dcceb4c to your computer and use it in GitHub Desktop.
ETH Denver Interop Workshop

Today we are going to explore some of the exciting things you can do with NATIVE interop coming to an OP Stack chain near you!

What is native interop?

Within the Superchain interop set, any chain can securely read any event from any other chain within seconds. This means tokens can be bridged instantly, apps can be built which span multiple chains, etc. Native interop removes the primary technical barrior to app devs building fully chain abstracted experiences, bringing us far closer to a world where users don't need to worry about bridging their tokens to the wrong chain.

Full explainer: https://docs.optimism.io/stack/interop/explainer

Let's try an example app!

Follow the instructions here: https://github.com/ethereum-optimism/superchain-starter

git clone https://github.com/ethereum-optimism/superchain-starter

Update Superchain Starter to use the devnet

Get some devnet eth with https://console.optimism.io/ !

diff --git a/src/App.tsx b/src/App.tsx
index c8d43c3..54583d6 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -16,7 +16,7 @@ import {
   useWatchContractEvent,
   useWriteContract,
 } from 'wagmi';
-import { supersimL2A, supersimL2B } from '@eth-optimism/viem/chains';
+import { interopAlpha0, interopAlpha1 } from '@eth-optimism/viem/chains';
 import { contracts, l2ToL2CrossDomainMessengerAbi } from '@eth-optimism/viem';
 import { privateKeyToAccount } from 'viem/accounts';
 import { sortBy } from '@/lib/utils';
@@ -30,10 +30,10 @@ import { crossChainCounterIncrementerAbi } from '@/abi/crossChainCounterIncremen
 
 const CONFIG = {
   devAccount: privateKeyToAccount(
-    '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'
+    'your private key'
   ),
-  sourceChain: supersimL2A,
-  destinationChain: supersimL2B,
+  sourceChain: interopAlpha0,
+  destinationChain: interopAlpha1,
   contracts: {
     counter: {
       address: '0x1b68f70248d6d2176c88d9285564cd23173d41d3',
diff --git a/src/Providers.tsx b/src/Providers.tsx
index 2431135..c157921 100644
--- a/src/Providers.tsx
+++ b/src/Providers.tsx
@@ -1,14 +1,14 @@
 import { createConfig, http, WagmiProvider } from 'wagmi';
 import { QueryClientProvider, QueryClient } from '@tanstack/react-query';
-import { supersimL2A, supersimL2B } from '@eth-optimism/viem/chains';
+import { interopAlpha0, interopAlpha1 } from '@eth-optimism/viem/chains';
 
 const queryClient = new QueryClient();
 
 const config = createConfig({
-  chains: [supersimL2A, supersimL2B],
+  chains: [interopAlpha0, interopAlpha1],
   transports: {
-    [supersimL2A.id]: http(),
-    [supersimL2B.id]: http(),
+    [interopAlpha0.id]: http(),
+    [interopAlpha1.id]: http(),
   },
 });

Building a random DeFi app

Alright let's do this. TO THE SALON! - I mean to cursor, let's use cursor. Who actually writes code anymore???

git clone [email protected]:opsuperchain/futuristic-superchain-starter.git

If you want, you can try out this prompt in cursor

Alrighty! Please:
1. Poke around the repo and get familiar. Look at the contracts in `./src`, look at the tests in `./test` and look at the frontend in `./frontend`

2. Add a token contract which has a 'bridgeTo' that takes a chain id and token amount and sends a message to itself on that chain. You can use the script `./scripts/promify_contracts.py` to generate the async interfaces. Please make it so the contract takes in as a constructor arg the address that should get the initial supply minted to it AND a "home chain ID". Only mint tokenns if chain ID is the home chain. 
  - For bridgeTo please follow these steps:
     - Make the cross chain call using the pattern found in Counter.sol (read it for the example)
     - You can generate the remote interface using the python script

Pause there

Once the little AI has done this for you, you might want to say:

Great! Now can you add some new tests which test deploying a new token and transferring it? Look at how the tests are structured in Counter.spec.ts to understand how to build them

A new paradigm

We are adding a powerful new primative to the EVM that will fundamentally change how developers build their Solidity apps. This is both a terrible thing because now we need to build new tooling, but also a super exciting thing because YOU can be the one who builds the tools!

Some examples of things we need...

Solidity Promises

We have known for a long time that eventually Solidity would require async support in order for the EVM to scale. With native interop, async in Solidity is transitioning from theory into practice. We need the ability to initiate a cross chain transaction on chain A, wait for it to execute on chain B, then trigger a callback on chain A to complete the round trip... Sounds like we need some Promises!

Cross chain contract deployment

We have a hard requirement in interop land that contracts are at the same address on every chain. Why? We've seen an scary amount of user error--even pre-interop--where hackers will squat addresses of known applications that haven't been deployed on a new chain so users accidentally send to that address.

Thankfully, we've got a good way to ensure addresses are consistent on every chain with the CREATE2 factory! However, CREATE2 is insanely annoying to work with manually, so we've got a lot of work to do to make it actually usable.

Upgradable cross chain proxies

Many Ethereum smart contracts are upgradable... How do we do this in a cross chain setting? We need standards!

Specifically we probably want a standard way for a cross chain proxy to look up its implementation address on a remote chain before executing. And we probably want this to be configurable so that instead of having to do a remote call every time the proxy is used, it can cache its implementation and just invalidate the cache periodically.

There's also an interesting interaction between async<>create2<>upgradbale proxies where we will probably want to build a standard where when a contract sends messages to instances of itself on a different chain, it can check to make sure that the version of itself it is communicating with is correct before executing the message. For example, if you have your cross chain proxy on two chains and one proxy updated its implementation before the other one, then you might want messages from ProxyA (latest impl) -> ProxyB (old impl) to be ignored until ProxyB upgrades its implementation.

FUN STUFF!

πŸš€πŸš€πŸš€ COME HACK WITH US πŸš€πŸš€πŸš€

@opsuperchain
Copy link
Author

@j6i
Copy link

j6i commented Feb 25, 2025

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment