Unichain Docs

Submitting Transactions from L1

Guide to Submitting Transactions from L1

Withdrawing ETH via L1 Transaction

Initiating an L2 withdrawal from L1 on the OP Stack is a 3 step process:

  1. Initiate the Withdrawal on L2 (either via an L1 deposit transaction or direct to L2 transaction)
  2. Relay the Withdrawal to L1
    1. This can be done after the Withdrawal has occurred on L2 and a proposer has proposed an output on L1.
    2. This step can take place up to 1 hour after the withdrawal has been initiated on L2
  3. Finalize the Withdrawal on L1
    1. This step can be done no sooner than 7 days after the withdrawal has been relayed due to the fault challenge period of 7 days inherent in the OP stack.

Unichain Contract Addresses

PORTAL_ADDR=0x0bd48f6B86a26D3a217d0Fa6FfE2B491B956A7a2
DGF_ADDRESS=0x2F12d621a16e2d3285929C9996f478508951dFe4

Initiating a withdrawal from L1

Via the command line, call the Optimism Portal Proxy on L1 to create an L2 deposit transaction. The L2 transaction will send the ETH to the L2ToL1Messenger contract to initiate a withdrawal. You can withdraw up to your total balance on L2 (use cast balance $ADDR -r $L2_RPC_URL to get your ETH balance on L2).

cast send $PORTAL_ADDR \
    "depositTransaction(address _to, uint256 _value, uint64 _gasLimit,bool _isCreation,bytes memory _data)" \
    0x4200000000000000000000000000000000000016 \
    $AMOUNT_IN_WEI_TO_WITHDRAW \
    300000 \
    false \
    0x --private-key=$PK

After your deposit has landed on L1, determine your L2 transaction hash:

Check out https://github.com/ethereum-optimism/optimism
Go to the op-chain-ops/cmd folder

Run the following command to get your L2 deposit tx hash
go run ./deposit-hash -rpc https://eth.merkle.io -tx $L1_DEPOSIT_TX_HASH

Relaying the Withdrawal from L2 to L1

This step initiates your withdrawal on L1. This step requires a proposer to have proposed an output which includes your withdrawal. Proposals occur about once every hour.

Checkout https://github.com/base-org/withdrawer and the run the following

export L2_TX_HASH=... # Take from the deposit-hash command
export L1_RPC=https://eth.merkle.io
export L2_RPC=https://mainnet-readonly.unichain.org
PORTAL_ADDR=0x0bd48f6B86a26D3a217d0Fa6FfE2B491B956A7a2
DGF_ADDRESS=0x2F12d621a16e2d3285929C9996f478508951dFe4
export PK=... # L1 private key. Can also use a ledger.

go run main.go --withdrawal $L2_TX_HASH --rpc=$L1_RPC --fault-proofs --l2-rpc=$L2_RPC --portal-address=$PORTAL_ADDR --dfg-address=$DGF_ADDRESS --private-key=$PK --network=op-mainnet

Finalizing the L1 Withdrawal

After 7 days, run the withdrawer command again to finalize the withdrawal.

Checkout https://github.com/base-org/withdrawer and the run the following command

export L2_TX_HASH=... # Take from the deposit-hash command
export L1_RPC=https://eth.merkle.io
export L2_RPC=https://mainnet-readonly.unichain.org
PORTAL_ADDR=0x0bd48f6B86a26D3a217d0Fa6FfE2B491B956A7a2
DGF_ADDRESS=0x2F12d621a16e2d3285929C9996f478508951dFe4
export PK=... # L1 private key. Can also use a ledger.

go run main.go --withdrawal $L2_TX_HASH --rpc=$L1_RPC --fault-proofs --l2-rpc=$L2_RPC --portal-address=$PORTAL_ADDR --dfg-address=$DGF_ADDRESS --private-key=$PK --network=op-mainnet

Submitting Arbitrary Transactions from L1

You can perform arbitrary contract calls (e.g., swaps) on L2 via deposit transactions. To create a deposit transaction on L2, call the Optimism Portal Proxy Contract:

cast send $PORTAL_ADDR \
    "depositTransaction(address _to, uint256 _value, uint64 _gasLimit,bool _isCreation,bytes memory _data)" \
    $TO $VALUE $GAS_LIMIT false $CALLDATA \
    --rpc-url $L1_RPC_URL \
    --private-key # or other cast wallet options

For example, to perform a swap on a fork of a Uniswap V2 pool on L2 using this method you can:

  1. Use the Uniswap V2 SDK to generate the required calldata for the swap (see docs here

    )

  2. Submit the calldata from step 1, to the $DEX_ADDRESS of the V2 fork:

    cast send $PORTAL_ADDR \
        "depositTransaction(address _to, uint256 _value, uint64 _gasLimit,bool _isCreation,bytes memory _data)" \
        $DEX_ADDRESS \
        0 \
        $GAS_LIMIT \
        false \
        $CALLDATA \
        --rpc-url $L1_RPC_URL \
        --private-key # or other cast wallet options
  3. If you use this method to swap back into ETH on the L2, you can withdraw the resulting ETH using the methods outlined above.

Last updated on

On this page