PDAs en Anchor
Las Direcciones Derivadas de Programa (PDAs) no tienen clave privada; tu programa firma por ellas con seeds y bump a través de invoke_signed o CPI with_signer.
Receta
#[account(
seeds = [b"escrow", maker.key().as_ref()],
bump,
)]
pub escrow: Account<'info, Escrow>,Cuándo usar esto: El programa debe custodiar activos o almacenar estado canónico en una dirección determinista.
Ejemplo Funcional
#[derive(Accounts)]
pub struct InitEscrow<'info> {
#[account(
init,
payer = maker,
space = 8 + Escrow::INIT_SPACE,
seeds = [b"escrow", maker.key().as_ref(), escrow_id.to_le_bytes().as_ref()],
bump,
)]
pub escrow: Account<'info, Escrow>,
#[account(mut)]
pub maker: Signer<'info>,
pub system_program: Program<'info, System>,
}Lo que esto demuestra:
- Las
seeds+ el ID del programa determinan la dirección de la PDA. bumpencuentra elbumpcanónico fuera de la curva.- Almacena el
bumpen la cuenta para comprobaciones posteriores más baratas. - Las PDAs no pueden ser de tipo
Signer.
Análisis Profundo
Derivación
Pubkey::find_program_address(seeds, program_id) devuelve (dirección, bump). Anchor envuelve esto en restricciones.
Firma de Programa
Solo el programa que posee las seeds de la PDA puede firmar, a menos que se use un ID de programa externo en las seeds (avanzado).
Errores Comunes
bumpfuera de la curva no almacenado - CU extra en cada CPI... Solución: Persistir elbumpen el estado.- Límites de longitud de
seeds- Restricciones máximas de datos deseeds... Solución: Mantener lasseedscompactas. - Patrón de PDA propiedad del sistema mal utilizado - Asignar al programa después de la creación... Solución: Usar la inicialización de Anchor en la PDA.
- Desajuste de
seedsentre cliente/servidor - La transacción falla... Solución: Compartir el generador deseedsen el SDK. - PDA como
Signer<'info>- No compilará / modelo incorrecto... Solución: UsarAccountcon restricción deseeds.
Alternativas
| Alternativa | Usar Cuando | No Usar Cuando |
|---|---|---|
Cuentas propiedad de Keypair | Se necesita firma externa | Custodia del programa |
seeds::program para PDAs externas | CPI a PDAs de programas extranjeros | Estado del propio programa |
Preguntas Frecuentes
¿Qué versión de Anchor se asume?
0.32.1 en toda esta sección.
¿Puede una PDA ser un `Signer` en la estructura de cuentas?
No. Usa restricciones de seeds y firma CPI.
¿Dónde se almacena el `bump`?
En el campo de tu struct de cuenta, establecido en la inicialización.
¿Cómo derivan los clientes las PDAs?
Usa @solana/kit 7.0.0 con bytes de seeds coincidentes.
¿Qué ID de programa se usa para las PDAs?
La dirección declare_id de tu programa Anchor.
¿Las `seeds` incluyen el `bump`?
No en el array de seeds; el bump es un parámetro separado para find_program_address.
¿Cómo depurar fallos de PDA?
Compara las claves registradas; verifica las seeds y el ID del programa en el lado del cliente.
¿Son las PDAs exentas de alquiler (rent-exempt)?
Sí, cuando contienen datos; fináncialas con el pagador en la inicialización.
¿Puede una PDA firmar múltiples CPIs en una ix?
Sí, con las mismas seeds de firmante para cada CPI.
¿Qué leer a continuación?
Consulta los enlaces relacionados para temas más profundos sobre PDAs.
Relacionado
- Firmar con PDAs - Firma CPI
- Restricciones de
SeedsyBump- validación - Conceptos Básicos de PDA - modelo nativo
Versiones de Stack: 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.