Conceptos básicos de las PDA
10 ejemplos para empezar con las PDA: 7 básicos y 3 intermedios.
Prerrequisitos
- Comprender Pubkeys.
- Solana CLI 3.0.10 para las utilidades
solana addressfuera de la cadena.
Ejemplos básicos
1. Derivación fuera de la cadena
Los clientes encuentran la PDA + bump antes de construir transacciones.
use solana_program::pubkey::Pubkey;
let program_id = Pubkey::new_unique();
let (pda, bump) = Pubkey::find_program_address(&[b"vault"], &program_id);find_program_addressprueba los bumps 255..0.- La PDA está fuera de la curva; no existe clave privada.
- Las mismas semillas + ID de programa siempre generan la misma dirección.
2. PDA como clave de cuenta
Las transacciones hacen referencia a la pubkey de la PDA como cualquier otra cuenta.
// AccountMeta::new(pda, false) - la PDA no es un firmante de billetera- Las billeteras firman; las PDA solo firman a través de
invoke_signeddel programa. - Las PDA pueden poseer cuentas de tokens y cuentas de datos.
- Almacena el bump en los datos de la cuenta para una rederivación más barata.
3. Segmentos de semillas
Las semillas son cadenas de bytes: pubkeys, cadenas, números.
let seeds: &[&[u8]] = &[b"escrow", buyer.as_ref(), seller.as_ref()];- Se aplican las reglas de longitud máxima de semilla por semilla.
- Usa prefijos constantes para organizar las PDA por namespaces.
- Documenta el orden de las semillas para los clientes.
4. ID del programa en la derivación
Cambiar la ID del programa cambia la dirección de la PDA.
Pubkey::find_program_address(seeds, program_id);- Los despliegues de actualización mantienen la ID del programa.
- Las PDA de programas cruzados usan la ID del programa llamado.
- Nunca codifiques PDA de forma rígida; siempre deriva.
5. La PDA no puede firmar transacciones
Los usuarios finales nunca tienen las claves privadas de la PDA.
// Solo el programa propietario puede firmar para la PDA a través de invoke_signed- Modelo de seguridad: la lógica del programa es la autoridad.
- Programa comprometido = PDA comprometidas.
- Mantén segura la autoridad de actualización del programa.
6. Fuera de la curva vs. en la curva
Las PDA están intencionalmente fuera de la curva ed25519.
// Fuera de la cadena: Pubkey::create_program_address valida el bumpcreate_program_addressfalla si está en la curva.find_program_addressbusca un bump válido.- Los exploradores aún muestran la PDA como una dirección normal.
7. Autoridad de programa única
Solo el programa que deriva puede firmar para la PDA.
invoke_signed(&ix, accounts, &[&[b"vault", &[bump]]])?;- Las semillas deben coincidir con la derivación.
- Una ID de programa incorrecta no puede firmar.
- CPI pasa las semillas firmantes al runtime.
Ejemplos intermedios
8. Almacenar el bump canónico
Guarda el bump al inicializar para evitar la búsqueda en la cadena.
pub struct Vault { pub bump: u8, pub total: u64 }- Verifica
seeds[bump] == stored_bumpen cada ix. - Previene el "griefing" de búsqueda de bumps.
- Ver la página de Bumps Canónicos.
Relacionado: Bumps Canónicos - almacenamiento de bumps
9. Cuenta de token propiedad de la PDA
Las cuentas de token pueden usar la PDA como autoridad.
// seeds: [b"token", mint.key.as_ref(), owner.as_ref()]- El programa firma las transferencias de tokens con
invoke_signed. - Valida la menta y el propietario en las semillas.
- Patrón de bóveda común.
Relacionado: PDA como Autoridades - bóvedas
10. Conciencia de colisiones
Diferentes conjuntos de semillas no deben colisionar semánticamente.
const PREFIX_VAULT: &[u8] = b"vault";
const PREFIX_ESCROW: &[u8] = b"escrow";- Usa prefijos estáticos distintos.
- Incluye pubkeys para PDA por usuario.
- Documenta la gramática de las semillas.
Relacionado: Diseño de Semillas y Colisiones - reglas de diseño
Versiones de la pila: Esta página fue escrita para Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, anchor-lang 0.32.1, Rust 1.91.1, @solana/kit 7.0.0, Surfpool 0.12.0, y LiteSVM 0.6.x.