Transactie-introspectie

Samenvatting

@solana/transaction-introspection zet een getTransaction RPC-respons om in een lijst van instructies met echte adressen. Het lost accountindices op (inclusief lookup-tabeladressen), decodeert inner Cross Program Invocation-instructies en doorloopt de volledige instructieboom in explorer-volgorde.

Op zoek naar hoe een programma zuster-instructies on-chain inspecteert tijdens runtime? Dat is de Instructions sysvar - zie Instructie-introspectie. Deze pagina gaat over het decoderen van een transactie off-chain vanuit een RPC-respons.

Een getTransaction-respons geeft je geen kant-en-klare lijst van instructies. Accounts worden opgeslagen als numerieke indices, versioned transactions splitsen die accounts op in statische sleutels plus adressen geladen vanuit Address Lookup Tables, en inner instructies van cross-program invocations (CPIs) arriveren als gecodeerde blobs in de transactiemetadata.

@solana/transaction-introspection voert deze resolutie voor je uit. Het decodeert de wire-transactie, koppelt elke accountindex terug aan zijn Address, normaliseert de inner instructies en geeft instructies terug in dezelfde buitenste-dan-binnenste volgorde die een blokverkenner toont. De geretourneerde instructies zijn direct bruikbaar in de codama-gegenereerde clients' (bijv. @solana-program/*) parseXInstruction hulpfuncties.

Terminal
npm install @solana/transaction-introspection @solana/kit @solana/instructions @solana-program/token

De respons decoderen

Haal de transactie op met een wire-formaat codering en geef de respons door aan decodeTransactionFromRpcResponse.

Decode a transaction
import { createSolanaRpc, signature } from "@solana/kit";
import { decodeTransactionFromRpcResponse } from "@solana/transaction-introspection";
const rpc = createSolanaRpc("https://api.mainnet-beta.solana.com");
const txid =
"3jUKrQp1UGq5ih6FTDUUt2kkqUfoG2o4kY5T1DoVHK2tXXDLdxJSXzuJGY4JPoRivgbi45U2bc7LZfMa6C4R3szX";
const rpcTx = await rpc
.getTransaction(signature(txid), {
commitment: "confirmed",
encoding: "base64",
maxSupportedTransactionVersion: 0
})
.send();
if (!rpcTx) throw new Error(`Transaction ${txid} not found`);
const { compiledMessage, loadedAddresses } =
decodeTransactionFromRpcResponse(rpcTx);

De overige fragmenten hergebruiken rpcTx, compiledMessage en loadedAddresses vanuit deze stap.

Haal op met base64, base58 of json codering. decodeTransactionFromRpcResponse weigert jsonParsed-responsen - die codering vraagt het RPC-knooppunt om instructies server-side te parseren, waardoor er niets meer te decoderen valt op de client.

Loop door de instructies

walkInstructions geeft elke instructie - zowel outer als inner - terug als een array in de volgorde die een block explorer toont: elke outer instructie direct gevolgd door de inner instructies die zijn CPI's hebben geproduceerd. Elke instructie bevat een trace-veld dat beschrijft waar deze zich bevindt in de aanroephiërarchie.

Walk every instruction
import { walkInstructions } from "@solana/transaction-introspection";
for (const ix of walkInstructions({
compiledMessage,
loadedAddresses,
meta: rpcTx.meta
})) {
const location =
ix.trace.kind === "outer"
? `outer[${ix.trace.index}]`
: `inner[${ix.trace.outerIndex}/${ix.trace.innerIndex}]`;
console.log(location, ix.programAddress, ix.accounts?.length ?? 0);
}

De trace is een gediscrimineerde union: { kind: "outer", index } voor een instructie op het hoogste niveau, of { kind: "inner", outerIndex, innerIndex, stackHeight? } voor een CPI-instructie genest onder een outer instructie.

meta is optioneel - geef rpcTx.meta direct door, ook als het null kan zijn. Zonder meta geeft walkInstructions alleen de outer instructies terug.

Verwerk met een programma-client

Elke instructie van walkInstructions is een ResolvedInstruction, dus het werkt direct samen met de predicaten van @solana/instructions en de identifyXInstruction / parseXInstruction helpers gegenereerd door de @solana-program/* clients - geen conversiestap nodig.

Dit voorbeeld controleert elke Token Program SyncNative-instructie in een transactie, of deze nu op het hoogste niveau is uitgevoerd of binnen een CPI.

Find and parse SyncNative instructions
import {
isInstructionForProgram,
isInstructionWithAccounts,
isInstructionWithData
} from "@solana/instructions";
import { walkInstructions } from "@solana/transaction-introspection";
import {
identifyTokenInstruction,
parseSyncNativeInstruction,
TOKEN_PROGRAM_ADDRESS,
TokenInstruction
} from "@solana-program/token";
for (const ix of walkInstructions({
compiledMessage,
loadedAddresses,
meta: rpcTx.meta
})) {
if (!isInstructionForProgram(ix, TOKEN_PROGRAM_ADDRESS)) continue;
if (!isInstructionWithData(ix) || !isInstructionWithAccounts(ix)) continue;
if (identifyTokenInstruction(ix) !== TokenInstruction.SyncNative) continue;
const parsed = parseSyncNativeInstruction(ix);
console.log(ix.trace, parsed);
}

Hulpfuncties op lager niveau

walkInstructions dekt de meeste behoeften, maar het pakket stelt ook de onderliggende bouwstenen beschikbaar:

  • getInstructionsFromCompiledTransactionMessage(compiledMessage, loadedAddresses?) geeft alleen de outer instructies terug, met opgeloste accounts en gedecodeerde data.
  • getInnerInstructionsFromMeta(meta, accountMetas) decodeert de inner CPI-instructies uit de transactiemetadata.
  • getAccountMetasFromCompiledTransactionMessage(compiledMessage, loadedAddresses?) geeft de volledige accountlijst terug in transactievolgorde - de invoer die de vorige helper nodig heeft om inner-instructie account-indices op te lossen.
Resolve outer and inner instructions separately
import {
getAccountMetasFromCompiledTransactionMessage,
getInnerInstructionsFromMeta,
getInstructionsFromCompiledTransactionMessage
} from "@solana/transaction-introspection";
const outer = getInstructionsFromCompiledTransactionMessage(
compiledMessage,
loadedAddresses
);
const accountMetas = getAccountMetasFromCompiledTransactionMessage(
compiledMessage,
loadedAddresses
);
if (!rpcTx.meta) throw new Error("Transaction metadata missing");
const inner = getInnerInstructionsFromMeta(rpcTx.meta, accountMetas);

Rust gebruiken?

Er is geen Rust-equivalent van dit pakket. Om verwerkte instructies vanuit Rust te verkrijgen, vraag je UiTransactionEncoding::JsonParsed op via getTransaction en laat het RPC-knooppunt accounts en inner instructies voor je oplossen.

Zie ook

Is this page helpful?

Inhoudsopgave

Pagina Bewerken
© 2026 Solana Foundation. Alle rechten voorbehouden.