> ## 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, ориентированная на аккаунты — аккаунты хранят состояние, программы представляют собой код без состояния, работающий с аккаунтами. Rent, владение, программные аккаунты и аккаунты с данными — и что это значит при чтении состояния пула Raydium.

<Info>
  **Эта страница переведена с помощью ИИ. За эталон принимается английская версия.**

  [Открыть английскую версию →](/solana-fundamentals/account-model)
</Info>

Модель аккаунтов 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 |
| ATA                        | 165 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`](/ru/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`](/ru/sdk-api/anchor-idl).

Программы Anchor добавляют 8-байтовый **дискриминатор** к каждому создаваемому ими аккаунту, выведённый из `hash("account:<StructName>")[0..8]`. Это позволяет клиентам определить тип аккаунта, просто прочитав первые 8 байт — критично для сканирований `getProgramAccounts`, которые перечисляют все аккаунты типа.

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

Через SDK:

```ts theme={null}
const pool = await raydium.cpmm.getPoolInfoFromRpc({ poolId });
console.log(pool.poolInfo);
```

Через сырой RPC + layout:

```ts theme={null}
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 пользователя.

```ts theme={null}
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]`, принадлежащая программе фермы.

## Ссылки

* [`solana-fundamentals/programs-and-anchor`](/ru/solana-fundamentals/programs-and-anchor) — как программы обрабатывают аккаунты.
* [`solana-fundamentals/pdas-and-cpis`](/ru/solana-fundamentals/pdas-and-cpis) — выведение PDA и CPI.
* [`solana-fundamentals/transactions-and-fees`](/ru/solana-fundamentals/transactions-and-fees) — как аккаунты ссылаются в транзакциях.
* [`sdk-api/anchor-idl`](/ru/sdk-api/anchor-idl) — layouts аккаунтов для программ Raydium.

Источники:

* [Solana Account docs](https://docs.solana.com/developing/programming-model/accounts).
* [SPL Token program](https://spl.solana.com/token) — где живут token accounts.
