> ## 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.

# Quy tắc đường cong LaunchLab

> Cách một nền tảng hạn chế các tham số khởi chạy mà những người tạo có thể chọn: kiểm tra nhóm, mô hình ràng buộc (trường, toán tử, giá trị), và chín kịch bản — các tầng chính xác, dải giá trị, giới hạn định giá tốt nghiệp, sàn di chuyển, gating loại token, và các chương trình khuyến mãi có thời hạn.

<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/launchlab/curve-rules)
</Info>

<Info>
  Một **curve rule** (quy tắc đường cong) là câu trả lời của nền tảng cho câu hỏi "những lần khởi chạy nào tôi sẵn sàng lưu trữ?". [`GlobalConfig`](/vi/products/launchlab/global-config) đặt sàn giao thức — cung cấp ít nhất 10M, ít nhất 20% cung cấp được bán trên đường cong, v.v. — và những sàn này được cố ý rộng để mọi loại nền tảng đều phù hợp. Quy tắc đường cong là nơi bạn thu hẹp chúng thành hình dạng mà sản phẩm của bạn thực sự hỗ trợ.

  Các quy tắc nằm trong tài khoản `PlatformCurveRule` riêng của chúng, một tài khoản cho mỗi cặp (nền tảng, [`GlobalConfig`](/vi/products/launchlab/global-config)). Chúng chỉ có thể thu hẹp những gì cấu hình đã cho phép; một quy tắc không bao giờ có thể mở rộng giới hạn giao thức.
</Info>

## Mô hình tư duy

Ba cấp độ, từ ngoài vào trong:

```
GlobalConfig       sàn giao thức      "supply >= 10M, sell rate >= 20%, ..."
  └─ PlatformCurveRule   quy tắc của bạn     "và trên nền tảng của tôi: một trong những hình dạng này"
       └─ check group    một hình dạng     "supply = 1B AND fund raising in [80, 90] SOL"
            └─ constraint một kiểm tra    "(Supply, Eq, 1_000_000_000)"
```

Hai cấp độ lồng nhau là những gì làm cho điều này có biểu cảm:

* **Các ràng buộc bên trong một nhóm được AND lại với nhau.** Tất cả chúng phải giữ.
* **Các nhóm bên trong một quy tắc được OR lại với nhau.** Một lần khởi chạy được phép ngay khi nó thỏa mãn bất kỳ nhóm nào.

Vì vậy, một nhóm là một *hình dạng* được phép, và quy tắc là menu các hình dạng bạn cung cấp. Một quy tắc chứa tối đa 10 nhóm, và một nhóm chứa tối đa 25 ràng buộc.

Hai trường hợp biên giới đáng ghi nhớ:

| Trạng thái                                             | Ý nghĩa                                                                      |
| ------------------------------------------------------ | ---------------------------------------------------------------------------- |
| Không có tài khoản quy tắc, hoặc quy tắc có không nhóm | Nền tảng không hạn chế các tham số khởi chạy cho cấu hình đó.                |
| Một nhóm có không ràng buộc                            | Nhóm đó khớp với mọi lần khởi chạy, vì vậy toàn bộ quy tắc cho phép mọi thứ. |

Một quy tắc chỉ có hiệu lực khi `PlatformConfig.restrict_curve_param` là `1`. Ở `0`, chương trình không đọc quy tắc nào cả, đây cũng là công tắc bạn sử dụng để triển khai quy tắc và để quay lại.

## Ràng buộc

Một ràng buộc là một bộ ba `(field, op, value)`. Không có gì khác — không có biểu thức, không có lồng nhau.

```rust theme={null}
pub struct ParamConstraint {
    pub field: u8,    // tham số khởi chạy nào, xem bảng dưới đây
    pub op:    u8,    // 0 Eq, 1 Gte (min), 2 Lte (max), 3 Neq
    pub value: u128,
}
```

Một **dải là hai ràng buộc** trên cùng một trường bên trong một nhóm: một `Gte` cho sàn và một `Lte` cho trần. Cặp `(field, op)` giống nhau không được xuất hiện hai lần trong một nhóm, đó là điều ngăn bạn viết hai mức tối thiểu mâu thuẫn.

