如何使用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
相关产品推荐
相关产品推荐

