如何在Solana上获取智能合约部署作者的公钥信息
Solana 智能合约获取/存储部署者信息的方法
Solana的链上程序(即智能合约)本身不会默认存储部署者(部署交易的签名账户)的公钥信息,因此你直接从程序的AccountInfo结构中无法提取到对应字段。
和你在Solidity构造函数中存_owner到合约存储槽的逻辑一致,Solana也需要手动存储部署者信息,区别在于Solana没有合约内置存储的概念,所有状态都存储在独立的链上账户中,具体实现方式如下:
核心实现逻辑
- 提前创建一个专门用于存储程序全局配置的状态账户(推荐用PDA生成,避免地址冲突),预留
owner字段用于存储部署者公钥 - 程序部署完成后,由部署者作为签名者发送第一笔交易调用程序的初始化指令,在指令逻辑中将交易签名者的公钥存入状态账户的
owner字段
代码示例(基于Anchor框架)
// 声明程序配置PDA的存储结构 #[account] pub struct ProgramConfig { pub owner: Pubkey, // 存储部署者公钥 } // 初始化指令的账户校验结构 #[derive(Accounts)] pub struct Initialize<'info> { // 部署者作为交易签名者 #[account(mut)] pub deployer: Signer<'info>, // 初始化程序配置PDA账户 #[account( init, payer = deployer, space = 8 + 32, // 8字节Anchor标识 + 32字节公钥长度 seeds = [b"program-config"], bump )] pub program_config: Account<'info, ProgramConfig>, pub system_program: Program<'info, System>, } // 初始化指令逻辑,对应Solidity构造函数逻辑 pub fn initialize(ctx: Context<Initialize>) -> Result<()> { let program_config = &mut ctx.accounts.program_config; // 将部署者公钥写入配置账户 program_config.owner = ctx.accounts.deployer.key(); Ok(()) } // 校验调用者是否为所有者的方法,对应你实现的isOwner方法 #[derive(Accounts)] pub struct CheckOwner<'info> { pub caller: Signer<'info>, pub program_config: Account<'info, ProgramConfig>, } pub fn is_owner(ctx: Context<CheckOwner>) -> Result<bool> { Ok(ctx.accounts.caller.key() == ctx.accounts.program_config.owner) }
补充说明
- 如果你要查询的是已经部署、且没有在初始化逻辑中存储
owner信息的链上程序,无法直接从链上状态获取部署者公钥,只能通过查询该程序地址的历史部署交易签名者信息间接获取 - 部分开源Solana程序会在自定义元数据中写入部署者信息,但这属于项目自定义实现,不是链上默认规则
内容的提问来源于stack exchange,提问作者laitmiro
相关产品推荐
相关产品推荐

