StandardBridge,
the CrossDomainMessenger pair, and the OptimismPortal contract.
Is this guide for you?
Use this guide if:- You are building contracts or backend infrastructure that initiate L2 actions from L1: a custom token bridge, an L1-controlled L2 contract, or a protocol that must be able to force transactions into the L2.
- You need to choose which contract interface to build against, not just follow one path.
Before you start
You should already have:- A Solidity development environment and a funded account on Sepolia and OP Sepolia (or another OP Stack testnet).
- Basic familiarity with how contracts call each other on a single chain; the bridging basics guide sets the baseline vocabulary.
Step 1: Map the deposit path
Every L1 to L2 write, whatever interface you use, ends as a call to theOptimismPortal contract’s depositTransaction function, which emits a
TransactionDeposited event that the rollup node derives into an L2
transaction. Read the deposit flow explanation
and take away:
- The encapsulation chain: your contract calls a messenger, the messenger
calls the portal, the portal emits the event, and
op-nodeturns the event into an L2 transaction. Each layer you use adds convenience and safety on top of the one below it. - That deposits are included by derivation, not by the sequencer’s grace: once the L1 transaction is confirmed, the L2 transaction will happen.
sendMessage(target, message, minGasLimit) interface shape,
the 1 to 3 minute L1 to L2 delivery time, and how the portal charges for L2
execution by burning L1 gas.
Step 2: Choose your entry layer
This is the decision that shapes everything downstream. Work down the table and stop at the first row that fits:
For the current contract interfaces, use the
contracts-bedrock reference
or the source on
develop:
StandardBridge.sol,
CrossDomainMessenger.sol,
and OptimismPortal2.sol.
Deployed addresses for OP Mainnet and OP Sepolia are on the
contract addresses page.
If you concluded you need a custom bridge, read the
custom bridges guide and take
away the recommendation to extend StandardBridge rather than start from
scratch, and the requirement to register bridged tokens in the Superchain
Token List.
Step 3: Get the safety details right
Three properties of the deposit path surprise custom integrations. Check each against your design before writing code:- Address aliasing. When a contract (not an EOA) initiates a deposit,
the
fromaddress on L2 is the L1 contract’s address plus a constant offset. If your L2 contract checksmsg.senderagainst an L1 contract address, it must check the aliased form. Read address aliasing in the deposits spec and take away the offset constant and the reason it exists. The messenger abstracts this away; portal-direct integrations must handle it themselves. - Gas limits are minimums with real floors. The
minGasLimityou pass tosendMessageis a minimum for the L2 execution, and the portal enforces its own data-size-scaled minimum on every deposit (seeminimumGasLimitinOptimismPortal2.sol) plus a hard cap on deposit calldata size. The L1 gas burned to pay for L2 gas is dynamic, so follow the fee guidance in the messaging guide and take away the recommendation to buffer your gas limit by at least 20%. - Sender authentication. On the receiving side,
msg.senderis the L2 messenger, not your L1 contract. Read accessing msg.sender and take away thexDomainMessageSendercheck pattern. Portal-direct deposits do not get this: the L2 target sees only the (aliased)from.
Step 4: Build against the pattern
Each entry layer has a worked, runnable path. Follow the one matching your Step 2 decision; each is a tutorial, so it includes environment setup this guide skips:- Standard Bridge with a custom token: follow
Bridging your custom ERC-20 token
to deploy an
OptimismMintableERC20variant with custom logic. - Messenger-based contract calls: follow Communicating between contracts on L1 and L2 for the full send, relay, and authenticate loop in Solidity.
- Portal-direct deposits: there is no dedicated tutorial; work from the
depositTransactioninterface inOptimismPortal2.soland the deposits spec, and keep Step 3’s aliasing and gas rules in front of you.
Step 5: Test the flow locally
Deposits cross two chains, so test against a local multi-chain environment before testnet. Follow the supersim deposit transactions tutorial and take away how supersim surfaces theOptimismPortal,
L1CrossDomainMessenger, and L1StandardBridge addresses for each local
chain, and how to watch a deposit land on the L2 without running a full
derivation pipeline.
Step 6: Plan for failed deposits
An L2 execution can fail (usually out-of-gas), and your design must decide in advance who notices and who pays for the retry:
For the messenger path, follow the
replaying a failed deposit tutorial
and take away how a failed message is detected and the replay call that
retries it with more gas.
Step 7: Verify the outcome
Run your flow end to end on testnet and confirm each link of the chain:- The L1 side: your transaction emits a
TransactionDepositedevent from theOptimismPortal(directly or via the messenger). This event is the canonical proof the deposit entered the system. - The L2 side: the corresponding L2 transaction appears within a few
minutes, and the target contract observed the sender it expected
(
xDomainMessageSenderfor messenger flows, the aliased address for portal-direct flows). - The failure drill (messenger flows): force one deposit to fail with an
undersized
minGasLimit, confirm it is recorded as a failed message, and replay it successfully per Step 6. - Token accounting (bridge flows): amounts locked on L1 match amounts minted on L2, and the round trip back burns and releases correctly.
Next steps
- Deposits in the protocol specs: the normative definition of deposited transactions, the deposit contract, and address aliasing.
- contracts-bedrock reference: generated interface documentation for the current contracts, for when you need the exact function and event signatures.
OptimismPortal2.solon develop: the deposit entry point’s source, includingminimumGasLimitand the calldata cap. Tracks thedevelopbranch, so read it alongside the release your chain actually runs.- Superchain Token List: where custom-bridged tokens must be registered before users can find them.