### Trường

<Info>
  Các id trường là vĩnh viễn. Các trường mới chỉ được thêm vào, vì vậy một id không bao giờ thay đổi ý nghĩa sau khi tài khoản quy tắc giữ nó.
</Info>

| id | Trường                   | Đơn vị       | Ghi chú                                                                                                      |
| -- | ------------------------ | ------------ | ------------------------------------------------------------------------------------------------------------ |
| 0  | `CurveType`              | enum         | 0 constant product, 1 fixed price, 2 linear price                                                            |
| 1  | `MigrateType`            | enum         | Các lần khởi chạy mới phải là `1` (CPMM) dù sao                                                              |
| 2  | `MigrateCpmmFeeOn`       | enum         | 0 quote-only, 1 cả hai token                                                                                 |
| 3  | `Supply`                 | đơn vị cơ sở | Toàn bộ cung cấp token                                                                                       |
| 4  | `TotalSellA`             | đơn vị cơ sở | Bán trên đường cong. Chỉ cấu hình constant-product — xem [Hạn chế loại đường cong](#hạn-chế-loại-đường-cong) |
| 5  | `TotalFundRaisingB`      | đơn vị quote | Mục tiêu tốt nghiệp                                                                                          |
| 6  | `TotalLockedAmount`      | đơn vị cơ sở | Ngân sách vesting                                                                                            |
| 7  | `CliffPeriod`            | giây         | Chờ trước khi mở khóa bắt đầu                                                                                |
| 8  | `UnlockPeriod`           | giây         | Thời lượng mở khóa                                                                                           |
| 9  | `BaseTokenProgram`       | enum         | 0 SPL Token, 1 Token-2022                                                                                    |
| 10 | `TransferFeeEnabled`     | bool         | 1 khi base mint mang `TransferFeeConfig`                                                                     |
| 11 | `TransferFeeBasisPoints` | 1/10 000     | 0 nếu không có tiện ích mở rộng                                                                              |
| 12 | `TransferFeeMaximumFee`  | đơn vị cơ sở | 0 nếu không có tiện ích mở rộng                                                                              |
| 13 | `SellRateA`              | 1/1 000 000  | Dẫn xuất: `TotalSellA / Supply`. Chỉ constant-product                                                        |
| 14 | `LockRate`               | 1/1 000 000  | Dẫn xuất: `TotalLockedAmount / Supply`                                                                       |
| 15 | `MigrateAmountA`         | đơn vị cơ sở | Dẫn xuất: `Supply − TotalSellA − TotalLockedAmount`. Chỉ constant-product                                    |
| 16 | `MigrateRateA`           | 1/1 000 000  | Dẫn xuất: `MigrateAmountA / Supply`. Chỉ constant-product                                                    |
| 17 | `FundRaisingRateB`       | 1/1 000 000  | Dẫn xuất: `TotalFundRaisingB / Supply`                                                                       |
| 18 | `UnixTimestamp`          | giây         | Thời gian khối của lần khởi chạy                                                                             |

Các trường dẫn xuất là những trường làm cho quy tắc có thể di động. Ghim `Supply` và `TotalFundRaisingB` vào các số chính xác sẽ sửa một hình dạng khởi chạy; ràng buộc `FundRaisingRateB` sửa *mối quan hệ* giữa chúng và cho phép người tạo chọn bất kỳ cung cấp nào giữ nó.

<Warning>
  Các trường tỷ lệ chỉ có thể so sánh được trong một `GlobalConfig`, vì mẫu số của chúng phụ thuộc vào quote mint của cấu hình đó và số thập phân của nó. Đó không phải là một hạn chế trong thực tế: một quy tắc được phạm vi cho một cấu hình theo cấu trúc.
</Warning>

## Chín kịch bản

Mỗi kịch bản dưới đây là một quy tắc. Các ràng buộc được viết dưới dạng `(field, op, value)`.

### 1. Một tầng tiêu chuẩn

Quy tắc đơn giản nhất, và hành vi chính xác mà danh sách trắng tham số đường cong đã loại bỏ cung cấp: một hình dạng, được ghim.

| Nhóm | Ràng buộc                                                                                           |
| ---- | --------------------------------------------------------------------------------------------------- |
| 0    | `(Supply, Eq, 1_000_000_000e6)`, `(TotalSellA, Eq, 800_000_000e6)`, `(TotalFundRaisingB, Eq, 85e9)` |

Bất kỳ lần khởi chạy nào lệch trong bất kỳ ba cái nào đều bị từ chối với `CurveParamNotMatchPlatformRule`.

### 2. Một dải thay vì một số

Lý do dải tồn tại: một người tạo chọn mục tiêu gây quỹ mà bạn thoải mái, mà không cần bạn liệt kê từng giá trị.

| Nhóm | Ràng buộc                                                                                            |
| ---- | ---------------------------------------------------------------------------------------------------- |
| 0    | `(Supply, Eq, 1_000_000_000e6)`, `(TotalFundRaisingB, Gte, 50e9)`, `(TotalFundRaisingB, Lte, 200e9)` |

Một nhóm, bốn ràng buộc, và người tạo có một hành lang 50–200 SOL. Theo danh sách trắng cũ, điều này cần một mục cho mỗi giá trị được phép, và giới hạn mười mục làm cho nó không thể.

### 3. Các tầng cạnh nhau

Các nhóm được OR lại, vì vậy mỗi tầng là một nhóm.

| Nhóm | Ràng buộc                                                           | Tầng       |
| ---- | ------------------------------------------------------------------- | ---------- |
| 0    | `(Supply, Eq, 1_000_000_000e6)`, `(TotalFundRaisingB, Eq, 85e9)`    | Tiêu chuẩn |
| 1    | `(Supply, Eq, 100_000_000e6)`, `(TotalFundRaisingB, Eq, 30e9)`      | Nhỏ        |
| 2    | `(Supply, Eq, 10_000_000_000e6)`, `(TotalFundRaisingB, Gte, 500e9)` | Cá voi     |

Thứ tự quan trọng đối với tính toán, không phải ngữ nghĩa: đánh giá dừng ở nhóm đầu tiên khớp, vì vậy hãy đặt tầng được sử dụng nhiều nhất của bạn trước tiên.

### 4. Một dải định giá tốt nghiệp

`FundRaisingRateB` là `TotalFundRaisingB / Supply` tính bằng triệu. Ràng buộc nó giới hạn mức độ phong phú mà một token có thể tốt nghiệp bất kể cung cấp mà người tạo chọn.

| Nhóm | Ràng buộc                                                             |
| ---- | --------------------------------------------------------------------- |
| 0    | `(FundRaisingRateB, Gte, 60_000)`, `(FundRaisingRateB, Lte, 120_000)` |

Với cung cấp 1e12 và quote mint 9 chữ số thập phân, `85e9 / 1e12 × 1e6 = 85_000` nằm trong dải đó. Một người tạo nhân đôi cung cấp phải gần như nhân đôi mục tiêu để ở trong nó — đó là điểm. Hai ràng buộc thay thế những gì sẽ là một bảng các cặp `(supply, target)`.

### 5. Một sàn di chuyển

`MigrateRateA` là phần cung cấp thực sự hạ cánh trong nhóm CPMM tại tốt nghiệp: `Supply − TotalSellA − TotalLockedAmount`, trên cung cấp. Đó là độ sâu của nhóm tốt nghiệp, và đó là một trong những nút giao thức duy nhất không có tương đương phía nền tảng trước khi quy tắc tồn tại.

| Nhóm | Ràng buộc                      |
| ---- | ------------------------------ |
| 0    | `(MigrateRateA, Gte, 150_000)` |

Ít nhất 15% cung cấp đạt đến nhóm. Một người tạo không thể bán 95% trên đường cong và để lại một cuốn sách nông sau.

<Note>
  Nếu các tham số không cộng lại — một lượng bị khóa lớn hơn những gì còn lại sau bán đường cong — giá trị dẫn xuất không thể được tính toán và ràng buộc không thành công, vì vậy lần khởi chạy bị từ chối thay vì được cho phép im lặng.
</Note>

### 6. Vesting mà bạn thực sự thực thi

`GlobalConfig.max_lock_rate` giới hạn vesting từ trên. Một quy tắc có thể đặt một sàn dưới nó, và yêu cầu một vách đá thực sự.

| Nhóm | Ràng buộc                                                                              |
| ---- | -------------------------------------------------------------------------------------- |
| 0    | `(LockRate, Gte, 50_000)`, `(LockRate, Lte, 200_000)`, `(CliffPeriod, Gte, 2_592_000)` |

Từ 5% đến 20% cung cấp được vesting, với ít nhất một vách đá 30 ngày. Hữu ích cho một nền tảng có pitch là "không có lần khởi chạy mở khóa tức thì".

### 7. Gating loại token

`BaseTokenProgram` và `TransferFeeEnabled` là độc lập, điều này quan trọng: một mint Token-2022 không có `TransferFeeConfig` báo cáo `TransferFeeEnabled = 0` giống như một mint SPL Token.

| Ý định                                | Nhóm | Ràng buộc                                                  |
| ------------------------------------- | ---- | ---------------------------------------------------------- |
| Chỉ SPL Token                         | 0    | `(BaseTokenProgram, Eq, 0)`                                |
| Chỉ Token-2022                        | 0    | `(BaseTokenProgram, Eq, 1)`                                |
| Token-2022, không có phí chuyển       | 0    | `(BaseTokenProgram, Eq, 1)`, `(TransferFeeEnabled, Eq, 0)` |
| Không có phí chuyển, chương trình nào | 0    | `(TransferFeeEnabled, Eq, 0)`                              |

### 8. Một giới hạn phí chuyển có điều kiện

Không có toán tử "if", và không cần — hai nhóm biểu thị điều kiện.

| Nhóm | Ràng buộc                                                                                                  | Đọc là                                                     |
| ---- | ---------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- |
| 0    | `(TransferFeeEnabled, Eq, 0)`                                                                              | Không có phí chuyển: được                                  |
| 1    | `(TransferFeeEnabled, Eq, 1)`, `(TransferFeeBasisPoints, Lte, 100)`, `(TransferFeeMaximumFee, Gte, 1_000)` | Với một phí: tối đa 1%, và một phí tối đa thực sự được đặt |

Một `TransferFeeConfig` tỷ lệ không trượt qua nhóm 0: tiện ích mở rộng có mặt, vì vậy `TransferFeeEnabled` là `1` và chỉ nhóm 1 có thể chấp nhận nó.

### 9. Một chương trình khuyến mãi có thời hạn, được lên lịch trước

`UnixTimestamp` là thời gian khối của lần khởi chạy, vì vậy một nhóm có thể mang cửa sổ hợp lệ của riêng nó. Bạn viết cả hai nhóm hôm nay và chuyển đổi xảy ra tự động.

| Nhóm | Ràng buộc                                                               | Cửa sổ                          |
| ---- | ----------------------------------------------------------------------- | ------------------------------- |
| 0    | `(UnixTimestamp, Lte, 1_767_225_600)`, `(TotalFundRaisingB, Gte, 30e9)` | Kỳ khuyến mãi: tối thiểu 30 SOL |
| 1    | `(UnixTimestamp, Gte, 1_767_225_601)`, `(TotalFundRaisingB, Gte, 80e9)` | Sau đó: tối thiểu 80 SOL        |

Không cần giao dịch ở ranh giới. Chi phí là hai khe nhóm thay vì một.

## Hạn chế loại đường cong

Bốn trường đọc `TotalSellA`: `TotalSellA`, `SellRateA`, `MigrateAmountA`, và `MigrateRateA`. Trên cấu hình constant-product, người tạo cung cấp số đó. Trên cấu hình fixed-price hoặc linear-price, đường cong dẫn xuất nó thay vào đó, và giá trị mà chương trình so sánh là `0`, điều này sẽ từ chối mọi lần khởi chạy.

Thay vì để bạn viết một quy tắc im lặng chặn cấu hình của riêng bạn, chương trình từ chối bốn trường đó tại thời gian viết với `CurveRuleFieldNotSupportedByCurve`. Chỉ cấu hình constant-product tồn tại ngày hôm nay, vì vậy trong thực tế bạn sẽ không gặp lỗi này.

## Kiểm tra trước khi gửi

Cả hai hướng của kiểm tra on-chain đều có sẵn ngoài chuỗi, vì vậy không ai — người tạo cũng không phải nền tảng — phải học một quy tắc bằng cách xem các giao dịch hoàn nguyên.

<Info>
  **Biểu ngữ phiên bản.**

  * SDK: `@raydium-io/raydium-sdk-v2@0.2.42-alpha` là phiên bản mà mọi bản demo mã khác trên trang này được ghim. Hai trợ giúp dưới đây đến với bản phát hành SDK hỗ trợ curve-rule; cho đến lúc đó, hãy chuyển chúng từ `platform_curve_rule.rs` của chương trình hoặc gọi chương trình và đọc mã lỗi.
  * Cluster: kiểm tra trên Solana `devnet` trước — xem [Kiểm tra trên devnet trước tiên](#kiểm-tra-trên-devnet-trước-tiên).
  * Program ID: xem [`reference/program-addresses`](/vi/reference/program-addresses)

  Cả hai trợ giúp đều là hàm thuần. Chúng không chạm vào RPC, vì vậy chúng an toàn để chạy trên mỗi keystroke trong một biểu mẫu.
</Info>

### Trước một lần khởi chạy: những tham số này sẽ vượt qua không?

`checkLaunchAgainstCurveRule` phản ánh kiểm tra thời gian khởi chạy của chương trình chính xác, bao gồm hành vi không thành công của nó. Chạy nó trong biểu mẫu khởi chạy của bạn và bạn có thể vô hiệu hóa nút gửi với một lý do thay vì để người tạo trả tiền cho một giao dịch hoàn nguyên.

```ts theme={null}
import {
  checkLaunchAgainstCurveRule,
  getPdaPlatformCurveRule,
  LaunchpadCurveRuleBaseTokenProgram,
  LaunchpadCurveRuleField,
  PlatformCurveRule,
} from "@raydium-io/raydium-sdk-v2";
import BN from "bn.js";

const platformConfig = await raydium.launchpad.getPlatformConfig(platformConfigId);

// ở 0 chương trình không đọc quy tắc nào cả, vì vậy không có gì để kiểm tra
if (platformConfig.restrictCurveParam !== 0) {
  const ruleId = getPdaPlatformCurveRule(programId, platformConfigId, configId).publicKey;
  const ruleAccount = await connection.getAccountInfo(ruleId);

  const result = checkLaunchAgainstCurveRule({
    // undefined khi tài khoản không tồn tại — nền tảng không viết quy tắc cho cấu hình này
    rule: ruleAccount === null ? undefined : PlatformCurveRule.decode(ruleAccount.data),
    context: {
      curveType: globalConfig.curveType,
      migrateType: 1,
      migrateCpmmFeeOn: 0,
      supply: new BN("1000000000000000"),
      totalSellA: new BN("793100000000000"),
      totalFundRaisingB: new BN("85000000000"),
      totalLockedAmount: new BN(0),
      cliffPeriod: new BN(0),
      unlockPeriod: new BN(0),
      baseTokenProgram: LaunchpadCurveRuleBaseTokenProgram.SplToken,
      // bỏ qua transferFee hoàn toàn khi base mint không mang tiện ích mở rộng phí chuyển
      unixTimestamp: new BN(Math.floor(Date.now() / 1000)),
    },
  });

  if (!result.ok) {
    // mỗi nhóm từ chối lần khởi chạy; mỗi mục liệt kê tất cả các ràng buộc không thành công của nhóm đó
    for (const group of result.groupFailures) {
      for (const c of group.unsatisfied) {
        console.log(
          `group ${group.groupId}: ${LaunchpadCurveRuleField[c.field]} is ${c.actual ?? "not computable"},`,
          `rule wants op ${c.op} ${c.value.toString()}`,
        );
      }
    }
  }
}
```

Ba điều mà trợ giúp tái tạo thay vì xấp xỉ:

* **Một tài khoản quy tắc bị thiếu, và một quy tắc không có nhóm, đều vượt qua.** Một nhóm không có ràng buộc cũng vậy. Chuyển `rule: undefined` cho một tài khoản không tồn tại; không coi nó là một từ chối.
* **Các giá trị không thể tính toán không thành công.** Một cung cấp không có tỷ lệ, và một lượng bị khóa lớn hơn những gì bán đường cong để lại không có lượng di chuyển. `actual` quay lại `undefined` và ràng buộc được tính là không thỏa mãn, chính xác như on-chain.
* **Tất cả các ràng buộc không thành công được báo cáo, không chỉ cái đầu tiên.** Chương trình tắt ngắn vì nó chỉ cần một phán quyết; trợ giúp thu thập mọi thứ để biểu mẫu của bạn có thể liệt kê mọi vấn đề cùng một lúc.

Điều duy nhất nó không thể biết là thời gian khối mà giao dịch của bạn sẽ thực sự hạ cánh. Nếu một quy tắc sử dụng `UnixTimestamp` gần một ranh giới, hãy coi một lần vượt qua là tạm thời.

### Trước khi viết một quy tắc: nhóm này có hợp lệ không?

`checkCurveRuleGroupWritable` phản ánh xác thực thời gian viết của `UpdatePlatformCurveRule` — id ràng buộc, quy tắc `(field, op)` trùng lặp, cả hai giới hạn số lượng, và hạn chế loại đường cong. Chạy nó trong công cụ quản trị nền tảng của bạn trước khi ký.

```ts theme={null}
import {
  checkCurveRuleGroupWritable,
  LaunchpadCurveRuleField,
  LaunchpadCurveRuleOp,
} from "@raydium-io/raydium-sdk-v2";

const constraints = [
  { field: LaunchpadCurveRuleField.Supply, op: LaunchpadCurveRuleOp.Eq, value: new BN("1000000000000000") },
  { field: LaunchpadCurveRuleField.TotalFundRaisingB, op: LaunchpadCurveRuleOp.Gte, value: new BN("50000000000") },
  { field: LaunchpadCurveRuleField.TotalFundRaisingB, op: LaunchpadCurveRuleOp.Lte, value: new BN("200000000000") },
];

const writable = checkCurveRuleGroupWritable({
  groupId: 0,
  constraints,
  curveType: globalConfig.curveType,
  // các id mà quy tắc đã giữ, vì vậy thay thế một nhóm không bị nhầm lẫn với việc thêm một
  existingGroupIds: existingRule?.groups.map((g) => g.groupId) ?? [],
});

// mỗi lỗi mang mã lỗi chương trình mà giao dịch sẽ bị từ chối
if (!writable.ok) console.log(writable.errors);
```

<Note>
  Vượt qua kiểm tra này có nghĩa là giao dịch sẽ không bị từ chối vì bị hỏng. Nó không nói gì về việc quy tắc có phải là những gì bạn dự định — một nhóm có thể hoàn toàn hợp lệ và vẫn từ chối mọi lần khởi chạy mà UI của bạn có thể tạo ra. Đó là những gì kiểm tra phía khởi chạy ở trên dành cho: sau khi viết một nhóm, chạy mọi hình dạng mà sản phẩm của bạn cung cấp thông qua `checkLaunchAgainstCurveRule` và xác nhận mỗi cái vẫn tìm thấy một nhóm.
</Note>

### Kiểm tra trên devnet trước tiên

Bật `restrict_curve_param` trên mainnet thay đổi những gì những người tạo của bạn có thể làm, ngay lập tức, cho mọi lần khởi chạy. Tập duyệt toàn bộ chuỗi trên devnet trước khi bạn chạm vào mainnet:

1. Tạo một cấu hình nền tảng và một quy tắc trên devnet, và viết các nhóm giống như bạn dự định gửi.
2. Chạy mọi hình dạng khởi chạy mà UI của bạn có thể tạo ra thông qua `checkLaunchAgainstCurveRule`, và xác nhận các phán quyết là những cái bạn mong đợi — cả những hình dạng nên vượt qua và những hình dạng nên bị từ chối.
3. Bật `restrict_curve_param`, sau đó thực sự khởi chạy một token nên vượt qua và một nên bị từ chối. Cái thứ hai nên không thành công với `CurveParamNotMatchPlatformRule` (`6025`), không phải `NotEnoughRemainingAccounts` (`6018`) — cái sau có nghĩa là trình xây dựng của bạn không nối PDA quy tắc và kiểm tra không thực sự được thực hiện.
4. Chỉ sau đó lặp lại trên mainnet, theo cùng một thứ tự.

Điểm 3 là cái đáng nhấn mạnh. Trợ giúp ngoài chuỗi và chương trình on-chain là hai triển khai của cùng một quy tắc, và một lần khởi chạy devnet là những gì chứng minh chúng đồng ý cho quy tắc của bạn — bao gồm cả việc trình xây dựng khởi chạy của bạn chuyển tài khoản nào cả.

## Vận hành một quy tắc

### Người quản lý được ủy quyền

Chỉnh sửa quy tắc là công việc thường xuyên; khóa quản trị nền tảng thường là một multisig. `PlatformConfig.curve_rule_manager` tồn tại chính xác vì lý do đó: đặt nó một lần thông qua `UpdatePlatformConfig::CurveRuleManager`, và ví nóng đó có thể tạo, cập nhật, xóa và đóng tài khoản quy tắc tự mình. Quản trị nền tảng giữ lại cùng một quyền lực song song, vì vậy một khóa quản lý bị mất có thể khôi phục — xoay nó bằng một cuộc gọi quản trị khác.

Phạm vi của một khóa quản lý bị xâm phạm: nó có thể nới lỏng hoặc xóa quy tắc tham số của bạn, và nó có thể khôi phục tiền thuê của tài khoản quy tắc. Nó không thể chạm vào ví phí, vesting, cấu hình CPMM, không thể lật `restrict_curve_param`, và không thể phá vỡ giới hạn `GlobalConfig`. Coi nó như một khóa cấu hình, không phải một khóa kho bạc.

### Tiền thuê theo nội dung

Một tài khoản quy tắc được tạo không giữ nhóm và được thay đổi kích thước trên mỗi thay đổi, vì vậy bạn trả tiền cho các quy tắc bạn thực sự viết. Xóa một nhóm hoàn lại sự khác biệt cho người ký.

| Nội dung quy tắc          | Kích thước tài khoản | Tiền thuê    |
| ------------------------- | -------------------- | ------------ |
| Trống (vừa tạo)           | 150 byte             | \~0.0019 SOL |
| 1 nhóm, 2 ràng buộc       | 200 byte             | \~0.0023 SOL |
| 3 nhóm, 4 ràng buộc mỗi   | 408 byte             | \~0.0037 SOL |
| 10 nhóm, 25 ràng buộc mỗi | 4 790 byte           | \~0.034 SOL  |

### Thứ tự triển khai

1. Tập duyệt toàn bộ chuỗi trên devnet — xem [Kiểm tra trên devnet trước tiên](#kiểm-tra-trên-devnet-trước-tiên).
2. Tạo tài khoản quy tắc và viết các nhóm của nó. Không có gì thay đổi — với `restrict_curve_param` vẫn `0`, chương trình không đọc chúng.
3. Kiểm tra quy tắc ngoài chuỗi với [`checkLaunchAgainstCurveRule`](#trước-một-lần-khởi-chạy-những-tham-số-này-sẽ-vượt-qua-không): cho mỗi hình dạng khởi chạy mà UI của bạn có thể tạo ra, xác nhận một số nhóm chấp nhận nó.
4. Đặt `restrict_curve_param` thành `1`. Từ thời điểm đó, những lần khởi chạy của những người tạo của bạn được kiểm tra.
5. Để quay lại, đặt nó thành `0` lại. Tài khoản quy tắc được để nguyên.

<Warning>
  Trình xây dựng khởi chạy của bạn phải nối PDA quy tắc vào `remaining_accounts` trong khi `restrict_curve_param` là `1`. Chương trình yêu cầu tài khoản có mặt ngay cả khi nó chưa tồn tại, vì vậy người tạo không thể bỏ qua kiểm tra bằng cách bỏ qua nó — một tài khoản bị thiếu là `NotEnoughRemainingAccounts`, không phải một lần vượt qua. Dẫn xuất là `[b"platform_curve_rule", platform_config, global_config]`.
</Warning>

## Chi phí tại thời gian khởi chạy

Kiểm tra chạy trên mỗi lần khởi chạy trong khi nó được bật, vì vậy chi phí tính toán của nó là một khoản thuế mỗi lần khởi chạy. Đo từ đầu đến cuối — dẫn xuất PDA, quét `remaining_accounts`, giải mã hóa và đánh giá:

| Nội dung quy tắc                | Trường rẻ | Trường dẫn xuất |
| ------------------------------- | --------- | --------------- |
| Bật, không có tài khoản quy tắc | 1 936     | —               |
| 1 nhóm, 2 ràng buộc             | 2 576     | 2 926           |
| 3 nhóm, 4 ràng buộc mỗi         | 3 624     | 5 724           |
| 10 nhóm, 25 ràng buộc mỗi       | 24 344    | 68 094          |

"Rẻ" là một đọc trường trực tiếp như `Supply`; "dẫn xuất" là một được tính toán như `MigrateRateA`, chi phí khoảng 223 CU cho mỗi ràng buộc so với khoảng 48. Ngay cả một quy tắc được tải đầy đủ của các ràng buộc dẫn xuất vẫn ở trong một phần ba ngân sách mặc định 200 000 CU mỗi hướng dẫn, và một quy tắc ba nhóm thực tế dưới 6 000. Các nhóm được đánh giá cho đến khi một khớp, vì vậy đặt tầng phổ biến của bạn trước tiên là tiết kiệm miễn phí.

## Nơi đi tiếp theo

* [`products/launchlab/platform-config`](/vi/products/launchlab/platform-config) — các trường `PlatformConfig` gating và ủy quyền quy tắc.
* [`products/launchlab/global-config`](/vi/products/launchlab/global-config) — sàn giao thức mà quy tắc thu hẹp.
* [`products/launchlab/instructions`](/vi/products/launchlab/instructions) — bốn hướng dẫn quy tắc và tài khoản của chúng.
* [`products/launchlab/accounts`](/vi/products/launchlab/accounts) — `PlatformCurveRule` trong kho tài khoản.
* [`sdk-api/typescript-sdk`](/vi/sdk-api/typescript-sdk) — bề mặt SDK mà hai trợ giúp kiểm tra nằm trong.
* [`reference/changelog/2026-08-31-launchlab-platform-curve-rules`](/vi/reference/changelog/2026-08-31-launchlab-platform-curve-rules) — những gì thay thế danh sách trắng tham số đường cong, và những gì bộ giải mã phải thay đổi.

Nguồn:

* `raydium-launch/programs/launchpad/src/states/platform_curve_rule.rs` — `PlatformCurveRule`, `CurveRuleGroup`, `ParamConstraint`, không gian id trường và op, và `CurveRuleContext::value_of`.
* `raydium-launch/programs/launchpad/src/utils/platform_curve_rule.rs` — kiểm tra thời gian khởi chạy.
* `raydium-launch/programs/launchpad/src/instructions/platform/` — `create`, `update`, `remove`, và `close_platform_curve_rule`.
