Визначення
CPI (Cross-Program Invocation) — це механізм у Solana, який дозволяє одній програмі викликати інструкції іншої програми безпосередньо під час власного виконання. Іншими словами, CPI дає змогу смарт-контрактам взаємодіяти між собою на рівні байт-коду, а не через зовнішні транзакції.
Це ключова архітектурна особливість Solana: замість того, щоб кожна програма реалізовувала всю логіку самостійно, вона делегує стандартні операції спеціалізованим програмам — насамперед SPL Token, System Program чи Account Compression.
Як працює
Коли програма виконує CPI, відбувається таке:
- Формування інструкції. Програма створює нову інструкцію — з тим самим форматом, що й у звичайній транзакції: облікові записи, дані, program_id.
- Передача контексту. Solana Runtime перевіряє, чи має поточна програма право передати кожен обліковий запис до виклику. Облікові записи, які програма отримала як доступні для запису (writable), можуть бути передані далі; ті, що лише для читання — залишаються такими.
- Виконання. Runtime завантажує цільову програму і виконує інструкцію в межах тієї ж транзакції. Зміни в облікових записах фіксуються спільно після успішного завершення всього ланцюжка.
- Вкладеність. 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.
Пов'язані матеріали
Внутрішні переходи
- PDA (Program Derived Address) — як програми отримують адреси для підпису під час CPI
- IDL (Interface Definition Language) — як описується інтерфейс програми для коректних викликів