Estructura de instrucciones

Resumen

Una instrucción tiene 3 campos: program_id (qué programa invocar), accounts (lista AccountMeta con banderas is_signer/is_writable) y data (array de bytes de datos que el programa interpreta).

Estructura de instrucciones

Una Instruction consiste en tres campos:

  • program_id: El ID del programa que se invoca.
  • accounts: Un array de metadatos de cuenta
  • data: Un array de bytes con datos adicionales para ser utilizados por la instrucción.
Instruction struct
pub struct Instruction {
/// Pubkey of the program that executes this instruction.
pub program_id: Pubkey,
/// Metadata describing accounts that should be passed to the program.
pub accounts: Vec<AccountMeta>,
/// Opaque data passed to the program for its own interpretation.
pub data: Vec<u8>,
}

ID de programa

El program_id de la instrucción es la dirección de clave pública del programa que contiene la lógica de ejecución de la instrucción. El runtime utiliza este campo para enrutar la instrucción al programa correcto para su procesamiento.

Metadatos de cuenta

El array accounts de la instrucción es una lista ordenada de estructuras AccountMeta. Se deben proporcionar metadatos para cada cuenta con la que interactúa la instrucción. El validador utiliza estos metadatos para determinar qué transacciones pueden ejecutarse en paralelo. Las transacciones que escriben en cuentas diferentes pueden ejecutarse en paralelo.

El diagrama a continuación muestra una transacción que contiene una sola instrucción. El array accounts de la instrucción contiene metadatos para dos cuentas.

Una transacción con una instrucción. La instrucción contiene dos estructuras AccountMeta en su array accounts.Una transacción con una instrucción. La instrucción contiene dos estructuras AccountMeta en su array accounts.

Cada AccountMeta tiene tres campos:

  • pubkey: La dirección de clave pública de la cuenta
  • is_signer: Se establece en true si la cuenta debe firmar la transacción
  • is_writable: Se establece en true si la instrucción modifica los datos de la cuenta

Para saber qué cuentas requiere una instrucción, incluyendo cuáles deben ser escribibles, de solo lectura o firmar la transacción, debes consultar la implementación de la instrucción, tal como está definida por el programa.

AccountMeta
pub struct AccountMeta {
/// An account's public key.
pub pubkey: Pubkey,
/// True if an `Instruction` requires a `Transaction` signature matching `pubkey`.
pub is_signer: bool,
/// True if the account data or metadata may be mutated during program execution.
pub is_writable: bool,
}

Datos

El campo data de la instrucción es un array de bytes que indica al programa qué función invocar y proporciona los argumentos para esa función. Los datos típicamente comienzan con un discriminador o byte(s) de índice que identifica la función objetivo, seguido de los argumentos serializados. El formato de codificación está definido por cada programa (por ejemplo, serialización Borsh o un diseño personalizado).

Convenciones de codificación comunes:

  • Programas principales (System, Stake, Vote): Utilizan un índice de variante enum serializado con Bincode seguido de argumentos serializados.
  • Programas Anchor: Utilizan un discriminador de 8 bytes (los primeros 8 bytes del hash SHA-256 de "global:<function_name>") seguido de argumentos serializados con Borsh.

El runtime no interpreta el campo data. Se pasa tal cual al punto de entrada process_instruction del programa.

Instrucción compilada

Cuando las instrucciones se serializan en un mensaje de transacción, se convierten en estructuras CompiledInstruction que reemplazan todas las claves públicas con índices enteros compactos en el array account_keys del mensaje.

Ejemplo: instrucción de transferencia de SOL

El ejemplo a continuación muestra la estructura de una instrucción de transferencia de SOL.

import { generateKeyPairSigner, lamports } from "@solana/kit";
import { getTransferSolInstruction } from "@solana-program/system";
// Generate sender and recipient keypairs
const sender = await generateKeyPairSigner();
const recipient = await generateKeyPairSigner();
// Define the amount to transfer
const LAMPORTS_PER_SOL = 1_000_000_000n;
const transferAmount = lamports(LAMPORTS_PER_SOL / 100n); // 0.01 SOL
// Create a transfer instruction for transferring SOL from sender to recipient
const transferInstruction = getTransferSolInstruction({
source: sender,
destination: recipient.address,
amount: transferAmount
});
console.log(JSON.stringify(transferInstruction, null, 2));
Console
Click to execute the code.

El código a continuación muestra la salida de los fragmentos de código anteriores. El formato difiere entre SDKs, pero observa que cada instrucción contiene las mismas tres piezas de información requerida: program_id, accounts, data.

{
"accounts": [
{
"address": "Hu28vRMGWpQXN56eaE7jRiDDRRz3vCXEs7EKHRfL6bC",
"role": 3,
"signer": {
"address": "Hu28vRMGWpQXN56eaE7jRiDDRRz3vCXEs7EKHRfL6bC",
"keyPair": {
"privateKey": {},
"publicKey": {}
}
}
},
{
"address": "2mBY6CTgeyJNJDzo6d2Umipw2aGUquUA7hLdFttNEj7p",
"role": 1
}
],
"programAddress": "11111111111111111111111111111111",
"data": {
"0": 2,
"1": 0,
"2": 0,
"3": 0,
"4": 128,
"5": 150,
"6": 152,
"7": 0,
"8": 0,
"9": 0,
"10": 0,
"11": 0
}
}

Los ejemplos a continuación muestran cómo construir manualmente la instrucción de transferencia. (La pestaña Expanded Instruction es funcionalmente equivalente a la pestaña Instruction).

En la práctica, normalmente no tienes que construir una Instruction manualmente. La mayoría de los programas proporcionan bibliotecas cliente con funciones auxiliares que crean las instrucciones por ti. Si no hay una biblioteca disponible, puedes construir la instrucción manualmente.

const transferAmount = 0.01; // 0.01 SOL
const transferInstruction = getTransferSolInstruction({
source: sender,
destination: recipient.address,
amount: transferAmount * LAMPORTS_PER_SOL
});

Is this page helpful?

Tabla de Contenidos

Editar Página

Gestionado por

© 2026 Fundación Solana.
Todos los derechos reservados.
Conéctate