> 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-base-sang-chiliz.md).

# Bridge từ Base sang Chiliz Chain

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

{% hint style="info" %}
Lưu ý rằng LayerZero cung cấp [QuickStart riêng cho các hợp đồng OFT](https://docs.layerzero.network/v2/developers/evm/oft/quickstart), cũng như một hướng dẫn để học cách [đúc từ Base sang một chain EVM khác](https://docs.layerzero.network/v2/deployments/evm-chains/chiliz-mainnet-oft-quickstart) như Chiliz Chain. Hướng dẫn đó sử dụng Optimism làm chain đích, nhưng bạn có thể thay thế bằng [thông tin chi tiết của Chiliz Chain](https://docs.layerzero.network/v2/deployments/evm-chains/chiliz-mainnet-oft-quickstart).
{% endhint %}

## Yêu cầu trước khi bắt đầu

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

* Địa chỉ hợp đồng token ERC-20 trên Base.
* Một ví Web3 (chẳng hạn như MetaMask) được thiết lập để hoạt động với cả Base và Chiliz Chain.
  * [Xem tại đây để cấu hình RPC Base Mainnet](https://docs.base.org/base-chain/quickstart/connecting-to-base).
  * [Xem tại đây để cấu hình RPC Chiliz Chain](/vi/phat-trien/co-ban/ket-noi-voi-chiliz-chain/ket-noi-bang-rpc.md).
* Đủ token gas trên mỗi chain để thanh toán phí triển khai hợp đồng cũng như phí gas cho việc gửi tin nhắn.
  * Trên Base: token ETH.
  * Trên Chiliz Chain: token CHZ.

Chúng ta sẽ sử dụng [Hardhat](https://hardhat.org/) làm môi trường phát triển, cùng với Node/npx.

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

### Chuẩn bị `OFTAdapter` trên Base

{% 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` đóng vai trò 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ọ ra khỏi Base, hợp đồng này sẽ khóa các token ERC-20 gốc lại.

Tạo một file mới tên `BaseTokenAdapter.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 BaseTokenAdapter is OFTAdapter {
    constructor(
        address _token,      // The address of your EXISTING token on Base
        address _lzEndpoint, // The LayerZero V2 Endpoint address on Base
        address _delegate    // The address capable of making configuration changes (usually your wallet)
    ) OFTAdapter(_token, _lzEndpoint, _delegate) Ownable(_delegate) {}
}
```

{% hint style="info" %}
Như bạn có thể 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` chuẩn để cấp quyền quản trị. Bạn cần cả hai để chỉ mình bạn có thể kết nối các chain một cách an toàn.
{% endhint %}

Khi triển khai lên Base Mainnet, bạn phải truyền địa chỉ hợp đồng token hiện có của mình làm `_token` và địa chỉ Base Endpoint V2 (`0x1a44076050125825900e736c501f859c50fE728c`) làm `_lzEndpoint`.

Xem tất cả các endpoint có sẵn cho Chiliz Chain tại đây:

{% embed url="<https://docs.layerzero.network/v2/deployments/chains/base>" %}

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

Vì token chưa tồn tại trên Chiliz Chain, bạn phải triển khai một hợp đồng OFT chuẩn. Hợp đồng này có quyền đúc token mới khi nhận được tin nhắn hợp lệ từ OFT Adapter đã triển khai trên Base, và đốt chúng khi người dùng bridge ngược lại.

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

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

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

contract ChilizTokenOFT is OFT {
    constructor(
        string memory _name,   // The name of the token (Should match your Base token)
        string memory _symbol, // The symbol of the token (Should match your Base token)
        address _lzEndpoint,   // The LayerZero V2 Endpoint address on Chiliz Chain
        address _delegate      // The address capable of making configuration changes
    ) OFT(_name, _symbol, _lzEndpoint, _delegate) Ownable(_delegate) {}
}
```

{% hint style="info" %}
Như bạn có thể thấy, hợp đồng này kế thừa [hợp đồng LayerZero OFT](https://github.com/LayerZero-Labs/LayerZero-v2/blob/main/packages/layerzero-v2/evm/oapp/contracts/oft/OFT.sol) cũng như hợp đồng `Ownable.sol` chuẩn, vì những lý do tương tự như đã nêu ở trên.
{% endhint %}

Khi triển khai lên Chiliz Chain, hãy đảm bảo rằng `_name` và `_symbol` khớp với token gốc của bạn trên Base để tránh gây nhầm lẫn cho người dùng. Truyền địa chỉ Chiliz Chain Endpoint V2 (`0x6F475642a6e85809B1c36Fa62763669b1b48DD5B`) làm `_lzEndpoint`.

Xem tất cả các endpoint có sẵn cho Chiliz Chain tại đây:

{% embed url="<https://docs.layerzero.network/v2/deployments/chains/chiliz>" %}

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

Sau khi các hợp đồng của bạn đã sẵn sàng, bạn cần thông báo cho công cụ LayerZero biết cách chúng kết nối với nhau. Việc này được thực hiện bằng cách sử dụng file `layerzero.config.ts` nằm ở thư mục gốc của dự án Hardhat của bạn.

File cấu hình này đóng vai trò như bản thiết kế cho kiến trúc cross-chain của bạn. Nó ánh xạ các smart contract đã triển khai với Endpoint ID (EID) tương ứng trên LayerZero và xác định các đường dẫn (kết nối) giữa chúng.

[Simple Config Generator](https://docs.layerzero.network/v2/tools/simple-config) là cách được khuyến nghị để tạo cấu hình wiring, 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ị.

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

```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 baseContract: OmniPointHardhat = {
    eid: EndpointId.BASE_V2_MAINNET,
    contractName: 'BaseTokenAdapter',
};

const chilizContract: OmniPointHardhat = {
    eid: EndpointId.CHILIZ_V2_MAINNET,
    contractName: 'ChilizNativeOFT',
};

// Define standard EVM Gas Limits (Enforced Options)
const EVM_ENFORCED_OPTIONS: OAppEnforcedOption[] = [
    {
        msgType: 1,  // Standard OFT Transfer
        optionType: ExecutorOptionType.LZ_RECEIVE,
        gas: 200000, // Execution gas limit
        value: 0,    // Native drop (0 for standard transfers)
    },
];

// Export the Generated Configuration
export default async function () {
    return {
        contracts: [
            { contract: baseContract },
            { contract: chilizContract },
        ],
        // The generator automatically creates the A->B and B->A pathways!
        connections: await generateConnectionsConfig([
            [
                baseContract,      // Source
                chilizContract,    // Destination
                [['LayerZero Labs'], []], // Default DVN Configuration
                [1, 1],                   // Block Confirmations
                [EVM_ENFORCED_OPTIONS, EVM_ENFORCED_OPTIONS], // Execution Options [To Chiliz, To Base]
            ],
        ]),
    };
}
```

Mảng `[EVM_ENFORCED_OPTIONS, EVM_ENFORCED_OPTIONS]` yêu cầu LayerZero Executor thực thi 200.000 đơn vị gas khi giao tin nhắn đến Chiliz, và tương tự 200.000 đơn vị gas khi trả tin nhắn về Base.

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

Sau khi các hợp đồng đã được viết và `layerzero.config.ts` đã được chuẩn bị, đã đến lúc triển khai các hợp đồng lên các mạng tương ứng. Bộ công cụ LayerZero V2 dựa vào plugin `hardhat-deploy` để quản lý việc triển khai một cách hiệu quả.

Bạn cần tạo hai script triển khai trong thư mục `deploy/` của dự án: một cho Base Mainnet và một cho Chiliz Chain Mainnet.

### Script triển khai Base Adapter

Tạo một file tên `01_deploy_base_adapter.ts` trong thư mục `deploy/`. Script này truyền địa chỉ token hiện có của bạn và địa chỉ Base Endpoint V2 vào constructor.

```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 Base
    const TOKEN_ADDRESS = "0xYourTokenAddressHere"; 
    
    // The Base Mainnet Endpoint V2 Address
    const BASE_ENDPOINT_V2 = "0x1a44076050125825900e736c501f859c50fE728c";

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

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

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

### Script triển khai Chiliz Chain OFT

Tạo file thứ hai tên `02_deploy_chiliz_oft.ts` trong thư mục `deploy/`. Script này khởi tạo Native OFT mới trên Chiliz Chain.

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

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

    // Token Details (Must match your Base token)
    const TOKEN_NAME = "My Token";
    const TOKEN_SYMBOL = "TKN";

    // The Chiliz Chain Mainnet Endpoint V2 Address 
    const CHILIZ_ENDPOINT_V2 = "0x6F475642a6e85809B1c36Fa62763669b1b48DD5B";

    console.log("Deploying Native OFT to Base Mainnet...");

    await deploy('BaseTokenOFT', {
        from: deployer,
        args: [
            TOKEN_NAME,           // _name
            TOKEN_SYMBOL,         // _symbol
            CHILIZ_ENDPOINT_V2,   // _lzEndpoint
            deployer              // _delegate (Owner)
        ],
        log: true,
        waitConfirmations: 2,
    });
};

export default deployOFT;
deployOFT.tags = ['BaseTokenOFT'];
```

### Thực thi việc triển khai

Hãy đảm bảo rằng `hardhat.config.ts` của bạn đã cấu hình đúng URL RPC và private key cho cả Base và Chiliz Chain.

{% embed url="<https://docs.base.org/base-chain/quickstart/connecting-to-base>" %}

[Kết nối bằng RPC](/vi/phat-trien/co-ban/ket-noi-voi-chiliz-chain/ket-noi-bang-rpc.md)

Chạy các lệnh sau trong terminal để triển khai các hợp đồng:

```bash
# 1. Deploy the Adapter to Base
npx hardhat deploy --network chiliz --tags BaseTokenAdapter

# 2. Deploy the Native OFT to Chiliz Chain
npx hardhat deploy --network base --tags ChilizTokenOFT
```

Sau khi triển khai hoàn tất, Hardhat sẽ lưu các địa chỉ hợp đồng trong thư mục `deployments/`. Bộ công cụ LayerZero sẽ tự động đọc các địa chỉ này khi chúng ta chạy lệnh wiring ở bước tiếp theo.

## Bước 4: Wiring & Peering

Ở giai đoạn này, các hợp đồng `BaseTokenAdapter` và `ChilizTokenOFT` của bạn đã được triển khai trên mỗi chain, nhưng chúng hoàn toàn độc lập với nhau.\
Nếu hợp đồng trên Chiliz Chain nhận được tin nhắn yêu cầu đúc token, nó cần biết rằng tin nhắn đó thực sự xuất phát từ Adapter của *bạn* trên Base, chứ không phải từ một tác nhân độc hại.

Bạn phải thiết lập sự tin tưởng này bằng cách "kết nối" mật mã các hợp đồng lại với nhau như các peer.

Điều này được thực hiện bằng cách chạy lệnh `wire`, lệnh này sẽ tạo và thực thi các giao dịch trên cả Chiliz và Base.

{% hint style="info" %}
**Điều gì xảy ra bên trong?**

Một cấu hình đường dẫn LayerZero V2 hoàn chỉnh thực sự yêu cầu 6 giao dịch trên mỗi chain:

* `setSendLibrary`: Gán LayerZero MessageLib chịu trách nhiệm gửi tin nhắn (ví dụ: cấu hình để sử dụng V2 Send Library).
* `setReceiveLibrary`: Gán MessageLib chịu trách nhiệm nhận tin nhắn. (Bao gồm `gracePeriod`, thường được đặt là `0`).
* `setConfig` (Send Library): Đặt các Decentralized Verifier Networks (DVN) và Executor cụ thể cho tin nhắn gửi đi.
* `setConfig` (Receive Library): Đặt các DVN cụ thể cần thiết để xác minh tin nhắn đến.
* `setEnforcedOptions`: Đặt giới hạn gas thực thi bắt buộc. Khi người dùng gửi tin nhắn từ Base, họ trả trước phí gas cho chain đích. Việc đặt enforced options đảm bảo họ trả đủ gas để LayerZero Executor xử lý thành công giao dịch trên Chiliz Chain.
* `setPeer`: Liên kết Endpoint ID (EID) đích với một địa chỉ hợp đồng đáng tin cậy. Bạn phải thông báo cho hợp đồng Base tin tưởng hợp đồng Chiliz Chain, và hợp đồng Chiliz Chain tin tưởng hợp đồng Base.
  {% endhint %}

### Thực thi Wire Task

Chạy lệnh sau trong terminal:

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

Bộ công cụ sẽ tự động tính toán các tham số cần thiết, hiển thị cho bạn bảng các giao dịch sắp được thực thi, và gửi chúng lên Chiliz và Base bằng ví deployer của bạn.

Sau khi các giao dịch được xác nhận trên cả hai mạng, bridge token của bạn đã chính thức hoạt động và được cấu hình đầy đủ! Base Adapter hiện được phép gửi lệnh đúc đến Chiliz Chain, và Chiliz Chain được phép gửi lệnh mở khóa trở lại Base.

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

Sau khi các hợp đồng được triển khai và kết nối an toàn với nhau, token của bạn đã trở thành omnichain. Bước cuối cùng là thực hiện một giao dịch cross-chain từ Base Mainnet sang Chiliz Chain Mainnet.

### 1) Thực hiện giao dịch Cross-Chain

Bộ công cụ LayerZero V2 cung cấp một Hardhat task tích hợp sẵn để kiểm tra các giao dịch OFT trực tiếp từ terminal. Lệnh này sẽ ước tính phí gas cross-chain, tính phí ví của bạn bằng $ETH (token gas gốc trên chain nguồn, Base), và khởi tạo giao dịch chuyển nhượng.

Chạy lệnh sau:

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

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

{% endcode %}

Lệnh này thực hiện:

1. Tra cứu Base Mainnet (`30184`) và Chiliz Mainnet (`30409`) trong cấu hình của bạn.
2. Ước tính phí cross-chain do LayerZero Executor yêu cầu.
3. Gọi hàm `send()` trên Base Adapter của bạn.
4. Adapter khóa 10 token và phát một packet đến LayerZero Endpoint.

### 2) Theo dõi Packet trên LayerZero Scan

Các giao dịch cross-chain là bất đồng bộ. Trong khi giao dịch Chiliz của bạn sẽ được xác nhận trong vài giây, tin nhắn vẫn cần được xác minh và thực thi trên Base.

Để theo dõi hành trình này theo thời gian thực, hãy 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>" %}

## Thiết lập giới hạn Gas

Việc đặt giới hạn gas là rất quan trọng, vì việc không làm như vậy có thể khiến các tin nhắn cross-chain của bạn thất bại trên mạng đích.

Khi người dùng bridge một token từ Base sang Chiliz Chain, họ trả phí gas cho *cả hai* chain trước trong một giao dịch duy nhất trên Base (sử dụng `$ETH`). LayerZero sau đó sử dụng một phần của phí đó để trả phí gas ETH thực tế cần thiết để thực thi giao dịch đúc trên Chiliz Chain.

Để đảm bảo LayerZero có đủ gas để xử lý thành công hàm `lzReceive` trên chain đích, bạn phải đặt Enforced Options. Nếu không đặt, giao dịch có thể bị hoàn lại trên chain đích do lỗi "Out of Gas".

### **Cấu hình Options**

Option này được thiết lập trong file `layerzero.config.ts` của bạn. Cập nhật mảng `connections` để bao gồm khối `enforcedOptions` cho mỗi đường dẫn:

{% code overflow="wrap" %}

```typescript
import { EndpointId } from '@layerzerolabs/lz-definitions';

// ... (contract definitions as before)

connections: [
    {
        from: 'BaseTokenAdapter',
        to: 'ChilizTokenOFT',
        config: {
            enforcedOptions: [
                {
                    msgType: 1,        // 1 = Standard OFT Transfer (SEND)
                    optionType: 1,     // 1 = lzReceive Option
                    gas: 200000,       // Estimated gas limit to mint on Chiliz Chain
                },
                {
                    msgType: 2,        // 2 = OFT Transfer with payload (SEND_AND_CALL)
                    optionType: 1,
                    gas: 250000,       // Slightly higher gas limit for complex calls
                }
            ]
        },
    },
    {
        from: 'ChilizTokenOFT',
        to: 'BaseTokenAdapter',
        config: {
            enforcedOptions: [
                {
                    msgType: 1,
                    optionType: 1,
                    gas: 200000,       // Estimated gas limit to unlock on Base
                }
            ]
        },
    },
],
// ...
```

{% endcode %}

Giải thích các tham số:

* `msgType: 1`: Đại diện cho một giao dịch chuyển nhượng token chuẩn. `msgType: 2` được dùng cho các lệnh gọi "composed" (ví dụ: bridge một token và ngay lập tức stake nó chỉ trong một cú nhấp).
* `optionType: 1`: Hướng dẫn Executor thực thi đơn giản hàm `lzReceive`.
* `gas: 200000`: Giới hạn gas cơ bản an toàn cho các lệnh đúc và mở khóa OFT chuẩn. Bạn có thể điều chỉnh dựa trên mức tiêu thụ gas cụ thể của các hợp đồng đã triển khai.

Nếu bạn đặt option này sau khi đã kết nối các chain, bạn có thể kết nối lại với các option mới bằng cùng một lệnh:

{% code overflow="wrap" %}

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

{% endcode %}

Bộ công cụ sẽ tự động phát hiện các thay đổi và gửi giao dịch `setEnforcedOptions()` đến các hợp đồng của bạn trên cả Base và Chiliz. Bây giờ, bất cứ khi nào người dùng kích hoạt một bridge, các hợp đồng sẽ yêu cầu người dùng trả ít nhất 200.000 đơn vị gas trên chain đích, đảm bảo việc giao nhận đáng tin cậy.


---

# 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-base-sang-chiliz.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.
