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

如何使用SolNet获取PDA数据?将Solana/Anchor JS代码迁移至.NET

使用SolNet获取Solana PDA账户数据(对应Anchor的program.account.fetch)

步骤1:生成PDA地址

对应JavaScript中的findProgramAddress,用SolNet生成目标PDA:

using Solnet.Wallet;

// 定义种子与程序ID
byte[] seed1 = System.Text.Encoding.UTF8.GetBytes("project");
string projectId = "你的项目ID";
byte[] seed2 = System.Text.Encoding.UTF8.GetBytes(projectId.Substring(0, 18));
byte[] seed3 = System.Text.Encoding.UTF8.GetBytes(projectId.Substring(18, 36));

PublicKey programId = new PublicKey("你的程序ID");

// 生成PDA和对应的bump值
(PublicKey projectPDA, byte bump) = PublicKey.FindProgramAddress(new List<byte[]> { seed1, seed2, seed3 }, programId);

步骤2:定义Anchor账户的C#模型

Anchor账户数据基于Borsh序列化,需要根据你的IDL结构定义对应C#类,确保字段顺序与IDL一致:

using Solnet.Wallet;
using Solnet.Borsh;

[BorshContract]
public class ProjectParameter
{
    [BorshProperty(0)]
    public List<Signatory> Signatories { get; set; }
    
    [BorshProperty(1)]
    public TransferAmount TransferAmount { get; set; }
}

[BorshContract]
public class Signatory
{
    [BorshProperty(0)]
    public PublicKey Key { get; set; }
}

[BorshContract]
public class TransferAmount
{
    [BorshProperty(0)]
    public PublicKey Reciever { get; set; }
    
    [BorshProperty(1)]
    public ulong Amount { get; set; }
}

步骤3:获取并反序列化PDA账户数据

通过SolNet的RPC客户端获取账户数据,去掉Anchor账户的8字节前缀后反序列化:

using Solnet.Rpc;
using Solnet.Rpc.Models;
using Solnet.Borsh;

// 创建RPC连接
IRpcClient rpcClient = ClientFactory.GetClient(Cluster.TestNet); // 按需切换主网/测试网

// 获取账户原始数据
RequestResult<AccountInfo> accountInfoResult = await rpcClient.GetAccountInfoAsync(projectPDA);

if (!accountInfoResult.WasSuccessful)
{
    Console.WriteLine($"获取失败: {accountInfoResult.Error.Message}");
    return;
}

// 移除Anchor账户的8字节前缀,再反序列化
byte[] rawData = accountInfoResult.Result.Data[0];
byte[] targetData = rawData.Skip(8).ToArray();

ProjectParameter state = BorshSerializer.Deserialize<ProjectParameter>(targetData);

// 处理签名者数据
var sigs = state.Signatories.Select(s => new 
{
    Key = s.Key.ToBase58(),
    Text = s.Key.ToBase58(),
    Value = s.Key.ToBase58()
}).ToList();

// 打印接收者地址
Console.WriteLine(state.TransferAmount.Reciever.ToBase58());

关键注意点

  • Anchor账户前缀:所有Anchor账户数据开头都有8字节的discriminator,反序列化前必须跳过这部分。
  • Borsh序列化:SolNet的SolNet.Borsh包负责处理序列化逻辑,需确保BorshProperty的索引与IDL字段顺序完全匹配。
  • PDA一致性:PublicKey.FindProgramAddress与JS端findProgramAddress逻辑完全一致,生成的PDA和bump值完全匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 21:06:15