In this lesson, you'll learn about:
invoke()
function in Solana.Solana's invoke()
function enables program calls without the need for
Signers. It is essential for routing instructions, accounts, and data to the callee program. A Cross-Program Invocation (CPI) is created by defining the accessed accounts and the instruction data. CPIs in Solana allow for limited depth reentrancy. We'll demonstrate how to use CPI by calling a lever program in our code example.
The invoke
function is crucial when making a CPI that does not require any Program-Derived Addresses (PDAs) to act as signers. In such CPIs, Solana runtime extends the original signature passed into a program to the callee program.
When calling a program, you often find libraries with useful functions to create the Instruction. These libraries, typically developed by individuals or groups, simplify the process of calling their programs.
The definition of the Instruction
type required for a CPI includes:
invoke()
is integrated into Solana's runtime, managing the routing of the given instruction to another program via the instruction's program_id
field.accounts
- a list of AccountInfo
corresponding to all accounts accessed by the callee program.data
- instruction data formatted to be understood by the callee program.The AccountInfo structures provided to this function contain data utilized by the runtime. This data is transferred to and from the memory space of the program being called.
Cross-program invocations allow programs to call other programs, but currently, this capability is limited to a depth of four.
Reentrancy is currently permitted only in cases of direct self-recursion and is constrained to a predetermined depth. This restriction aims to prevent scenarios where a program might inadvertently call another program from an intermediary state. Direct recursion ensures that the program has full control over its state when it is re-invoked.
To effectively use invoke
and invoke_signed
, a list of account_infos
is also necessary. Similar to the list of AccountMeta
in the instructions, it is crucial to include all AccountInfo
for each account that the callee program will access.
Since programs can only receive AccountInfo values from the runtime at the program's entry point, any account required by the callee program must also be needed by the calling program and provided by its caller. This rule also applies to the program ID of the callee program.
Below is a code example demonstrating how CPIs are created to interact with a leverProgram by calling their switchPower
function:
function pullLever(address dataAccount, string name) public {
// Account required by the switchPower instruction.
// This is the data account created by the lever program (not this program), storing the state of the switch.
AccountMeta[1] metas = [
AccountMeta({pubkey: dataAccount, is_writable: true, is_signer: false})
];
// Data required by the switchPower instruction.
string instructionData = name;
// Invoke the switchPower instruction on the lever program.
leverProgram.switchPower{accounts: metas}(instructionData);
}
In this code snippet, we define a pullLever
function, accepting dataAccount
and name
as parameters. The function configures the AccountMeta
for the lever program's data account, then assigns name
as the instruction data. Utilizing Cross-Program Invocation (CPI), it calls the switchPower
method in the lever program. This results in the construction of a CPI, and the Solana runtime generates an invoke()
call, providing the requisite accountInfos
and instructionData
.
When defining a CPI, the syntax for
Specifying the AccountMeta
for each account includes:
AccountMeta::new
- This signifies that the account is writable.AccountMeta::new_readonly
- This denotes that the account is not writable.(pubkey, true)
- Indicates that the account is a signer.(pubkey, false)
- Implies that the account is not a signer.Typically, the Instruction
is constructed within the calling program. However, it's also possible to source the Instruction
externally through deserialization.
In our upcoming lesson, we will focus on writing tests for the CPI Flip program, demonstrating how to ensure that the CPI integration works correctly and efficiently within the Solana framework.