> ## Documentation Index
> Fetch the complete documentation index at: https://docs.layerzero.network/llms.txt
> Use this file to discover all available pages before exploring further.

# Migrating from V1 to V2

> Migration options exist for deployed LayerZero V1 applications looking to take advantage of LayerZero. LayerZero enables secure crosschain messaging.

Migration options exist for deployed LayerZero V1 applications looking to take advantage of LayerZero V2.

## Deployed Apps on `Endpoint V1`

If you have already deployed on Endpoint V1, migrating to the new LayerZero V2 protocol is entirely **optional**.

LayerZero V2 comes with enhancements to the core protocol design that increase message efficiency and customizability.

You can access the new [Security Stack](../concepts/modular-security/security-stack-dvns) and [Independent Execution](../concepts/permissionless-execution/executors) by configuring your application's Message Library to **Ultra Light Node 301**.

With UltraLightNode301, your deployed `LZApp` on Endpoint V1 will be able to configure the new Security Stack for message authentication, as well as an Executor to ensure your application receives messages on the destination chain.

### Prerequisites

You should have an LZApp to start with that's already working with default settings. Any app that inherits `LZApp.sol` (including the Endpoint V1 OFT and ONFT standards) can be used.

## Migration Steps

### Temporarily block sending new messages

As messages require symmetrical Message Libraries on send and receive, updating the Receive Message Library while there are still in-flight messages sent using another version would result in those messages failing to deliver. To mitigate this, you would need to temporarily block new messages from being sent. This can be done by setting the Send Library to the [Blocked Message Library](https://github.com/LayerZero-Labs/LayerZero-v2/blob/c09287a8b1f236fcc057f474d8a773a0fb7758df/packages/layerzero-v2/evm/messagelib/test/mocks/EndpointV1.sol#L15) (`65535`) on all chains in your mesh.

```typescript wrap theme={null}
const BLOCK_VERSION = 65535;
const blockTx = await oappContract.setSendVersion(BLOCK_VERSION);
await blockTx.wait();
```

Then, wait for all in-flight messages to be delivered. You can monitor using [LayerZero Scan](https://layerzeroscan.com/). Paste your OApp address into the search bar to display all messages for the pathway involving that OApp. Once all messages are delivered, you can proceed with migrating the Message Libraries to ULN301.

### Configuring UltraLightNode301

To set a new MessageLib on Endpoint V1, you will call the `setConfig` function on Chain A and Chain B.

Below is a simple example for how to set your MessageLib:

```solidity wrap theme={null}
// @dev function to set your LZApp's send MessageLib
function setSendVersion(uint16 _version) external override onlyOwner {
        lzEndpoint.setSendVersion(_version);
}

// @dev function to set your LZApp's receive MessageLib
function setReceiveVersion(uint16 _version) external override onlyOwner {
        lzEndpoint.setReceiveVersion(_version);
}
```

To find the specific Send/Receive version for a given chain, call the `latestVersion` variable on the chain's endpoint contract.

```javascript wrap theme={null}
const latestVersion = await endpointContract.latestVersion();
```

The `latestVersion` represents the index of the last MessageLib that was appended to the chain's endpoint, which currently is **ReceiveULN301** for all endpoints, while **SendULN301** is the index before **ReceiveULN301**.

```javascript wrap theme={null}
const receiveUln301Version = latestVersion;
const sendUln301Version = latestVersion - 1;
```

Finally, you can use the respective Send/Receive versions to set your OApp to UltraLightNode301:

```javascript wrap theme={null}
const sendTx = await oappContract.setSendVersion(sendUln301Version);
await sendTx.wait();

const receiveTx = await oappContract.setReceiveVersion(receiveUln301Version);
await receiveTx.wait();
```

After setting your libraries to the new **UltraLightNode301**, you can configure your `LZApp` using the Endpoint V1 `setConfig` function, passing the `configType` and `config` values for the specific [Security Stack](../developers/evm/configuration/dvn-executor-config#setting-custom-send-config-dvn-executor) and [Executors](../developers/evm/configuration/dvn-executor-config#setting-custom-send-config-dvn-executor).

<br />

```solidity wrap theme={null}
function setConfig(
    uint16 _version,
    uint16 _chainId,
    // highlight-start
    uint _configType,
    bytes calldata _config
    // highlight-end
) external override onlyOwner {
    lzEndpoint.setConfig(_version, _chainId, _configType, _config);
}
```

With `UltraLightNode301`, your deployed `LZApp` on Endpoint V1 will be able to configure the new Security Stack for message authentication, as well as an Executor to ensure your application receives messages on the destination chain.

This enables a wider range of security configurations while simultaneously isolating network liveness from message execution.

See the full list of improvements for **Deployed V1 Apps** in the [V2 Overview](/v2).

## New Apps on `Endpoint V2`

For new applications deciding between Endpoint V1 and Endpoint V2, we recommend deploying exclusively with V2 Contracts to take advantage of onchain specific benefits (*i.e., higher message throughput, smaller contract sizes, gas optimization, and horizontal message composability*).

You will need to deploy using the new [Contract Standards](../concepts/protocol/contract-standards) on Endpoint V2.

<Info>
  These benefits specifically come from improvements in onchain protocol and application related contracts. For your application to receive these specific benefits, you will need to deploy new OApps using these contracts. See the full overview in [**New Protocol Contracts**](/v2).
</Info>
