解析Solana交易指令
本文将展示如何使用它们各自的IDL解析用Anchor框架编写的Solana上的原始交易。

一键发币: SUI | SOL | BNB | ETH | BASE | ARB | OP | POLYGON | AVAX | FTM | OK
你是否好奇过Shyft Translator和其他Solana浏览器是如何解析你的交易并以人类可读的格式显示的?在本文中,我们将向你展示如何解析一个使用Anchor框架编写的程序的交易,并将其转换为人类可读的格式。
1、获取IDL
要开始解析Anchor程序的交易,首先需要该程序的IDL。在Solana编程中,接口定义语言(IDL)指定了程序的公共接口,包括Solana程序的账户结构、指令和错误代码的定义。 IDL是.json
文件,用于生成客户端代码,使用户能够方便地与Solana程序交互。
本文将演示如何解析来自Metaplex Candy Machine V2的交易。你可以通过点击这里查看该程序的IDL。要找到你程序的IDL,请执行anchor build
命令来构建你的程序。构建过程完成后,IDL文件可以在以下路径找到:<your-program-root-folder>/target/idl/<your-program-name>.json
{
"version": "0.1.0",
"name": "demo_anchor",
"instructions": [
{
"name": "initialize",
"accounts": [
{
"name": "newAccount",
"isMut": true,
"isSigner": true
},
{
"name": "signer",
"isMut": true,
"isSigner": true
},
{
"name": "systemProgram",
"isMut": false,
"isSigner": false
}
],
"args": [
{
"name": "data",
"type": "u64"
}
]
}
],
"accounts": [
{
"name": "NewAccount",
"type": {
"kind": "struct",
"fields": [
{
"name": "data",
"type": "u64"
}
]
}
}
]
}
2、使用BorshCoder解码交易指令
一旦你获得了IDL文件,就可以开始解析交易了。下面的代码片段展示了如何实现这一点:
const { clusterApiUrl, Connection } = require('@solana/web3.js');
const fs = require('fs/promises');
const { BorshCoder } = require('@coral-xyz/anchor')
const connection = new Connection(
clusterApiUrl('mainnet-beta'), 'confirmed',
)
async function main() {
// 加载IDL文件
const fileContent = await fs.readFile('candy-machine-v2.json', 'utf-8');
const borshCoder = new BorshCoder(JSON.parse(fileContent));
// 示例签名
const txn = await connection.getTransaction('2zvo8i6VqcN9D9kZeqDJZCDC4FMak7HBfZXLGieFNhLi5aPWmoGMmnZtG14xPptdGtKP8uDemiSdmsxXC9WMz44Y');
// `4` 是与Candy Machine V2交互的指令索引
const instruction = txn.transaction.message.instructions[4]
const decodedIx = borshCoder.instruction.decode(instruction.data, 'base58')
const accountMetas = instruction.accounts.map(
(idx) => ({
pubkey: txn.transaction.message.accountKeys[idx],
isSigner: txn.transaction.message.isAccountSigner(idx),
isWritable: txn.transaction.message.isAccountWritable(idx),
}),
);
const formatted = borshCoder.instruction.format(decodedIx, accountMetas);
console.log({ name: decodedIx.name, ...formatted });
}
main();
执行上述代码后,结果将如下所示。name
字段表示函数名称,args
字段包含函数所需的参数列表,accounts
字段列出了此函数所需的账户。
{
name: 'mintNft',
args: [ { name: 'creatorBump', type: 'u8', data: '254' } ],
accounts: [
{
name: 'Candy Machine',
pubkey: [PublicKey [PublicKey(AcR4Hi7hxnyJdXY4HkcL2P94QrNYdkr4NNnfPPFK15Pg)]],
isSigner: false,
isWritable: true
},
{
name: 'Candy Machine Creator',
pubkey: [PublicKey [PublicKey(5TK4BXYVUQrpgxKHNn89kExpGnZSjoFQZ9w172oDv7Dq)]],
isSigner: false,
isWritable: false
},
{
name: 'Payer',
pubkey: [PublicKey [PublicKey(CNLE75xYtJXqiaYovC5gb7BGrKAzqXTLKNgdPskqTAtr)]],
isSigner: true,
isWritable: true
},
{
name: 'Wallet',
pubkey: [PublicKey [PublicKey(RTieWhhgy4j3Gr5FkUXX5MLpyEeaFJbquJ4xE8nsidE)]],
isSigner: false,
isWritable: true
},
{
name: 'Metadata',
pubkey: [PublicKey [PublicKey(EsW67JUMP8s5vRjNPVHGTJ5rHv9VvFxEkMzmRy91NS7o)]],
isSigner: false,
isWritable: true
},
{
name: 'Mint',
pubkey: [PublicKey [PublicKey(3nGmvv2zvm6JPe7THs56BZak3oUsqjYd7nvGypgBQZjH)]],
isSigner: true,
isWritable: true
},
{
name: 'Mint Authority',
pubkey: [PublicKey [PublicKey(CNLE75xYtJXqiaYovC5gb7BGrKAzqXTLKNgdPskqTAtr)]],
isSigner: true,
isWritable: true
},
{
name: 'Update Authority',
pubkey: [PublicKey [PublicKey(CNLE75xYtJXqiaYovC5gb7BGrKAzqXTLKNgdPskqTAtr)]],
isSigner: true,
isWritable: true
},
{
name: 'Master Edition',
pubkey: [PublicKey [PublicKey(9B3Q5ddBP7EZ6PAAmxSgf1ZoPQrjXhVsXDjYs79ZynFJ)]],
isSigner: false,
isWritable: true
},
{
name: 'Token Metadata Program',
pubkey: [PublicKey [PublicKey(metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s)]],
isSigner: false,
isWritable: false
},
{
name: 'Token Program',
pubkey: [PublicKey [PublicKey(TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA)]],
isSigner: false,
isWritable: false
},
{
name: 'System Program',
pubkey: [PublicKey [PublicKey(11111111111111111111111111111111)]],
isSigner: false,
isWritable: false
},
{
name: 'Rent',
pubkey: [PublicKey [PublicKey(SysvarRent111111111111111111111111111111111)]],
isSigner: false,
isWritable: false
},
{
name: 'Clock',
pubkey: [PublicKey [PublicKey(SysvarC1ock11111111111111111111111111111111)]],
isSigner: false,
isWritable: false
},
{
name: 'Recent Blockhashes',
pubkey: [PublicKey [PublicKey(SysvarS1otHashes111111111111111111111111111)]],
isSigner: false,
isWritable: false
},
{
name: 'Instruction Sysvar Account',
pubkey: [PublicKey [PublicKey(Sysvar1nstructions1111111111111111111111111)]],
isSigner: false,
isWritable: false
}
]
}
值得一提的是,在这个例子中,我们解析了一个与多个程序交互的交易,例如系统程序、Candy Machine程序v2和Token Metadata程序。因此,如果你打算解析所有指令,你需要所有涉及程序的IDL。在我们的例子中,我们只使用了Candy Machine程序v2,解析了第4个指令。
3、结束语
本文帮助你了解如何自行构建解析管道。通过使用IDL,开发者可以与Solana程序通信并理解其交易的格式。然而,如果你不想自己管理这些方面,你可以使用Shyft的Transaction API,它为你处理复杂的可靠解析。
原文链接:How to parse Raw Transactions on Solana
DefiPlot翻译整理,转载请标明出处
免责声明:本站资源仅用于学习目的,也不应被视为投资建议,读者在采取任何行动之前应自行研究并对自己的决定承担全部责任。