https://github.com/timdaub/interop-pingpong
https://github.com/timdaub/interop-pingpong
Last synced: 4 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/timdaub/interop-pingpong
- Owner: TimDaub
- Created: 2025-05-20T16:59:01.000Z (9 months ago)
- Default Branch: main
- Last Pushed: 2025-05-20T17:05:48.000Z (9 months ago)
- Last Synced: 2025-06-13T05:42:59.354Z (8 months ago)
- Language: Solidity
- Size: 14.6 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# CrossChain PingPong
A demonstration of Optimism's L2-to-L2 cross-chain messaging using two OP chains in a SuperSim environment. This project implements a simple "ping pong" game where a virtual ball is sent back and forth between two OP chains.
This project is based on the [SuperSim Cross-chain Contract Calls tutorial](https://supersim.pages.dev/guides/interop/cross-chain-contract-calls-pingpong), but has been isolated and simplified to focus purely on the cross-chain messaging functionality.
## Overview
This project demonstrates:
- L2-to-L2 direct messaging between Optimism chains
- Using [SuperSim](https://supersim.pages.dev/) to run a local OP Stack devnet
- Deterministic deployments using CREATE2
- Cross-chain communication via the L2ToL2CrossDomainMessenger
## Prerequisites
- [Foundry](https://book.getfoundry.sh/getting-started/installation)
- [SuperSim](https://supersim.pages.dev/)
## Setup Instructions
1. Start SuperSim with auto-relay enabled:
```bash
supersim --interop.autorelay
```
This will launch two OP chains with the following configuration:
- OPChainA: Chain ID 901, port 9545
- OPChainB: Chain ID 902, port 9546
- Available accounts, with the first account (used for deployment) having private key `0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80`
2. Deploy the contracts to both chains:
```bash
./deploy.sh
```
The deploy script will:
- Create identical contracts on both chain 901 and chain 902 at the same address (using CREATE2)
- Initialize chain 901 with the ball (as specified in the constructor)
Successful deployment will look like:
```
Deploying to OPChainA (Chain ID 901)...
[⠊] Compiling...
No files changed, compilation skipped
Script ran successfully.
== Logs ==
Deployed at: 0xEFd7B7eCD385EdB10311Deeb760b433E215d101A
## Setting up 1 EVM.
==========================
Chain 901
... (deployment details)
ONCHAIN EXECUTION COMPLETE & SUCCESSFUL.
Deploying to OPChainB (Chain ID 902)...
[⠊] Compiling...
No files changed, compilation skipped
Script ran successfully.
== Logs ==
Deployed at: 0xEFd7B7eCD385EdB10311Deeb760b433E215d101A
## Setting up 1 EVM.
==========================
Chain 902
... (deployment details)
ONCHAIN EXECUTION COMPLETE & SUCCESSFUL.
```
**Note:** Deployment can only happen once per SuperSim session as the CREATE2 addresses will already exist on subsequent attempts. If you need to redeploy, restart SuperSim.
## Using the PingPong Game
### Check Ball Location
To check where the ball is currently located:
```bash
./check.sh
```
Initial state should show the ball on OPChainA (901):
```
Checking ball on OPChainA (901):
1
901
0x4e59b44847b379578588920cA78FbF26c0B4956C # Address may vary
Checking ball on OPChainB (902):
0
0
0x0000000000000000000000000000000000000000
```
### Hit Ball to Chain B
To hit the ball from Chain A to Chain B:
```bash
./hit.sh
```
You should see transaction details and in the SuperSim logs, you'll see messages like:
```
INFO [timestamp] L2ToL2CrossChainMessenger#SentMessage sourceChainID=901 destinationChainID=902 ...
INFO [timestamp] L2ToL2CrossChainMessenger#RelayedMessage sourceChainID=901 destinationChainID=902 ...
```
### Check Ball Again
After hitting the ball to Chain B, check its location:
```bash
./check.sh
```
You should now see:
```
Checking ball on OPChainA (901):
0
0
0x0000000000000000000000000000000000000000
Checking ball on OPChainB (902):
2
901
0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 # Address of player who hit the ball
```
### Hit Ball Back to Chain A
To hit the ball from Chain B back to Chain A:
```bash
./hitback.sh
```
After hitting the ball back, check its location again:
```bash
./check.sh
```
You should see:
```
Checking ball on OPChainA (901):
3
902
0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 # Address of player who hit the ball
Checking ball on OPChainB (902):
0
0
0x0000000000000000000000000000000000000000
```
## How It Works
1. **Contract Deployment:**
- The same contract is deployed to two different OP chains at the same address using CREATE2
- The deployment script specifies chain 901 as the "server chain" that starts with the ball
2. **Cross-Chain Messaging:**
- When a user calls `hitBallTo()`, the contract:
- Increments the rally count
- Records the sender's address and chain ID
- Clears the ball from the current chain
- Sends a cross-chain message to the destination chain using the L2ToL2CrossDomainMessenger
3. **Message Relay:**
- SuperSim's auto-relay functionality automatically relays the message to the destination chain
- The destination contract receives the ball via the `receiveBall()` function
- The ball is now on the destination chain and can be hit back
4. **Ball State:**
- The ball's state includes:
- `rallyCount`: How many times the ball has been hit
- `lastHitterChainId`: The chain ID where the ball was last hit
- `lastHitterAddress`: The address of the last player to hit the ball
## Technical Details
### Contract Address
Both contracts are deployed to the same address on different chains through CREATE2, using the same salt value:
```solidity
CrossChainPingPong game = new CrossChainPingPong{salt: "pingpong"}(901);
```
### Message Authentication
The contract includes safeguards to ensure messages come from valid sources:
```solidity
modifier onlyCrossDomainCallback() {
if (msg.sender != address(messenger)) revert CallerNotL2ToL2CrossDomainMessenger();
if (messenger.crossDomainMessageSender() != address(this)) revert InvalidCrossDomainSender();
_;
}
```
## Troubleshooting
- **Deployment Fails**: If you see revert errors during deployment, it's likely because the contracts have already been deployed. Restart SuperSim to reset the chains.
- **Ball Not Moving**: Ensure SuperSim's auto-relay is enabled with the `--interop.autorelay` flag.
- **Script Permissions**: If scripts don't run, ensure they have executable permissions: `chmod +x *.sh`