Cross Program Invocation (CPI) là khi một chương trình gọi một lệnh trên chương trình khác trong quá trình thực thi. CPI cho phép khả năng kết hợp: bất kỳ lệnh nào của chương trình đều có thể được gọi bởi bất kỳ chương trình nào khác trên mạng.
Ví dụ về Cross Program Invocation
CPI không có người ký PDA
Sử dụng hàm invoke, Anchor CpiContext, ví dụ Native Rust, ví dụ CPI chuyển SOL.
CPI với người ký PDA
Sử dụng invoke_signed với signer seeds, Anchor CpiContext với PDA, ví dụ ký PDA Native Rust.
Thực thi CPI và đặc quyền
Quy trình thực thi CPI 11 bước, quy tắc mở rộng đặc quyền, reentrancy, xác thực tài khoản.
Mô hình chi phí CPI và đồng bộ dữ liệu
Công thức chi phí CPI, chi phí serialization, đồng bộ dữ liệu tài khoản, ký PDA, dữ liệu trả về.
Thông tin chính
- Hai hàm:
invoke(không ký PDA) vàinvoke_signed(có ký PDA). - Mở rộng đặc quyền: Đặc quyền tài khoản (người ký, có thể ghi) được mở rộng từ người gọi đến người được gọi. Người được gọi không thể nâng cao đặc quyền vượt quá những gì người gọi đã truyền.
- Ngân sách tính toán dùng chung: Mức tiêu thụ CU của người được gọi làm giảm ngân sách còn lại của người gọi.
- Reentrancy: Đệ quy trực tiếp được phép (A->A->A). Reentrancy gián tiếp
không được phép (A->B->A trả về
ReentrancyNotAllowed).
Giới hạn
| Giới hạn | Giá trị | Nguồn |
|---|---|---|
| Độ sâu ngăn xếp lệnh tối đa | 5 (9 với SIMD-0268) | MAX_INSTRUCTION_STACK_DEPTH, MAX_INSTRUCTION_STACK_DEPTH_SIMD_0268 |
| Chi phí gọi CPI | 1.000 CU (946 với SIMD-0339) | DEFAULT_INVOCATION_COST, INVOKE_UNITS_COST_SIMD_0339 |
| Số người ký PDA tối đa mỗi CPI | 16 | MAX_SIGNERS |
| Dữ liệu lệnh CPI tối đa | 10 KiB (10.240 byte) | MAX_INSTRUCTION_DATA_LEN |
| Dữ liệu trả về tối đa | 1.024 byte | MAX_RETURN_DATA |
| Số account info CPI tối đa | 128 (255 với SIMD-0339)* | MAX_CPI_ACCOUNT_INFOS, MAX_CPI_ACCOUNT_INFOS_SIMD_0339 |
| Chi phí serialization CPI | 1 CU mỗi 250 byte | cpi_bytes_per_unit |
| Cấp phát lại dữ liệu tài khoản tối đa mỗi CPI | 10.240 byte (10 KiB) | MAX_PERMITTED_DATA_INCREASE |
invoke so với invoke_signed
Solana cung cấp hai hàm để thực hiện CPI:
| Hàm | Trường hợp sử dụng | Ký PDA |
|---|---|---|
invoke | CPI khi tất cả người ký cần thiết đã ký giao dịch ban đầu | Không |
invoke_signed | CPI khi chương trình gọi cần ký thay mặt cho PDA mà nó sở hữu | Có, thông qua signer seeds |
Về cơ bản, invoke chỉ đơn giản gọi invoke_signed với một mảng signer
seeds rỗng. Sử dụng invoke khi bạn không cần ký PDA, và
invoke_signed khi chương trình phải ủy quyền một hành động thay mặt cho
PDA.
Cả hai hàm cuối cùng đều kích hoạt cùng một syscall
(sol_invoke_signed_rust)
và đi qua cùng một đường dẫn runtime
(cpi_common).
Sự khác biệt duy nhất là liệu signer seeds có được cung cấp hay không. Khi seeds
được cung cấp, runtime sẽ tạo ra các pubkey PDA và thêm chúng vào tập hợp các
signer hợp lệ trước khi kiểm tra đặc quyền.
Is this page helpful?