このページは AI による自動翻訳です。すべての内容は英語版を正とします。英語版を表示 →
Solana 上のあらゆる取引可能資産(Raydium プール内のすべてのベース資産とクォート資産を含む)は、2 つのプログラムのいずれか――レガシーの SPL Token プログラムか、その後継の Token-2022 プログラム――によってミントされたトークンです。これらは異なるアドレスにある別々のプログラムで、異なるアカウント構造と拡張機能セマンティクスを持ちます。Raydium は両方をサポートしていますが、すべての場所で対応しているわけではありません。CPMM、CLMM、Farm v6 は Token-2022 ミントを受け入れますが、AMM v4 は受け入れません。プールと統合する前に、この分割を理解することが不可欠です。
2 つのプログラム
| SPL Token | Token-2022 |
|---|
| プログラム ID | TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA | TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb |
| ローンチ | 2020 | 2022 |
| アカウントサイズ(トークンアカウント) | 165 B | 165 B + 拡張機能(可変) |
| 拡張機能 | なし | あり — 17 以上の公式拡張機能 |
| レガシー互換性 | 完全 | ミント単位でオプトイン |
両方とも Solana Labs チーム(現在は Anza)によって保守され、solana-program-library リポジトリ下にあります。
なぜ 2 つのプログラムなのか
SPL Token は前方互換性のために凍結されています――そのバイトコードは事実上不変であり、エコシステム全体の明確なベースラインになっています。ユースケースが増加するにつれ(ステーブルコインが転送手数料を求める、機関投資家のミントが微妙なフリーズ権限を必要とする、NFT がメタデータポインターを必要とするなど)、Solana チームは SPL Token をアップグレードするのではなく、Token-2022 を別の拡張可能なプログラムとして導入しました。これにより、既存の統合が保存され、各ミントは必要な拡張機能に正確にオプトインできます。
Token-2022 はアドレス空間ではなく機能の厳密なスーパーセットです――2 つのプログラムは共存し、与えられたアドレスのミントはそれらのうちの 1 つに正確に属します。
アカウント構造
ミントアカウント
トークンの識別を定義します。
SPL Token ミント(82 バイト):
u32 mint_authority_option
Pubkey mint_authority
u64 supply
u8 decimals
bool is_initialized
u32 freeze_authority_option
Pubkey freeze_authority
Token-2022 ミント:同じベース レイアウト + ベースの後に追加された 0 個以上の 拡張 TLV(型長値)レコード。
トークンアカウント
特定のミント、特定の所有者の残高を保有します。
SPL Token アカウント(165 バイト):
Pubkey mint
Pubkey owner
u64 amount
u32 delegate_option
Pubkey delegate
u8 state // initialized, frozen
u32 is_native_option
u64 is_native
u64 delegated_amount
u32 close_authority_option
Pubkey close_authority
Token-2022 アカウント:同じベース + アクティブな拡張機能がある場合は拡張 TLV レコード。
Token-2022 拡張機能
拡張機能は、ミントまたはアカウントに付加できるモジュール機能です。各拡張機能は個別の TLV レコードです。Raydium の主要なもの:
転送手数料
ミントはすべての転送に対してパーセンテージ手数料を課すことができます。手数料は設定された引き出し権限に移動します。Raydium CPMM と CLMM では SwapV2 を介してサポートされています――プログラムは交換レートを計算する際に手数料を考慮するため、プール数学は一貫性を保ちます。
let extension = TransferFeeConfig {
transfer_fee_config_authority,
withdraw_withheld_authority,
withheld_amount: 0,
older_transfer_fee: ...,
newer_transfer_fee: ...,
};
転送フック
ミントは、ランタイムがすべての転送で実行するプログラムを指します。フック プログラムは転送を拒否するか、副作用を実行できます(コンプライアンス状態を更新する、ログを出力するなど)。Raydium CPMM/CLMM は SwapV2 を介してフックを実行します――トランザクションにはフック プログラムとそれが必要とする追加アカウントが含まれます。
利息生成
チェーン上の残高は設定されたレートで利息が発生します。実際のミントではなく表示専用(残高は時間とともに見かけ上高くなります)。基礎となるサプライは変わりません。
ミント クローズ権限
サプライがゼロに達したら、ミントを閉じることができます。
永続デリゲート
指定されたウォレットは、任何のアカウントから無条件にトークンを転送またはバーンできます。Raydium はこの拡張機能を持つミント用のプール作成をブロックします――プール リザーブを没収できないという不変条件と互換性がありません。
非転送可能
トークンはミントされたアカウントから移動できません。Raydium はプール作成をブロックします――取引不可能な資産は LP プールのベースまたはクォートになることはできません。
デフォルト アカウント状態
このミント用の新しいトークンアカウントはデフォルトでフリーズされ、フリーズ権限によってアンフリーズされる必要があります。使用可能ですが珍しいです。
機密転送
残高と転送量は暗号化されます。Raydium は機密転送ミントをサポートしていません(プール数学には明文の残高が必要です)。
メタデータ ポインタ + トークン メタデータ
Token-2022 ミント用の Metaplex メタデータを置き換えます。Raydium プール リスティングでサポートされています。
グループ / メンバー ポインタ
ミントがグループに属していることを宣言します(例:NFT コレクション)。情報提供のみです。Raydium はこれを表示に使用します。
完全なリストについては、公式 Token-2022 拡張機能ページを参照してください。
Raydium 製品のサポート
| 製品 | SPL Token | Token-2022 | 注記 |
|---|
| AMM v4 | あり | なし | OpenBook 統合は SPL Token を必要とします |
| CPMM | あり | あり | Token-2022 プールの場合 SwapV2 が必須です |
| CLMM | あり | あり | Token-2022 プールの場合 SwapV2 が必須です |
| Farm v6 | あり | あり | ステーク ミントと報酬ミント両方でサポート |
| LaunchLab | あり | あり | 卒業した CPMM プールは Token-2022 サポートを継承します |
Raydium プールのミント適格性――特定されたもの以外はすべての拡張機能が許可されます:
- ブロック: 非転送可能、永続デリゲート、機密転送、デフォルト アカウント状態(拒否された設定)。
- 注意付きで許可(LP はリスクを受け入れる必要があります):転送手数料、転送フック、フリーズ権限がアクティブ。
- 完全に許可:利息生成、メタデータ ポインタ、グループ ポインタ、ミント クローズ権限。
getPoolInfoFromRpc レスポンスにはミントの拡張機能フラグが含まれます――LP する前に、クライアントがチェックする必要があります。
トークンアカウント標準
Associated Token Account(ATA)
両方のプログラムは Associated Token Account 慣例を共有します。これは Associated Token Program(ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL)を介して [owner, programId, mint] から導出された PDA です。Solana 上のほぼすべてのユーザー トークンアカウントが ATA です。
import { getAssociatedTokenAddressSync } from "@solana/spl-token";
// SPL Token
const ata = getAssociatedTokenAddressSync(mint, owner);
// Token-2022
const ata22 = getAssociatedTokenAddressSync(
mint,
owner,
false, // allowOwnerOffCurve
TOKEN_2022_PROGRAM_ID,
);
ATA プログラムは、ミントが所有しているプログラムに基づいて、適切なトークン プログラムが所有するアカウントを作成します。
非 ATA トークンアカウント
ウォレットは単一のミント用に複数のトークンアカウントを持つことができます。ATA は単なる慣例です。プール ボルト、例えば、ATA ではなく、プール プログラムの PDA で、プールの リザーブを保有しています。
ミントがどのプログラムに属しているかを検出
すべてのミントのアカウントには、SPL Token または Token-2022 のいずれかを指す owner フィールドがあります:
const mintInfo = await connection.getAccountInfo(mintPubkey);
if (mintInfo.owner.equals(TOKEN_PROGRAM_ID)) {
console.log("SPL Token mint");
} else if (mintInfo.owner.equals(TOKEN_2022_PROGRAM_ID)) {
console.log("Token-2022 mint");
}
Raydium SDK はこの検出を自動的に処理します――getPoolInfoFromRpc は適切な programId をトークンごとに返すため、クライアントは正しい ATA を構築できます。
プログラム別スワップ命令
Raydium の CPMM と CLMM のそれぞれに 2 つのスワップ命令があります:
| 命令 | サポートされたミント |
|---|
Swap / SwapBaseInput(レガシー) | SPL Token のみ |
SwapV2 / SwapBaseInputV2 | SPL Token と Token-2022 の両方 |
SwapV2 は追加のアカウントを取ります:両側のミント アカウント、各側のトークン プログラム(異なる可能性があるため)、および――転送フック ミント用――フック プログラムとその必要なアカウント。
クライアントは、少なくとも 1 つ側が Token-2022 の場合は常に SwapV2 を使用する必要があります。SwapV2 は SPL のみのプールでも動作しますが、レガシー Swap はコンピュート量で安いです。
SDK は自動的に正しいバリアントを選択します。
SPL Token プロジェクトを Token-2022 に移行
Token-2022 はミント レベルでは直接交換ではありません――アドレス X のミントは SPL または Token-2022 のいずれかであり、それは作成時に固定です。「移行」するには、次の操作を行う必要があります:
- 必要な拡張機能を使用して Token-2022 下に新しいミントを作成します。
- 古い SPL ミントの保有者が新しいミントと交換できるようにスワップ/ラップ メカニズムを提供します。
- すべての LP プール、ファーム、統合を更新して、新しいミントを参照します。
これは大変です。特定の拡張機能の必要性が移動を強制しない限り、SPL の下で起動したほとんどのプロジェクトは SPL の下に留まります。
実装例:転送手数料付き Token-2022 ミントの作成
import {
Connection, Keypair, SystemProgram, Transaction, sendAndConfirmTransaction,
} from "@solana/web3.js";
import {
TOKEN_2022_PROGRAM_ID, ExtensionType, createInitializeMintInstruction,
getMintLen, createInitializeTransferFeeConfigInstruction,
} from "@solana/spl-token";
const connection = new Connection("https://api.mainnet-beta.solana.com");
const payer = Keypair.generate();
const mint = Keypair.generate();
const extensions = [ExtensionType.TransferFeeConfig];
const mintLen = getMintLen(extensions);
const rentLamports = await connection.getMinimumBalanceForRentExemption(mintLen);
const tx = new Transaction().add(
SystemProgram.createAccount({
fromPubkey: payer.publicKey,
newAccountPubkey: mint.publicKey,
space: mintLen,
lamports: rentLamports,
programId: TOKEN_2022_PROGRAM_ID,
}),
createInitializeTransferFeeConfigInstruction(
mint.publicKey,
payer.publicKey, // transfer fee authority
payer.publicKey, // withdraw-withheld authority
50, // 50 bps = 0.5%
BigInt(1_000_000), // max fee per transfer (smallest units)
TOKEN_2022_PROGRAM_ID,
),
createInitializeMintInstruction(
mint.publicKey,
9, // decimals
payer.publicKey, // mint authority
null, // freeze authority
TOKEN_2022_PROGRAM_ID,
),
);
await sendAndConfirmTransaction(connection, tx, [payer, mint]);
このミントは Raydium CPMM プールに LP することができます。スワッパーはプールのスワップ手数料に加えて 0.5% の転送手数料を支払います。
セキュリティに関する考慮事項
Token-2022 ミントに LP したり、それを通じてスワップしたりする前に:
freeze_authority をチェックしてください。null でなく、中央集中党によって保有されている場合、彼らはあなたの ATA(およびおそらくプール ボルト)をフリーズできます。
transfer_hook をチェックしてください。フック プログラムは転送を恣意的にブロックできます――フックのソースに関する調査を行ってください。
transfer_fee をチェックしてください。予想されるスワップ出力で手数料を考慮します。
permanent_delegate と non_transferable をチェックしてください。Raydium のプログラムはこれらを拒否しますが、カスタム統合を構築している場合は確認します。
すべてのリスク受け入れフレームワークについては、security/oracle-and-token-risksを参照してください。
ポインタ
ソース: