You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Solana/Rust中检测函数调用者(类似Solidity的msg.sender)

在Solana/Rust中检测函数调用者并限制特定钱包访问

作为从以太坊转Solana的开发者,你需要先明确两者核心模型的差异:以太坊通过msg.sender直接标识调用者,而Solana的交易由签名者账户授权,程序需通过交易中的签名者列表识别发起者。

1. 实现类似Solidity msg.sender的调用者检测

在Solana Rust程序中,交易的签名者会被包含在accounts参数里,通常第一个签名者账户就是发起交易的用户钱包(对应以太坊的msg.sender)。具体实现代码如下:

use solana_program::{
    account_info::AccountInfo, entrypoint, entrypoint::ProgramResult, pubkey::Pubkey,
    program_error::ProgramError,
};

entrypoint!(process_instruction);

fn process_instruction(
    _program_id: &Pubkey,
    accounts: &[AccountInfo],
    _instruction_data: &[u8],
) -> ProgramResult {
    // 取出账户列表中的第一个签名者账户
    let caller_account = &accounts[0];

    // 必须验证该账户是交易签名者,防止未授权调用
    if !caller_account.is_signer {
        return Err(ProgramError::MissingRequiredSignature);
    }

    // 获取调用者公钥,对应Solidity的msg.sender
    let caller_pubkey = caller_account.key;

    // 后续业务逻辑...
    Ok(())
}

2. 限制仅特定钱包调用函数

拿到调用者公钥后,只需将其与预设的允许钱包地址对比,不匹配则返回错误即可:

// 替换为你允许的钱包公钥
const ALLOWED_WALLET: &str = "FjGQx6zZbX7E8Y9WqR3T4Y6U7I8O0P1A2S3D4F5G6H7J8K9L";

fn process_instruction(
    _program_id: &Pubkey,
    accounts: &[AccountInfo],
    _instruction_data: &[u8],
) -> ProgramResult {
    let caller_account = &accounts[0];
    if !caller_account.is_signer {
        return Err(ProgramError::MissingRequiredSignature);
    }
    let caller_pubkey = caller_account.key;

    // 解析允许的钱包公钥
    let allowed_pubkey = Pubkey::from_str(ALLOWED_WALLET)?;

    // 对比公钥,限制访问
    if caller_pubkey != &allowed_pubkey {
        // 可使用标准错误或自定义错误返回
        return Err(ProgramError::InvalidAccountData);
    }

    // 仅允许的钱包可执行的业务逻辑
    Ok(())
}

关键注意事项

  • 账户顺序很重要:如果程序需要多个签名者,要确保调用者账户在预期的列表位置;
  • 必须验证is_signer:即使账户在列表中,也需确认它签署了交易,避免未授权调用;
  • 自定义错误优化:可以定义专属的程序错误类型,替代标准错误,让调用者更清晰知晓失败原因。

内容的提问来源于stack exchange,提问作者Muhammad Abdullah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 18:40:49