Skip to main content
Эта страница переведена с помощью ИИ. За эталон принимается английская версия.Открыть английскую версию →
Модель аккаунтов 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 стоит в сумме ~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 список аккаунтов транзакции включает:
Это явное перечисление — причина, по которой транзакции Solana быстрые и параллелизуемые — runtime может заранее определить неконфликтующие транзакции.

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

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

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

Через SDK:
Через сырой RPC + layout:
Layout находится в src/raydium/cpmm/layout.ts в исходниках SDK.

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

Давайте прочитаем баланс USDC пользователя.
Этот паттерн — выведение адреса, получение аккаунта, проверка владельца, декодирование — применяется к каждому читалу в блокчейне, включая пулы 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], принадлежащая программе фермы.

Ссылки

Источники: