Перейти к основному содержанию

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.

Эта страница переведена с помощью ИИ. За эталон принимается английская версия.Открыть английскую версию →
Модель аккаунтов Solana — наиболее важная вещь, которую необходимо понять перед чтением кода Raydium. В отличие от Ethereum, где состояние хранится вместе с кодом контракта, программы Solana полностью без состояния: все состояние живёт в отдельных “аккаунтах”, с которыми работают программы. Каждый пул Raydium, позиция и хранилище — это аккаунт. Понимание того, как работают эти аккаунты, делает остальную документацию понятной.

Фундаментальное разделение: программы и аккаунты

Программы

Программа на Solana — это исполняемый код, скомпилированный бинарный файл, загруженный из файла, развёрнутый на Pubkey и вызываемый через транзакции. Программы не имеют связанного состояния; они содержат только логику. Программы Raydium:
  • CPMM: CPMMoo8L3F4NbTegBCKVNunggL7H1Zpdmwpwh8KMoZ0F
  • CLMM: CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK
  • AMM v4: 675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8
Каждая — это фиксированный бинарный файл. Программа “не помнит” ничего между вызовами.

Аккаунты

Аккаунт — это строка данных в блокчейне. Каждый аккаунт имеет:
  • pubkey — его адрес.
  • owner — программу, которой он принадлежит (контролирует запись).
  • data — сырые байты.
  • lamports — баланс SOL (1 SOL = 1 000 000 000 lamports).
  • rent_epoch — устаревшее поле для сбора rent (игнорируется с тех пор, как rent-exemption стал обязательным).
Когда вы запрашиваете пул Raydium, вы читаете один или несколько аккаунтов. Когда происходит swap, программа CPMM читает/записывает несколько аккаунтов — состояние пула, хранилища, состояние наблюдения и аккаунты токенов пользователя.

Владение

Каждым аккаунтом владеет ровно одна программа. Только код этой программы может изменять поле data аккаунта. Пользователь может изменять lamports (отправлять/получать SOL) на аккаунте, за который он может подписать, но изменение data требует, чтобы программа-владелец сделала это от его имени. Примеры:
  • Ваш кошелёк пользователя: принадлежит System Program. Lamports хранятся здесь; вы подписываете для перевода.
  • Ваш аккаунт токена USDC: принадлежит SPL Token Program. Инструкция transfer программы токенов обновляет баланс.
  • Аккаунт состояния пула Raydium: принадлежит программе CPMM. Только инструкции CPMM могут изменять резервы, комиссии и т. д.
  • PersonalPositionState NFT позиции Raydium: принадлежит программе CLMM.
“Принадлежит” — это строго: если программа A записывает в аккаунт, принадлежащий программе B, Solana runtime отклоняет транзакцию.

Rent и rent-exemption

Создание аккаунта потребляет место в хранилище. Solana взимает плату за это место, но с 2020 года все новые аккаунты должны быть rent-exempt — это означает, что они хранят достаточно lamports, чтобы заранее была оплачена rent, которую они будут должны в течение 2 лет. На практике:
  • Аккаунт, освобождённый от rent, существует вечно.
  • Закрытие аккаунта возвращает lamports подписавшему инструкцию.
Для аккаунта размером 165 байт (например, аккаунт SPL Token), rent-exemption составляет ~0,00204 SOL. Для состояния пула Raydium CPMM размером ~1440 байт это ~0,011 SOL.

Стоимость rent в Raydium

АккаунтРазмерRent
CPMM PoolState~1 440 B~0,011 SOL
CLMM PoolState~1 500 B~0,012 SOL
CLMM TickArray~9 000 B~0,063 SOL
CLMM PersonalPositionState~280 B~0,003 SOL
ATA165 B~0,002 SOL
Vault (Token Account)165 B~0,002 SOL
Создание пула требует rent для нескольких аккаунтов одновременно — вот почему создание пула CPMM стоит в сумме ~0,15 SOL.

Data-аккаунты и executable-аккаунты

Аккаунты бывают двух типов:

Data-аккаунты

Хранят состояние (резервы пула, балансы токенов, позиции пользователей). executable = false. Это подавляющее большинство.

Executable-аккаунты

Хранят байт-код программы. executable = true. Это программы (CPMM, CLMM и т. д.). Программы не имеют данных сверх своего байт-кода.

Program-derived accounts (PDA)

PDA — это data-аккаунт, адрес которого детерминировано выведен из программы и некоторых seeds — для этого адреса не существует приватного ключа. Только программа-производитель может подписать от имени PDA через invoke_signed. Raydium широко использует PDA:
  • PDA состояния пула: выведены из [poolTypeDiscriminator, mintA, mintB, ammConfig].
  • PDA хранилищ: выведены из [pool, mint].
  • PDA состояния наблюдения: выведена из [observationSeed, pool].
