# Token Bridge

The ability to send cross layer messages trustlessly between L1 and L2 can be leveraged to build a token bridge to move assets from L1 to L2 and back. Goshen provide a standard bridge for Ether and ERC20 tokens.

### Deposit Ether

To move Ether from L1 to L2, you can send a deposit transaction via `depositETH` or `depositETHTo` of `L1StandardBridge` contract. This will transfer the funds to the `L1StandardBridge` contract and will send a cross layer message to `L2StandardBridge` contract deployed on L2 to mint the same amount of funds to the specified address.

```javascript
/**
 * @dev Deposit an amount of the ETH to the caller's balance on L2.
 * @param _data Optional data to forward to L2. This data is provided
 *        solely as a convenience for external contracts. Aside from enforcing a maximum
 *        length, these contracts provide no guarantees about its content.
 */
function depositETH(bytes calldata _data) external payable;

/**
 * @dev Deposit an amount of ETH to a recipient's balance on L2.
 * @param _to L2 address to credit the withdrawal to.
 * @param _data Optional data to forward to L2. This data is provided
 *        solely as a convenience for external contracts. Aside from enforcing a maximum
 *        length, these contracts provide no guarantees about its content.
 */
function depositETHTo(address _to, bytes calldata _data) external payable;
```

### Withdraw Ether

To withdraw Ether from L2 to L1, you can send a withdraw transaction via `withdrawETH` or `withdrawETHTo` of `L2StandardBridge` contract. This will transfer the funds to the `L2StandardBridge` contract and will send a cross layer message to `L1StandardBridge` contract to transfer the same amount of funds to the specified address.

```javascript
function withdrawETH(bytes calldata _data) external payable onlyEOA ;
function withdrawETHTo(address _to, bytes calldata _data) external payable;
```

### Deposit ERC20 tokens

To move a ERC20 token from L1 to L2, you can send a deposit transaction via `depositERC20` or `depositERC20To` of `L1StandardBridge` contract. This will transfer the funds to the `L1StandardBridge` contract and will send a cross layer message to `L2StandardBridge` contract deployed on L2 to mint the same amount of funds to the specified address.

```javascript
/**
 * @dev deposit an amount of the ERC20 to the caller's balance on L2.
 * @param _l1Token Address of the L1 ERC20 we are depositing
 * @param _l2Token Address of the L1 respective L2 ERC20
 * @param _amount Amount of the ERC20 to deposit
 * @param _data Optional data to forward to L2. This data is provided
 *        solely as a convenience for external contracts. Aside from enforcing a maximum
 *        length, these contracts provide no guarantees about its content.
 */java
function depositERC20(
    address _l1Token,
    address _l2Token,
    uint256 _amount,
    bytes calldata _data
) external;

/**
 * @dev deposit an amount of ERC20 to a recipient's balance on L2.
 * @param _l1Token Address of the L1 ERC20 we are depositing
 * @param _l2Token Address of the L1 respective L2 ERC20
 * @param _to L2 address to credit the withdrawal to.
 * @param _amount Amount of the ERC20 to deposit.
 * @param _data Optional data to forward to L2. This data is provided
 *        solely as a convenience for external contracts. Aside from enforcing a maximum
 *        length, these contracts provide no guarantees about its content.
 */
function depositERC20To(
    address _l1Token,
    address _l2Token,
    address _to,
    uint256 _amount,
    bytes calldata _data
) external;
```

### Withdraw ERC20 tokens

To withdraw a ERC20 token from L2 to L1, you can send a withdraw transaction via `withdraw` or `withdrawTo` of `L2StandardBridge` contract. This will transfer the funds to the `L2StandardBridge` contract and will send a cross layer message to `L1StandardBridge` contract to transfer the same amount of funds to the specified address.

```javascript
/**
 * @dev initiate a withdraw of some tokens to the caller's account on L1
 * @param _l2Token Address of L2 token where withdrawal was initiated.
 * @param _amount Amount of the token to withdraw.
 * @param _data Optional data to forward to L1. This data is provided
 *        solely as a convenience for external contracts. Aside from enforcing a maximum
 *        length, these contracts provide no guarantees about its content.
 */
function withdraw(
    address _l2Token,
    uint256 _amount,
    bytes calldata _data
) external;

/**
 * @dev initiate a withdraw of some token to a recipient's account on L1.
 * @param _l2Token Address of L2 token where withdrawal is initiated.
 * @param _to L1 adress to credit the withdrawal to.
 * @param _amount Amount of the token to withdraw.
 * @param _data Optional data to forward to L1. This data is provided
 *        solely as a convenience for external contracts. Aside from enforcing a maximum
 *        length, these contracts provide no guarantees about its content.
 */
function withdrawTo(
    address _l2Token,
    address _to,
    uint256 _amount,
    bytes calldata _data
) external;
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.goshen.network/advanced/cross-layer-interoperability/token-bridge.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
