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

# Hướng dẫn lệnh Farm / Staking

> CreateFarm, Deposit, Withdraw, Harvest, AddReward / SetRewards / RestartRewards, WithdrawReward — bộ lệnh đầy đủ trên farm v3, v5, và v6.

<Info>
  **Trang này được dịch tự động bằng AI. Phiên bản tiếng Anh là bản chính thức.**

  [Xem bản tiếng Anh →](/products/farm-staking/instructions)
</Info>

<Info>
  Các lệnh farm là tuỳ theo phiên bản. Một `Deposit` trên v6 không thể gọi được trên farm v5 và ngược lại. SDK phân phối bằng cách đọc chủ sở hữu chương trình của farm; đối với CPI trên chuỗi, bạn phải chọn ID chương trình phù hợp từ đầu.
</Info>

## Danh mục lệnh

| Mục đích                                    | v3                        | v5                        | v6                        |
| ------------------------------------------- | ------------------------- | ------------------------- | ------------------------- |
| Tạo một farm                                | `CreateFarm`              | `CreateFarm`              | `CreateFarm`              |
| Thêm sổ cái người dùng (có thể ngầm định)   | `CreateUserLedger`        | `CreateAssociatedLedger`  | Ngầm định trong `Deposit` |
| Stake                                       | `Deposit`                 | `Deposit`                 | `Deposit`                 |
| Unstake                                     | `Withdraw`                | `Withdraw`                | `Withdraw`                |
| Chỉ nhận phần thưởng                        | N/A (sử dụng `Deposit 0`) | N/A (sử dụng `Deposit 0`) | `Harvest`                 |
| Thêm luồng phần thưởng sau khi tạo          | N/A                       | `AddReward`               | `AddReward`               |
| Chỉnh sửa luồng phần thưởng hiện có         | N/A                       | `SetRewards`              | `SetRewards`              |
| Khởi động lại phần thưởng sau end\_time     | N/A                       | `RestartRewards`          | `RestartRewards`          |
| Rút ngân sách phần thưởng chưa nhận (admin) | N/A                       | `WithdrawReward`          | `WithdrawReward`          |

Trên v3 và v5, cách chuẩn để nhận phần thưởng mà không thay đổi stake là gọi `Deposit` với `amount = 0`. Chương trình coi đây là một quyết toán thuần túy. v6 đã giới thiệu `Harvest` rõ ràng để làm rõ ý định.

SDK trừu tượng hóa tất cả những điều này đằng sau `raydium.farm.deposit({ ... })` v.v. Các phần dưới đây ghi chép danh sách tài khoản cơ bản cho những người tích hợp cần xây dựng lệnh thủ công (aggregators, công cụ theo dõi, mở rộng SDK).

## `CreateFarm` (v6)

Khởi động một farm v6 mới.

**Đối số**

```
reward_info_count: u8               // số lượng luồng phần thưởng khi tạo (1..=5)
reward_infos: [
  {
    open_time:            u64,
    end_time:             u64,
    emission_per_second_x64: u128,   // Q64.64
    mint:                 Pubkey,    // phần thưởng mint
    token_program:        Pubkey,    // SPL hoặc Token-2022
  }
]
```

**Tài khoản** (tóm tắt, cho `reward_info_count = 1`)

| #  | Tên                        | W | S | Ghi chú                                                     |
| -- | -------------------------- | - | - | ----------------------------------------------------------- |
| 1  | `creator`                  | W | S | Trả tiền thuê, sở hữu farm.                                 |
| 2  | `farm_state`               | W |   | Tài khoản `FarmState` mới.                                  |
| 3  | `farm_authority`           |   |   | PDA `[farm_id]`.                                            |
| 4  | `staking_mint`             |   |   |                                                             |
| 5  | `staking_vault`            | W |   | Được tạo dưới dạng ATA của authority hoặc vault PDA.        |
| 6  | `staking_token_program`    |   |   |                                                             |
| 7  | `reward_mint`              |   |   |                                                             |
| 8  | `reward_vault`             | W |   | Sẽ nhận ngân sách ban đầu.                                  |
| 9  | `reward_token_program`     |   |   |                                                             |
| 10 | `reward_sender_ata`        | W |   | ATA của creator trên phần thưởng mint; bị xóa bởi lệnh này. |
| 11 | `system_program`           |   |   |                                                             |
| 12 | `token_program`            |   |   |                                                             |
| 13 | `associated_token_program` |   |   |                                                             |
| 14 | `rent`                     |   |   |                                                             |

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

