Визначення

CPI (Cross-Program Invocation) — це механізм у Solana, який дозволяє одній програмі викликати інструкції іншої програми безпосередньо під час власного виконання. Іншими словами, CPI дає змогу смарт-контрактам взаємодіяти між собою на рівні байт-коду, а не через зовнішні транзакції.

Це ключова архітектурна особливість Solana: замість того, щоб кожна програма реалізовувала всю логіку самостійно, вона делегує стандартні операції спеціалізованим програмам — насамперед SPL Token, System Program чи Account Compression.

Як працює

Коли програма виконує CPI, відбувається таке:

  1. Формування інструкції. Програма створює нову інструкцію — з тим самим форматом, що й у звичайній транзакції: облікові записи, дані, program_id.
  2. Передача контексту. Solana Runtime перевіряє, чи має поточна програма право передати кожен обліковий запис до виклику. Облікові записи, які програма отримала як доступні для запису (writable), можуть бути передані далі; ті, що лише для читання — залишаються такими.
  3. Виконання. Runtime завантажує цільову програму і виконує інструкцію в межах тієї ж транзакції. Зміни в облікових записах фіксуються спільно після успішного завершення всього ланцюжка.
  4. Вкладеність. CPI може бути вкладеним: програма A викликає B, B викликає C. Максимальна глибина — 4 рівні. Перевищення призводить до помилки виконання.

Важливий нюанс: під час CPI підписувачем може виступати PDA (Program Derived Address). Програма передає seeds у Runtime, той відтворює адресу і, якщо вона збігається, дозволяє підпис. Це єдиний спосіб, яким програма в Solana може легітимно підписати транзакцію від свого імені.

Приклад

Уявіть децентралізовану біржу (DEX), де користувач обмінює токени. Сама програма DEX не містить логіки переказу токенів — це було б дублюванням коду. Натомість під час виконання обміну DEX робить CPI до SPL Token Program з інструкцією transfer, передаючи облікові записи токенів користувача та пулу, а також PDA-підписувача від імені біржі.

Усе відбувається в одній транзакції: якщо хоча б один крок (перевірка балансу, CPI-переказ, оновлення стану пулу) завершується помилкою — відкочуються всі зміни.

Типова помилка

Найчастіша помилка при роботі з CPI — неправильна передача прав на облікові записи. Якщо цільова програма очікує обліковий запис як writable, а викликаюча програма передала його як readonly, Runtime відхилить виклик. Це особливо болісно при вкладених CPI, де на кожному рівні права можуть звужуватися.

Друга поширена помилка — невідповідність seeds для PDA-підписувача. Якщо програма передає інший набір seeds, ніж той, за яким PDA було створено, підпис не буде підтверджено, і CPI завершиться помилкою Secp256k1SignatureVerificationFailure або InvalidSeeds.

Пов'язані матеріали

Внутрішні переходи