invoke vs invoke_signed
invoke reenvía solo las firmas de transacciones. invoke_signed añade firmas de PDA derivadas de porciones de semillas, permitiendo a los programas mover fondos que custodian.
Receta
invoke(&ix, accounts)?; // solo firmantes de billetera
invoke_signed(&ix, accounts, seeds)?; // + firmantes de PDACuándo usar esto:
- Para debitar un PDA de bóveda.
- Para acuñar con una autoridad de acuñación PDA.
- Para crear cuentas propiedad de tu programa.
Ejemplo funcional
pub fn move_from_vault(bump: u8, amount: u64, from: &AccountInfo, to: &AccountInfo, sys: &AccountInfo) -> ProgramResult {
let ix = system_instruction::transfer(from.key, to.key, amount);
invoke_signed(&ix, &[from.clone(), to.clone(), sys.clone()], &[&[b"vault", &[bump]]])
}Lo que esto demuestra:
- La bóveda PDA firma la transferencia del sistema.
- Grupo de semillas único con byte de "bump".
- Sin
invoke_signed, la CPI falla por falta de firma.
Análisis en profundidad
Comparación
| invoke | invoke_signed | |
|---|---|---|
| Firma PDA | No | Sí |
| CU | Menor | Ligeramente mayor |
| Riesgo | Menor si no hay custodia | Errores de semillas críticos |
Notas de Rust
// seeds: &[&[u8]] - array de porciones de semillasTrampas
- invoke para autoridad PDA -
MissingRequiredSignature. Solución: Usarinvoke_signed. - Semillas incorrectas - Fallo silencioso o error. Solución: Centralizar el constructor de semillas.
- ¿Podría la billetera firmar un PDA? - No existe clave privada. Solución: Solo programa.
- Confusión de delegado - El delegado de token no es un firmante de programa PDA. Solución: Leer las reglas de token.
- Múltiples grupos de semillas - El orden importa para CPIs de múltiples PDAs. Solución: Probar cada ruta.
Alternativas
| Alternativa | Usar cuándo | No usar cuándo |
|---|---|---|
| Co-firma del cliente | El usuario paga directamente | Bóveda autónoma |
| Patrón de cuenta nonce | Claves duraderas | Custodia de PDA |
Preguntas frecuentes
¿Puede invoke_signed añadir firma de billetera?
No, solo firmas de programa PDA.
¿Límite de profundidad?
4, incluyendo CPIs anidadas.
¿CPI de acuñación de token?
A menudo invoke_signed.
¿Creación de cuenta del sistema?
invoke_signed para el pagador PDA.
¿Simular?
Las mismas reglas en LiteSVM.
¿Anchor CpiContext?
Envuelve invoke_signed con semillas.
¿Error de semilla fallida?
InvalidSeeds o firma faltante.
¿PDA entre programas?
El programa propietario debe hacer CPI.
¿Auditar?
Cada línea de invoke_signed.
¿Vida útil de las semillas?
El "borrow checker" lo impone.
¿Metadato de firmante opcional?
Metadato PDA signer verdadero.
¿invoke de Anchor?
La macro selecciona basándose en las semillas.
Relacionado
- Firmar con PDAs - Firma de PDA
- CPI al Programa del Sistema - Transferencias de SOL
- Pasar cuentas a CPIs - Metadatos de cuenta
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.