PDA позволяют Raydium создавать аккаунты по предсказуемым адресам без управления ключами. Кто угодно может вычислить адрес PDA для известного пула, зная seeds. См. solana-fundamentals/pdas-and-cpis.

Транзакции и ссылки на аккаунты

Каждая транзакция Solana содержит явный список аккаунтов, которые она будет читать/писать. Runtime обеспечивает:
  • Перечисленные аккаунты могут быть прочитаны или записаны (согласно их флагу is_writable).
  • Неперечисленные аккаунты не могут быть затронуты.
Для swap в Raydium список аккаунтов транзакции включает:
[readonly] CPMM program
[writable] pool state
[readonly] amm config
[readonly] pool authority (PDA)
[writable] input vault
[writable] output vault
[writable] user input ATA
[writable] user output ATA
[readonly] input mint
[readonly] output mint
[readonly] input token program
[readonly] output token program
[writable] observation state
[signer,writable] user
Это явное перечисление — причина, по которой транзакции Solana быстрые и параллелизуемые — runtime может заранее определить неконфликтующие транзакции.

Размер аккаунта и расположение данных

Каждый аккаунт Raydium имеет фиксированный или ограниченный размер. Расположение определено в коде (структуры Rust с #[repr(C)]) и задокументировано в sdk-api/anchor-idl. Программы Anchor добавляют 8-байтовый дискриминатор к каждому создаваемому ими аккаунту, выведённый из hash("account:<StructName>")[0..8]. Это позволяет клиентам определить тип аккаунта, просто прочитав первые 8 байт — критично для сканирований getProgramAccounts, которые перечисляют все аккаунты типа.

Чтение состояния пула Raydium

Через SDK:
const pool = await raydium.cpmm.getPoolInfoFromRpc({ poolId });
console.log(pool.poolInfo);
Через сырой RPC + layout:
const accountInfo = await connection.getAccountInfo(poolId);
const data = accountInfo.data;
// Пропустить первые 8 байт (дискриминатор), затем распарсить согласно структуре layout.
const poolState = CpmmPoolStateLayout.decode(data.slice(8));
Layout находится в src/raydium/cpmm/layout.ts в исходниках SDK.

Практический пример: чтение аккаунта токена

Давайте прочитаем баланс USDC пользователя.
import { Connection, PublicKey } from "@solana/web3.js";
import { getAssociatedTokenAddressSync, AccountLayout } from "@solana/spl-token";

const connection = new Connection("https://api.mainnet-beta.solana.com");
const user       = new PublicKey("YourUserWallet...");
const usdcMint   = new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");

// 1. Вычислить адрес ATA (выведение стиля PDA).
const ata = getAssociatedTokenAddressSync(usdcMint, user);

// 2. Прочитать аккаунт.
const accountInfo = await connection.getAccountInfo(ata);
if (!accountInfo) {
  console.log("ATA ещё не существует (пользователь никогда не держал USDC).");
  return;
}

// 3. Проверить, что владелец — SPL Token program.
console.assert(accountInfo.owner.toBase58() === "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");

// 4. Декодировать данные.
const parsed = AccountLayout.decode(accountInfo.data);
console.log("Баланс (наименьшие единицы):", parsed.amount.toString());
console.log("Mint:",                        new PublicKey(parsed.mint).toBase58());
console.log("Владелец:",                    new PublicKey(parsed.owner).toBase58());
Этот паттерн — выведение адреса, получение аккаунта, проверка владельца, декодирование — применяется к каждому читалу в блокчейне, включая пулы Raydium.

Почему это важно для Raydium

Модель аккаунтов формирует дизайн Raydium:
  • Состояние пула — это один аккаунт — всё о пуле (mints, резервы, комиссии, admin) живёт в одном аккаунте, принадлежащем программе пула.
  • LP-токены — это стандартные аккаунты SPL токенов — Raydium делегирует токенизацию программе SPL Token.
  • Tick arrays разбиты на части — CLMM не может иметь один растущий массив ticks, потому что аккаунты имеют фиксированный выделенный размер; вместо этого она использует разбитые на части PDA TickArray.
  • NFT позиций — это Metaplex NFT — позиции CLMM — это стандартные NFT по Metaplex; состояние позиции — это отдельный PDA.
Понимание этого позволяет вам правильно ответить на вопросы “где живёт X?”:
  • “Где резервы пула?” → два аккаунта хранилищ (token accounts), принадлежащие SPL Token program, с полномочиями делегированы PDA программы пула.
  • “Где данные ticks для CLMM?” → серия TickArray PDA, каждая охватывающая 60 последовательных ticks.
  • “Где моя ставка фермы?” → PDA UserLedger, выведённая из [user, farmId], принадлежащая программе фермы.

Ссылки

Источники: