> For the complete documentation index, see [llms.txt](https://docs.chiliz.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.chiliz.com/vi/phat-trien/nang-cao/su-dung-omnichain-tokens/bridge-tu-chiliz-sang-solana.md).

# Bridge từ Chiliz Chain sang Solana

Để bridge một token hiện có từ Chiliz Chain sang Solana, bạn cần viết và triển khai hai smart contract riêng biệt: một OFT Adapter trên chain mà token đã tồn tại (Chiliz Chain), và một Native OFT trên chain đích (Solana).

*Lưu ý rằng LayerZero cung cấp QuickStart riêng cho các hợp đồng OFT:*

{% embed url="<https://docs.layerzero.network/v2/developers/evm/oft/quickstart>" %}

## Điều kiện tiên quyết

{% hint style="info" %}
Bridge từ Chiliz Chain (EVM) sang Solana (Non-EVM) đòi hỏi phát triển song song trên hai hệ sinh thái.\
Bạn sẽ cần thiết lập môi trường và ví cho cả hai hệ sinh thái.

Do đó, bạn cần các môi trường sau:

* Để tương tác với Chiliz Chain: Node/npx và Hardhat.
* Để tương tác với Solana: [Rustup](https://rustup.rs/) (smart contract trên Solana sử dụng ngôn ngữ lập trình Rust), [Solana CLI và Anchor framework](https://solana.com/docs/intro/installation), và [LayerZero's Solana SDK](https://docs.layerzero.network/v2/tools/sdks/solana-sdk).
  {% endhint %}

Hướng dẫn này yêu cầu những điều sau:

* Địa chỉ hợp đồng token trên Chiliz Chain. Bạn không cần phải sở hữu nó.
* Một ví Web3 cho mỗi chain (MetaMask không hỗ trợ các chain non-EVM):
  * Đối với Chiliz Chain: ví MetaMask với [cấu hình Chiliz Chain RPC](/vi/phat-trien/co-ban/ket-noi-voi-chiliz-chain/ket-noi-bang-rpc.md).
  * Đối với Solana: ví [Solflare](https://www.solflare.com/) với [cấu hình Solana Mainnet](https://solana.com/docs/references/clusters). Đây là [hướng dẫn thiết lập của họ](https://www.solflare.com/guides/how-to-set-up-your-first-crypto-wallet-with-solflare-step-by-step/).
* Đủ token gas trên mỗi chain để trả phí triển khai hợp đồng cũng như gas fee cho việc gửi tin nhắn.
  * Trên Chiliz Chain: token CHZ.
  * Trên Solana: token SOL.

## Bước 1: Phát triển hợp đồng

{% hint style="info" %}
**Thách thức về "Shared Decimals"**

Vì Solana xử lý toán học token khác với Ethereum Virtual Machine (EVM), chúng ta phải xử lý số thập phân đúng cách:

* Chiliz Chain (EVM): Các token ERC-20 tiêu chuẩn thường có 18 chữ số thập phân.
* Solana: Các SPL Token gốc thường có 9 chữ số thập phân.

Nếu bạn gửi $$ $1 \times 10^{18}$ $$ đơn vị từ Chiliz sang Solana, hợp đồng Solana sẽ hiểu sai số lượng, dẫn đến lạm phát lớn của token trên chain đích.

Để chuẩn hóa phép tính, LayerZero sử dụng cấu hình `sharedDecimals`. Theo mặc định, tiêu chuẩn LayerZero V2 OFT đặt `sharedDecimals` là 6.

* Khi người dùng bridge 1,00 token từ Chiliz, Adapter loại bỏ 12 chữ số thập phân thấp nhất (coi chúng là "bụi") để thu nhỏ số xuống còn 6 chữ số thập phân.
* Tin nhắn được gửi qua bridge.
* Chương trình Solana nhận số 6 chữ số thập phân và mở rộng *lên* đến 9 chữ số thập phân cục bộ trước khi đúc.

[Tìm hiểu thêm tại đây](https://docs.layerzero.network/v2/faq#what-is-shareddecimals-can-i-override-default-shareddecimals-in-an-oft-contract).
{% endhint %}

### Chuẩn bị `OFTAdapter` trên Chiliz Chain

{% hint style="warning" %}
Đây là bước chuẩn bị, chưa triển khai ngay!\
Bạn sẽ triển khai ở Bước 3.
{% endhint %}

Hợp đồng `OFTAdapter` hoạt động như một két khóa cho token hiện có của bạn. Khi người dùng bridge token của họ rời khỏi Chiliz Chain, hợp đồng này sẽ khóa các token ERC20 gốc.

{% hint style="info" %}
Vì `OFTAdapter` của LayerZero đặt `sharedDecimals` mặc định là 6, bạn có thể sử dụng triển khai tiêu chuẩn. Nếu bạn cần thay đổi điều này (ví dụ: thành 8), bạn sẽ ghi đè hàm `sharedDecimals()`.
{% endhint %}

Tạo một file mới tên `ChilizTokenAdapter.sol` trong thư mục contracts của bạn:

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;

import { OFTAdapter } from "@layerzerolabs/lz-evm-oapp-v2/contracts/oft/OFTAdapter.sol";
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";

contract ChilizSolanaAdapter is OFTAdapter {
    constructor(
        address _token,      // The address of your EXISTING Token on Chiliz Chain (18 decimals)
        address _lzEndpoint, // The LayerZero V2 Endpoint address on Chiliz
        address _delegate    // The address capable of making configuration changes ( (usually your wallet)
    ) OFTAdapter(_token, _lzEndpoint, _delegate) Ownable(_delegate) {}
}
```

{% hint style="info" %}
Như bạn thấy, hợp đồng này kế thừa [hợp đồng LayerZero OFT Adapter](https://github.com/LayerZero-Labs/LayerZero-v2/blob/main/packages/layerzero-v2/evm/oapp/contracts/oft/OFTAdapter.sol), cũng như hợp đồng `Ownable.sol` tiêu chuẩn để cấp quyền quản trị. Bạn cần cả hai để chỉ bạn, và chỉ bạn, có thể kết nối các chain một cách an toàn.
{% endhint %}

### Chuẩn bị và triển khai `OFT` trên Solana

Không giống Chiliz Chain, Solana không sử dụng Ethereum Virtual Machine (EVM) hoặc ngôn ngữ Solidity. Các smart contract trên Solana (được gọi là "Programs") được viết bằng [Rust](https://rust-lang.org/).

Để bridge token của bạn, bạn cần triển khai một OFT program trên Solana. Khi program này nhận được tin nhắn đã xác minh từ OFTAdapter được triển khai trên Chiliz của bạn, nó sẽ đúc SPL token tương ứng vào ví Solana của người dùng.

{% embed url="<https://docs.layerzero.network/v2/developers/solana/oft/overview>" %}

LayerZero cung cấp một [ví dụ Anchor sẵn sàng sử dụng](https://github.com/LayerZero-Labs/devtools/tree/main/examples/oft-solana) để bạn không cần phải viết logic bridge Rust từ đầu.

#### 1. Clone ví dụ LayerZero OFT Solana:

```bash
git clone https://github.com/LayerZero-Labs/devtools.git
cd devtools/examples/oft-solana
npm install
```

#### 2. Build chương trình Rust

Thao tác này cũng sẽ tạo ra Program ID Solana duy nhất của bạn (tương đương với địa chỉ hợp đồng trong EVM):

```bash
anchor build
```

Sau khi build hoàn tất, Anchor sẽ tạo một keypair mới tại `target/deploy/oft_solana-keypair.json`.\
Bạn có thể lấy Program ID mới bằng cách chạy:

```bash
anchor keys list
```

#### 3. Triển khai lên Solana Mainnet

Đảm bảo rằng Solana CLI của bạn được cấu hình cho Mainnet và ví cục bộ của bạn có đủ $SOL cho việc triển khai và phí thuê lưu trữ.\
Đừng quên cập nhật file `Anchor.toml` và macro `lib.rs` declare\_id! với Program ID mới này trước khi triển khai.

```bash
solana config set --url mainnet-beta
anchor deploy
```

#### 4. Khởi tạo OFT và SPL Mint

Trên Solana, logic của token và sổ cái của nó được tách biệt. Bạn phải khởi tạo một Mint Account mới (SPL Token) và chỉ định OFT Program mới triển khai của bạn là Mint Authority. Điều này đảm bảo chỉ có LayerZero bridge mới có thể đúc token mới trên Solana.

LayerZero SDK cung cấp các Hardhat/TypeScript task để xử lý việc khởi tạo này trực tiếp từ dòng lệnh. Trong dự án `oft-solana` của bạn, cấu hình LayerZero Endpoint cho Solana (`30168`) và chạy script khởi tạo:

{% code overflow="wrap" lineNumbers="true" %}

```bash
npx hardhat lz:oft-solana:init --program-id <YOUR_NEW_PROGRAM_ID> --mint-decimals 9 --shared-decimals 6
```

{% endcode %}

{% hint style="info" %}
Các tham số quan trọng:

* `--mint-decimals 9`: Đặt độ chính xác token SPL tiêu chuẩn trên Solana.
* `--shared-decimals 6`: Phải khớp với shared decimals bạn đã cấu hình (hoặc mặc định) trên `OFTAdapter` Chiliz Chain của bạn. Đây là điều đảm bảo 1 token Chiliz = 1 token Solana.
  {% endhint %}

Khi giao dịch khởi tạo này được xác nhận trên blockchain Solana, OFT program gốc của bạn đã được thiết lập đầy đủ và sẵn sàng kết nối với Chiliz OFTAdapter!

## Bước 2: Cấu hình LayerZero

Với Chiliz Adapter đã triển khai và OFT program Solana đã khởi tạo, bạn phải cấu hình kết nối giữa chúng. Đây là nơi sự khác biệt giữa mạng EVM và non-EVM trở nên rõ ràng nhất.

{% hint style="info" %}
Định dạng địa chỉ:

* Chiliz Chain (EVM): Sử dụng địa chỉ hexadecimal 20 byte tiêu chuẩn (ví dụ: `0x123...`).
* Solana: Sử dụng địa chỉ được mã hóa Base58 (ví dụ: `YourProgramId111111111111111111111111111111`).
  {% endhint %}

Tin nhắn cross-chain của LayerZero yêu cầu tất cả [địa chỉ peer](https://docs.layerzero.network/v2/concepts/glossary#peer) phải được định dạng dưới dạng `bytes32`. May mắn thay, công cụ LayerZero V2 Hardhat tự động xử lý việc chuyển đổi Base58 sang Bytes32 cho bạn, miễn là bạn định nghĩa các endpoint chính xác trong cấu hình.

[Simple Config Generator](https://docs.layerzero.network/v2/tools/simple-config) là cách được khuyến nghị để tạo cấu hình kết nối, vì nó tự động hóa việc kết nối hai chiều và áp dụng các cấu hình bảo mật được khuyến nghị bên dưới.

Tạo hoặc cập nhật file `layerzero.config.ts` trong thư mục gốc của dự án Hardhat của bạn:

{% code lineNumbers="true" %}

```typescript
import { ExecutorOptionType } from '@layerzerolabs/lz-v2-utilities';
import { OAppEnforcedOption, OmniPointHardhat } from '@layerzerolabs/toolbox-hardhat';
import { EndpointId } from '@layerzerolabs/lz-definitions';
import { generateConnectionsConfig } from '@layerzerolabs/metadata-tools';

// Define the Contracts
const chilizContract: OmniPointHardhat = {
    eid: EndpointId.CHILIZ_V2_MAINNET,
    contractName: 'ChilizSolanaAdapter', // Your Hardhat deployment name on EVM
};

const solanaContract: OmniPointHardhat = {
    eid: EndpointId.SOLANA_V2_MAINNET,
    address: 'YourSolanaProgramIdHereInBase58', // Base58 address format for Solana
};

// Define Execution Options for Solana (Compute Units & Lamports)
const SOLANA_ENFORCED_OPTIONS: OAppEnforcedOption[] = [
    {
        msgType: 1,
        optionType: ExecutorOptionType.LZ_RECEIVE,
        gas: 200000,    // Solana Compute Units needed for destination execution
        value: 2500000, // Lamports to cover the potential ATA creation rent fee
    },
];

// Define Execution Options for the return trip to Chiliz (EVM Gas)
const EVM_ENFORCED_OPTIONS: OAppEnforcedOption[] = [
    {
        msgType: 1, 
        optionType: ExecutorOptionType.LZ_RECEIVE,
        gas: 200000, // Standard EVM gas units to unlock tokens on Chiliz
        value: 0,
    },
];

// Export the Generated Configuration
export default async function () {
    return {
        contracts: [
            { contract: chilizContract },
            { contract: solanaContract },
        ],
        connections: await generateConnectionsConfig([
            [
                chilizContract, 
                solanaContract,
                [['LayerZero Labs'], []], 
                [1, 1], 
                [SOLANA_ENFORCED_OPTIONS, EVM_ENFORCED_OPTIONS], // Options [To Solana SVM, To Chiliz EVM]
            ],
        ]),
    };
}
```

{% endcode %}

LayerZero wire task sẽ đọc điều này, giải mã chuỗi Base58, đệm nó thành 32 byte, và truyền an toàn vào hàm `setPeer` của Chiliz OFTAdapter.

## Bước 3: Quy trình triển khai

Với các hợp đồng đã viết và `layerzero.config.ts` đã chuẩn bị, đã đến lúc triển khai Chiliz OFTAdapter. Vì bạn đã build và triển khai Solana native OFT program bằng Anchor ở Bước 1, bước này tập trung vào việc triển khai phía EVM của bridge bằng Hardhat.

### **Triển khai hợp đồng Chiliz OFTAdapter**

Trong dự án Hardhat của bạn, tạo một script triển khai trong thư mục `deploy/` của bạn tên `01_deploy_chiliz_solana_adapter.ts`. Script này truyền địa chỉ token hiện có của bạn và địa chỉ Chiliz Endpoint V2 (EID) vào constructor.

{% code overflow="wrap" lineNumbers="true" %}

```typescript
import { DeployFunction } from 'hardhat-deploy/types';

const deployAdapter: DeployFunction = async ({ getNamedAccounts, deployments }) => {
    const { deploy } = deployments;
    const { deployer } = await getNamedAccounts();

    // The address of your existing ERC-20 token on Chiliz (18 decimals)
    const TOKEN_ADDRESS = "0xYourTokenAddressHere"; 
    
    // The Chiliz Mainnet Endpoint V2 Address
    const CHILIZ_ENDPOINT_V2 = "0x6F475642a6e85809B1c36Fa62763669b1b48DD5B";

    console.log("Deploying OFTAdapter to Chiliz Mainnet...");

    await deploy('ChilizSolanaAdapter', {
        from: deployer,
        args: [
            TOKEN_ADDRESS,       // _token
            CHILIZ_ENDPOINT_V2,  // _lzEndpoint
            deployer             // _delegate (Owner)
        ],
        log: true,
        waitConfirmations: 2,
    });
};

export default deployAdapter;
deployAdapter.tags = ['ChilizSolanaAdapter'];
```

{% endcode %}

### **Triển khai Chiliz OFTAdapter**

{% hint style="info" %}
Trước khi tiến hành, hãy đảm bảo rằng:

* bạn đã sao chép Program ID Base58 kết quả vào file `layerzero.config.ts` của mình.
* `hardhat.config.ts` của bạn có URL RPC và private key được cấu hình đúng cho Chiliz Chain Mainnet.
  {% endhint %}

Chạy lệnh sau trong terminal của bạn để triển khai EVM Adapter:

{% code overflow="wrap" lineNumbers="true" %}

```bash
npx hardhat deploy --network chiliz --tags ChilizSolanaAdapter
```

{% endcode %}

Sau khi triển khai hoàn tất, Hardhat sẽ lưu địa chỉ hợp đồng Chiliz trong thư mục `deployments/`.

Tại thời điểm này, bạn có các hợp đồng đang hoạt động trên cả Chiliz Chain (EVM) và Solana (SVM), nhưng chúng chưa tin tưởng lẫn nhau. Đã đến lúc kết nối chúng!

## Bước 4: Kết nối & Peering

Để cho phép hợp đồng OFTAdapter và OFT program của bạn giao tiếp, bạn phải "kết nối" chúng như các peer đáng tin cậy.

Vì chúng ta đang bridge qua hai Virtual Machine hoàn toàn khác nhau (EVM và SVM), việc cấu hình đòi hỏi sự chú ý đặc biệt.

{% hint style="info" %}
**EVM gas so với Solana compute units**

Khi người dùng bridge token từ Chiliz Chain sang một chain EVM khác (như Base), LayerZero Executor cần EVM gas để gọi `lzReceive`.

Tuy nhiên, khi bridge từ Chiliz Chain sang Solana, chain đích không sử dụng EVM gas. [Nó sử dụng Compute Units và Lamports (phần nhỏ của $SOL)](https://solana.com/docs/core/fees).\
Hơn nữa, nếu người dùng bridge token đến ví Solana chưa giữ token của bạn, Executor phải trả phí "rent exemption" của Solana để tạo Associated Token Account (ATA) cho họ. Điều này yêu cầu thả giá trị $SOL thực tế tại đích.
{% endhint %}

Để đảm bảo Executor có đủ Compute Units và Lamports để đúc token và tạo ATA trên Solana, bạn phải định nghĩa các giới hạn này trong file `layerzero.config.ts` của mình *trước khi* kết nối.

Chạy lệnh kết nối tự động trong terminal của bạn:

{% code lineNumbers="true" %}

```bash
npx hardhat lz:oapp:wire --oapp-config layerzero.config.ts
```

{% endcode %}

Thao tác này sẽ chuẩn bị 6 giao dịch cấu hình cần thiết:

1. `setSendLibrary`: Chỉ định MessageLib cho các gói tin đi ra.
2. `setReceiveLibrary`: Chỉ định MessageLib cho các gói tin đến.
3. `setConfig`: Cấu hình DVN và Executor.
4. `setConfig`: Cấu hình DVN cho xác minh đến.
5. `setEnforcedOptions`: Đảm bảo các tham số thực thi nhất quán (quan trọng để đảm bảo người dùng trả đủ tiền trước để bao gồm Solana Compute Units và Lamport rent).
6. `setPeer`: Liên kết Solana EID với Program ID Base58 đích của bạn.

LayerZero V2 toolbox tự động hóa phần nặng nhọc: nó sẽ giải mã địa chỉ Solana Base58, đệm nó thành định dạng EVM `bytes32` cần thiết, và gửi các giao dịch `setPeer` và `setEnforcedOptions` đến cả hai chain.

Khi các giao dịch kết nối được xác nhận, bridge EVM-to-Solana của bạn đã hoạt động và được phân quyền bảo mật.

Token của bạn chính thức sẵn sàng vượt qua ranh giới EVM/SVM!

## Bước 5: Vận hành & Kiểm thử

Với Chiliz Adapter đã triển khai, Solana Native OFT đã khởi tạo, và hai bên được kết nối đúng cách, token của bạn chính thức sẵn sàng vượt qua ranh giới EVM/SVM. Bước cuối cùng là thực hiện và theo dõi một giao dịch chuyển nhượng thử nghiệm từ Chiliz Chain sang Solana.

### 1) Gửi tin nhắn Cross-Chain đến Solana

LayerZero V2 toolbox bao gồm một Hardhat task để gửi các OFT transfer trực tiếp từ dòng lệnh.

Không giống như các transfer EVM-to-EVM nơi đích đến của bạn là một chuỗi hexadecimal tiêu chuẩn, đích đến ở đây là địa chỉ ví Solana Base58. LayerZero CLI xử lý việc chuyển đổi Base58 sang Bytes32 cho payload tin nhắn tự động.

Chạy lệnh sau trong terminal của bạn:

{% code overflow="wrap" lineNumbers="true" %}

```bash
npx hardhat lz:oft:send --oapp-config layerzero.config.ts --from-eid 30409 --to-eid 30168 --to <YOUR_SOLANA_WALLET_ADDRESS_BASE58> --amount 10
```

{% endcode %}

{% hint style="info" %}
Điều gì xảy ra ở đây?

1. Script báo giá phí cross-chain bằng $CHZ (bao gồm EVM gas, phí mạng verifier, và phí đích Solana).
2. Nó gọi hàm `send()` trên Chiliz Adapter của bạn.
3. Adapter khóa 10 token (18 chữ số thập phân). Nó loại bỏ 12 chữ số thập phân thấp nhất dưới dạng "bụi" (để chúng trong ví Chiliz của bạn) để thu nhỏ payload xuống còn 6 `sharedDecimals`.
4. LayerZero Endpoint phát gói tin về phía Solana Mainnet.
   {% endhint %}

### 2) Theo dõi gói tin trên LayerZero Scan

Vì bridge sang Solana liên quan đến việc dịch giữa hai cơ chế đồng thuận hoàn toàn khác nhau và chờ SVM finality, một độ trễ bất đồng bộ là bình thường.

Để theo dõi hành trình này theo thời gian thực, nhấp vào liên kết LayerZero Scan xuất hiện trong đầu ra CLI.

Tìm hiểu thêm về công cụ này tại đây:

{% embed url="<https://docs.layerzero.network/v2/developers/evm/tooling/layerzeroscan>" %}

{% hint style="info" %}

#### Dịch số thập phân

Solana Native OFT sẽ tự động mở rộng payload 6 chữ số thập phân đến từ bridge lên 9 chữ số thập phân SPL tiêu chuẩn, vì vậy ví Solana của bạn nhận chính xác 10 token đầy đủ.
{% endhint %}

**4) Xử lý các tin nhắn bị kẹt**

Nếu giao dịch của bạn được đánh dấu là đã xác nhận trên Chiliz nhưng không thực thi được trên Solana, nguyên nhân phổ biến nhất là lỗi Insufficient Lamports hoặc Compute Units.

* Nếu ví Solana đích chưa có Associated Token Account (ATA) cho token cụ thể của bạn, LayerZero Executor phải trả phí "rent exemption" của Solana để tạo nó.
* Nếu tham số `value` (Lamports) trong `enforcedOptions` của bạn được đặt quá thấp để bao gồm phí rent này, hoặc nếu `gas` (Compute Units) không đủ, Executor sẽ từ chối trả từ túi riêng, và tin nhắn sẽ bị dừng lại.
* Cách khắc phục: Bạn không mất token. Bạn có thể đẩy thủ công một tin nhắn bị kẹt thông qua giao diện LayerZero Scan UI. Kết nối ví Solana của bạn, nhấp vào nút "Force Resume" hoặc "Execute" trên block explorer, và tự trả phí đích cục bộ (Compute Units + ATA Rent bằng $SOL) để hoàn tất việc đúc.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://docs.chiliz.com/vi/phat-trien/nang-cao/su-dung-omnichain-tokens/bridge-tu-chiliz-sang-solana.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