* `open_time > now`, `end_time > open_time`.
* ATA của `creator` chứa ít nhất `emission_per_second_x64 × (end_time − open_time) / 2^64` của phần thưởng mint.
* `staking_mint` không có freeze authority hoặc freeze authority bị vô hiệu hóa.

**Điều kiện sau**

* `FarmState` được khởi tạo, `total_staked = 0`.
* Vault phần thưởng được tài trợ với toàn bộ ngân sách luồng.
* ATA phần thưởng của creator bị xóa theo số tiền đó.

## `Deposit` (v6)

Stake `amount` của staking mint.

**Đối số**

```
amount: u64
```

**Tài khoản**

| #        | Tên                        | W | S |
| -------- | -------------------------- | - | - |
| 1        | `user`                     | W | S |
| 2        | `user_ledger`              | W |   |
| 3        | `farm_state`               | W |   |
| 4        | `farm_authority`           |   |   |
| 5        | `staking_vault`            | W |   |
| 6        | `user_staking_ata`         | W |   |
| 7..(7+n) | `reward_vault_{i}`         | W |   |
| ...      | `user_reward_ata_{i}`      | W |   |
| last−2   | `system_program`           |   |   |
| last−1   | `token_program`            |   |   |
| last     | `associated_token_program` |   |   |

Nếu `user_ledger` không tồn tại, SDK sẽ thêm một ix kiểu `CreateAccount`; chương trình v6 cũng có thể tạo nó một cách lười biếng với tài khoản system program. Mẫu tài khoản còn lại: với mỗi phần thưởng hiện hoạt, hãy thêm `(reward_vault, user_reward_ata)` để có thể thực hiện quyết toán.

**Hiệu ứng**

1. Làm mới `reward_per_share_x64[i]` cho mỗi luồng phần thưởng hiện hoạt bằng công thức cập nhật lười biếng.
2. Tính toán `pending_i = user_ledger.deposited × reward_per_share_x64[i] / 2^64 − user_ledger.reward_debts[i]`.
3. Chuyển `pending_i` từ `reward_vault_{i}` đến `user_reward_ata_{i}`.
4. Chuyển `amount` staking mint từ `user_staking_ata` đến `staking_vault`.
5. Cập nhật `user_ledger.deposited += amount` và chụp lại `reward_debts[i]`.
6. Cập nhật `farm_state.total_staked += amount`.

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

* `amount > 0` cho một stake thực sự (v6 không cho phép `amount = 0` — sử dụng `Harvest` cho chỉ nhận).
* `user_staking_ata` chứa ít nhất `amount`.
* Mỗi vault phần thưởng hiện hoạt chứa ít nhất số tiền còn lại phải trả cho người dùng này.

## `Withdraw` (v6)

Unstake `amount`.

**Đối số**

```
amount: u64
```

**Tài khoản** — giống hệt với `Deposit`.

**Hiệu ứng** — quyết toán tương tự như `Deposit`, sau đó chuyển staking mint quay lại cho người dùng: `staking_vault → user_staking_ata`. Cả `total_staked` và `user_ledger.deposited` đều giảm.

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

* `amount ≤ user_ledger.deposited`.
* Farm không bị tạm dừng.

## `Harvest` (v6)

Nhận phần thưởng đang chờ xử lý mà không thay đổi stake.

**Đối số** — không có.

**Tài khoản** — giống như `Deposit`, không có chuyển động phía staking.

**Hiệu ứng** — làm mới `reward_per_share_x64[i]`, trả `pending_i`, chụp lại `reward_debts[i]`. Không có thay đổi đối với `total_staked` hoặc `deposited`.

## `AddReward` (v5/v6)

Thêm luồng phần thưởng mới vào farm hiện có có khe trống.

**Đối số**

```
reward_info: {
  open_time:            u64,
  end_time:             u64,
  emission_per_second_x64: u128,
  mint:                 Pubkey,
  token_program:        Pubkey,
}
```

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

* Khe trống tồn tại (`reward_info_count < 5` trên v6, `< 2` trên v5).
* `open_time ≥ now` (có thể ở tương lai) hoặc `open_time < now` được phép chỉ khi phiên bản chương trình cho phép — v6 có, v5 thì không.

**Điều kiện sau**

* Luồng mới được khởi tạo tại chỉ mục `reward_info_count`, `reward_info_count++`.
* Vault phần thưởng được tín dụng với toàn bộ ngân sách luồng từ ATA của người gọi.

