pub mod instruct;
pub mod process;
use {crate::process::process_instruction, solana_program::entrypoint};
entrypoint!(process_instruction);Let's break this down:
-
pub mod instruct;andpub mod process;: These lines declare public modules. Modules in Rust are ways to organize code. Here, we're saying that there are two modules named "instruct" and "process" that are part of this program. -
use {crate::process::process_instruction, solana_program::entrypoint};: This line is importing (bringing into scope) theprocess_instructionfunction from theprocessmodule in the current crate (crate means package in Rust), and theentrypointmacro from thesolana_programcrate. -
entrypoint!(process_instruction);: This is using theentrypointmacro to declare thatprocess_instructionis the entry point of this Solana program. When the program is invoked, this function will be called.
use borsh::{BorshDeserialize, BorshSerialize};
use solana_program::{
account_info::AccountInfo,
entrypoint::ProgramResult,
pubkey::Pubkey
};
use crate::instruct::*;
#[derive(BorshSerialize, BorshDeserialize, Debug)]
pub enum NativeVaultInstruction {
Initialize(),
Deposit(u64),
PartialWithdraw(),
}
pub fn process_instruction(
program_id: &Pubkey,
accounts : &[AccountInfo],
input : &[u8],
) -> ProgramResult {
let instruction: NativeVaultInstruction = NativeVaultInstruction::try_from_slice(input)?;
match instruction {
NativeVaultInstruction::Initialize() => initialize(
program_id,
accounts,
),
NativeVaultInstruction::Deposit(args) => deposit(
program_id,
accounts,
args
),
NativeVaultInstruction::PartialWithdraw() => partial_withdraw(
program_id,
accounts,
),
}
}Let's break this down:
-
The
usestatements at the top are importing necessary types and traits from theborshandsolana_programcrates, as well as everything from theinstructmodule. -
#[derive(BorshSerialize, BorshDeserialize, Debug)]: This is an attribute that automatically implements serialization, deserialization, and debug formatting for the following enum. -
pub enum NativeVaultInstruction: This defines an enumeration of the possible instructions that this program can handle: Initialize, Deposit, and PartialWithdraw. -
pub fn process_instruction: This is the main entry point of the program. It takes three parameters:program_id: The public key of the program.accounts: A slice ofAccountInfostructures, representing the accounts involved in the transaction.input: A byte slice containing the instruction data.
-
Inside
process_instruction:- It first deserializes the
inputinto aNativeVaultInstruction. - Then it uses a
matchstatement to call the appropriate function based on the instruction type.
- It first deserializes the
This file contains the main logic of the program. Let's break it down into sections:
use borsh::{BorshDeserialize, BorshSerialize};
use solana_program::{
account_info::{next_account_info, AccountInfo},
entrypoint::ProgramResult,
program::{invoke, invoke_signed},
program_error::ProgramError,
pubkey::Pubkey,
rent::Rent,
system_instruction, sysvar::{clock::Clock, Sysvar},
};
#[derive(BorshSerialize, BorshDeserialize, Debug)]
pub struct Vault {
pub owner : Pubkey,
}
#[derive(BorshSerialize, BorshDeserialize, Debug)]
pub struct Pda {
pub signer : Pubkey,
pub balance : u64,
pub deposit_time: i64,
pub done : bool,
}
pub const DELAY: i64 = 10;
pub const TAG_SSF_PDA: &[u8; 9] = b"SOL_VAULT";This section imports necessary modules and defines two structs: Vault and Pda. It also defines some constants.
pub fn initialize(
program_id: &Pubkey,
accounts : &[AccountInfo]
) -> ProgramResult {
// ... (implementation details)
}This function initializes a new vault. It:
- Extracts necessary accounts from the
accountsslice. - Calculates the minimum rent required for the vault account.
- Creates a new account for the vault.
- Initializes the vault data.
pub fn deposit(
program_id: &Pubkey,
accounts : &[AccountInfo],
amount : u64
) -> ProgramResult {
// ... (implementation details)
}This function handles depositing SOL into a Program Derived Address (PDA). It:
- Extracts necessary accounts.
- Derives the PDA.
- Initializes the PDA if it's new.
- Updates the PDA's balance and timestamp.
- Transfers SOL from the user to the PDA.
pub fn partial_withdraw(
program_id: &Pubkey,
accounts : &[AccountInfo]
) -> ProgramResult {
// ... (implementation details)
}This function handles partial withdrawal from the PDA. It:
- Extracts necessary accounts.
- Derives the PDA.
- Checks if enough time has passed since the deposit.
- Calculates and transfers 1/10th of the balance to the user.
- Marks the PDA as "done" to prevent further withdrawals.
Each of these functions uses various Solana-specific concepts like PDAs, rent, system instructions, and more. They also handle error cases and perform necessary checks to ensure the security and correctness of the operations.