STEP 1 OF 5
ALL QUICKSTARTS →
SETUP · TWO CONTRACTS, TWO CHAINS
CounterAndProxyL1 · YOUR CONTRACT · cap
contract CounterAndProxy {
Counter public target;
uint256 public targetCounter;
uint256 public counter;
constructor(Counter _target) {
target = _target;
}
function incrementProxy() external {
targetCounter = target.increment{gas: PROXY_CALL_GAS}();
counter++;
}
}
CounterL2 · REMOTE CONTRACT · counterL2
contract Counter is ICounterView {
uint256 public counter;
function increment() external returns (uint256) {
counter++;
return counter;
}
}
Counter is deployed on L2 only. On L1, target holds counterProxy, a CrossChainProxy the L1 manager deployed to stand in for Counter@L2. Neither contract imports anything from EEZ.
DAPP DEVELOPERS
Follow One Call There and Back
Card 01 ran one call from L1 into L2 and back. This is that call, contract by contract: CounterAndProxy on L1, the proxy and the manager it goes through, Counter on L2, and the value 1 coming back.
This is the local run. The scenario script does the composer's job: it posts the answer in the L1 entry and runs the call on L2. On a real network the composer builds both entries, and L1 accepts its entry only inside a verified batch.
WHAT YOU'LL LEARN
- 01 · SET UP ONCECounter lives on L2. On L1, a proxy stands in for it and becomes your contract's target.
- 02 · AN ORDINARY CALLYour contract calls target.increment() and stores what comes back.
- 03 · THE PROXY HANDS IT ONThe proxy's fallback calls executeCrossChainCall on the L1 manager.
- 04 · POSTED FIRSTCounter runs on L2. Its answer, 1, is already in the L1 entry.
- 05 · BACK IN YOUR CONTRACTThe 1 comes back through manager and proxy into targetCounter.
Verified against eez-core-protocol Git commit 9a1f815; interfaces may move.