**Lỗi phổ biến** — `RewardAlreadyExists` nếu mint va chạm với khe hiện có.

## `SetRewards` (v5/v6)

Mở rộng hoặc bổ sung luồng phần thưởng hiện có. Không thể thay đổi mint; không thể rút ngắn `end_time`; không thể giảm `emission_per_second_x64` khi đang chạy.

**Đối số**

```
reward_index:         u8
new_open_time:        u64,
new_end_time:         u64,
new_emission_per_second_x64: u128,
```

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

* Luồng vẫn đang chạy (`reward_state == 1`).
* `new_end_time ≥ current end_time`.
* Ngân sách bổ sung cần thiết `(new_emission × new_duration − already_emissioned)` có trong ATA của người gửi và được chuyển đến vault phần thưởng bởi lệnh.

Trên v5, lệnh tương đương là `SetRewards` với bộ đối số nhỏ hơn (không có thay đổi per-second trên các luồng hiện hoạt).

## `RestartRewards` (v5/v6)

Khởi động lại luồng sau khi `end_time` của nó đã trôi qua. Về mặt khái niệm giống như `AddReward` cho một mint đã có khe.

**Đối số** — hình dạng giống hệt với `AddReward` tại chỉ mục đó.

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

* `reward_state == 2` (đã kết thúc).
* Người gọi là `reward_sender` của khe (v6) hoặc `owner` của farm (v5).

## `WithdrawReward` (v5/v6)

Quét hành chính của số dư vault phần thưởng chưa nhận sau khi luồng đã kết thúc và tất cả những người stake đã có cơ hội để harvest.

**Đối số**

```
reward_index: u8
```

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

* Luồng đã kết thúc (`reward_state == 2`).
* `reward_total_emissioned == reward_claimed + vault_balance` (không có gì đang nợ).

**Hiệu ứng** — chuyển phần còn lại đến `reward_sender_ata`. Chương trình không ngăn chặn việc rút tiền trong khi những người stake vẫn còn các khoản thanh toán đang chờ xử lý; admin được kỳ vọng sẽ harvest thay mặt những người stake chậm trễ trước (hoặc để cho họ harvest). Nếu bạn quét sớm, người dùng sẽ mất quyền truy cập vào phần thưởng chưa nhận của họ. **Đừng gọi cái này sớm.**

## Biến thể v5

* `Deposit` / `Withdraw` có hình dạng giống v6 nhưng sử dụng tối đa 2 khe phần thưởng và `reward_per_share` là `u128` (điểm cố định với cơ số khác).
* `CreateAssociatedLedger` là lệnh gọi riêng biệt cần thiết trước `Deposit` đầu tiên; v6 đã hợp nhất nó.
* `AddReward` có sẵn, `Harvest` thì không (sử dụng `Deposit 0`).

## Biến thể v3

* Luồng phần thưởng duy nhất. Không có `AddReward`, không có khe thứ hai.
* `Deposit 0` là cách duy nhất để nhận.
* `CreateUserLedger` phải được gọi trước `Deposit` đầu tiên.

## Ma trận thay đổi trạng thái

| Lệnh             | `total_staked` | `user.deposited` | `reward_per_share` | Vault phần thưởng   |
| ---------------- | -------------- | ---------------- | ------------------ | ------------------- |
| `CreateFarm`     | 0              | —                | 0                  | tài trợ bởi creator |
| `Deposit(n)`     | +n             | +n               | làm mới            | −pending (trả)      |
| `Withdraw(n)`    | −n             | −n               | làm mới            | −pending            |
| `Harvest`        | —              | —                | làm mới            | −pending            |
| `AddReward`      | —              | —                | —                  | +ngân sách mới      |
| `SetRewards`     | —              | —                | —                  | +ngân sách delta    |
| `RestartRewards` | —              | —                | —                  | +ngân sách          |
| `WithdrawReward` | —              | —                | —                  | −phần còn lại       |

## Bước tiếp theo

* [`products/farm-staking/code-demos`](/vi/products/farm-staking/code-demos) — ví dụ TypeScript.
* [`products/farm-staking/accounts`](/vi/products/farm-staking/accounts) — bố cục `FarmState` / `UserLedger` / `UserStake`.
* [`reference/error-codes`](/vi/reference/error-codes) — liệt kê lỗi farm.

Nguồn:

* [Raydium SDK v2 `Farm` module](https://github.com/raydium-io/raydium-sdk-V2)
* Raydium farm program source (v3 / v5 / v6)
