Una billetera no custodial es un sistema en el que solo el usuario controla las claves privadas que autorizan las transacciones; ningún tercero puede mover o congelar fondos. Este artículo explica el modelo subyacente de gestión de claves, muestra cómo construir y probar un flujo de firma no custodial mínimo utilizando bibliotecas estándar y un punto final RPC, y proporciona un procedimiento reproducible para verificar que las claves nunca salen del cliente. También cubre modos de falla comunes, compensaciones entre almacenamiento en caliente y en frío, y cómo medir el comportamiento de la billetera sin depender de las afirmaciones del proveedor.
Definición y alcance de una billetera no custodial
Una billetera no custodial es un sistema de software o hardware en el que las claves privadas que controlan los activos de la cadena de bloques se generan y almacenan exclusivamente en infraestructura que el usuario controla. La billetera puede conectarse a nodos remotos para leer el estado de la cadena y difundir transacciones firmadas, pero nunca debe transmitir la clave privada ni la frase semilla a ningún servidor. Esto la distingue de las billeteras custodiales, donde un intercambio o plataforma posee las claves en nombre del usuario.
Este artículo se centra en la mecánica técnica: derivación de claves, firma local, interacción con RPC y verificación. No recomienda marcas específicas de billeteras ni compara productos de consumo. Para la selección de puntos finales al conectar una billetera a una red, utilice el Asistente RPC, que proporciona recomendaciones breves y directas para proveedores y redes.
- No custodial: el usuario posee las claves; la firma ocurre localmente.
- Custodial: la plataforma posee las claves; el usuario se autentica en un servicio.
- Los modelos híbridos (MPC, multifirma) siguen calificando como no custodiales si ningún tercero individual puede mover fondos unilateralmente.
Requisitos previos y supuestos para la implementación
Los ejemplos a continuación asumen que se dispone de Node.js 18+ y Python 3.10+, y que tiene acceso a un punto final RPC para una red compatible con EVM. Reemplace RPC_URL con el punto final de su proveedor. También necesitará una clave privada de prueba; nunca utilice una clave que controle fondos reales en desarrollo. El código utiliza bibliotecas conocidas: ethers para JavaScript y web3.py para Python.
Estos ejemplos son intencionalmente mínimos para ilustrar el límite de firma. Las billeteras de producción añaden almacenamiento seguro de claves, flujos de confirmación del usuario, simulación de transacciones y aislamiento de hardware.
npm install ethers
pip install web3Modelo de gestión de claves: frases semilla, rutas de derivación y almacenamiento
La mayoría de las billeteras no custodiales utilizan una estructura de billetera determinista jerárquica (HD). Una única frase semilla (típicamente 12 o 24 palabras) genera una clave privada maestra, a partir de la cual se derivan claves hijas a lo largo de una ruta de derivación como m/44'/60'/0'/0/0 para Ethereum. La frase semilla es el secreto de recuperación definitivo; cualquiera que la obtenga puede reconstruir todas las claves derivadas y firmar transacciones.
La billetera debe almacenar la semilla o la clave privada de manera que resista la extracción. Los enfoques comunes incluyen keystores cifrados (por ejemplo, Web3 Secret Storage), llaveros del sistema operativo, enclaves seguros y billeteras de hardware donde la clave nunca entra en la memoria de propósito general. La propiedad crítica es que la firma ocurre dentro de un límite de confianza y la clave nunca se serializa en una solicitud de red.
- Frase semilla = secreto maestro; respáldala fuera de línea.
- La ruta de derivación determina qué direcciones se controlan.
- El keystore cifrado añade una capa de contraseña pero es tan fuerte como la contraseña.
- Las billeteras de hardware mantienen las claves en un elemento seguro dedicado.
Ciclo de vida de una transacción en una billetera no custodial
Una transacción comienza cuando el usuario inicia una acción. La billetera consulta el punto final RPC para obtener el nonce actual, el precio del gas y el ID de cadena, construye un objeto de transacción sin firmar y lo presenta para confirmación. Tras la aprobación, la billetera firma el hash de la transacción localmente utilizando la clave privada. La transacción sin procesar firmada se envía luego al punto final RPC mediante eth_sendRawTransaction. El nodo la difunde a la red; la billetera no necesita mantener una copia de la cadena de bloques.
Esta separación es fundamental: el proveedor RPC solo ve transacciones firmadas y direcciones públicas, nunca la clave privada. Un punto final RPC malicioso o comprometido podría censurar o retrasar transacciones, pero no puede falsificar firmas ni robar fondos.
const { ethers } = require('ethers');
async function signAndSend() {
const provider = new ethers.JsonRpcProvider('RPC_URL');
const wallet = new ethers.Wallet('PRIVATE_KEY', provider);
const tx = {
to: '0xRecipientAddress',
value: ethers.parseEther('0.01'),
nonce: await provider.getTransactionCount(wallet.address),
gasLimit: 21000,
gasPrice: await provider.getFeeData().then(f => f.gasPrice),
chainId: (await provider.getNetwork()).chainId
};
const signed = await wallet.signTransaction(tx);
const response = await provider.broadcastTransaction(signed);
console.log('Transaction hash:', response.hash);
}
signAndSend().catch(console.error);Diagnóstico ejecutable: verificación de la firma local con una clave de prueba
El siguiente script de Python demuestra que la firma se puede realizar completamente fuera de línea. Crea una billetera a partir de una clave privada de prueba, firma una transacción y recupera la dirección del remitente a partir de la firma sin contactar ningún punto final RPC. Si la dirección recuperada coincide con la dirección de la billetera, el límite de firma está intacto.
Ejecute esto en un entorno aislado. La clave privada utilizada aquí es una clave de prueba bien conocida; nunca la utilice para activos reales.
from web3 import Web3
from eth_account import Account
# Well-known test private key (do not use for real funds)
private_key = '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318'
acct = Account.from_key(private_key)
# Build an unsigned transaction
tx = {
'nonce': 0,
'gasPrice': Web3.to_wei('10', 'gwei'),
'gas': 21000,
'to': '0x000000000000000000000000000000000000dEaD',
'value': Web3.to_wei('0.001', 'ether'),
'chainId': 1
}
signed = acct.sign_transaction(tx)
recovered = Account.recover_transaction(signed.raw_transaction)
print('Wallet address:', acct.address)
print('Recovered address:', recovered)
assert recovered == acct.address, 'Signing boundary compromised'
print('Local signing verified. No RPC call made.')Resultado esperado de la verificación e interpretación
Cuando el diagnóstico se ejecuta correctamente, imprime la dirección de la billetera y la dirección recuperada, que deben ser idénticas. La ausencia de cualquier llamada de red en el script confirma que la firma no depende de un proveedor RPC. Si las direcciones difieren, la biblioteca de firma o la derivación de claves está mal configurada; investigue antes de continuar.
Para una prueba completa de extremo a extremo, difunda la transacción firmada a una testnet utilizando un punto final RPC y confirme su inclusión en un bloque. La siguiente tabla describe las etapas de verificación y lo que demuestra cada una.
- Etapa 1: Firma y recuperación fuera de línea — demuestra el aislamiento de claves.
- Etapa 2: Difusión a testnet — demuestra compatibilidad con RPC.
- Etapa 3: Confirmación en cadena — demuestra aceptación por la red.
Tabla de resultados: lista de verificación
Utilice la siguiente tabla para registrar los resultados al probar una implementación de billetera no custodial. No invente valores; complete los resultados observados en su propio entorno.
| Verificación | Método | Resultado esperado | Observado |
|---|---|---|---|
| La clave nunca sale del cliente | Captura de red durante la firma | Ninguna solicitud saliente contiene la clave privada | |
| Recuperación de firma | Script de recuperación fuera de línea | La dirección recuperada es igual a la dirección de la billetera | |
| Difusión RPC | Enviar tx firmada a testnet | Se devuelve el hash de la transacción | |
| Confirmación | Consultar eth_getTransactionReceipt | Estado del recibo = 0x1 | |
| Gestión de nonce | Consultar eth_getTransactionCount | El nonce se incrementa correctamente |
Solución de problemas comunes de billeteras no custodiales
Incluso con una arquitectura correcta, surgen varios problemas con frecuencia. Una transacción puede ser rechazada con insufficient funds si el saldo de la cuenta no cubre el valor más el gas; esto es un problema del estado de la cadena, no un fallo de firma. Un error nonce too low indica una transacción pendiente con el mismo nonce; consulte el nonce pendiente usando eth_getTransactionCount con la etiqueta de bloque pending. Si el punto final RPC devuelve method not found, el proveedor puede no admitir el método JSON-RPC requerido; cambie a un punto final compatible.
Los fallos de verificación de firma a menudo se deben a IDs de cadena desajustados o a formatos de transacción EIP-1559 versus heredados. Asegúrese de que el chainId en la transacción firmada coincida con la red. Para billeteras de hardware, confirme que el dispositivo esté desbloqueado y que se haya seleccionado la ruta de derivación correcta.
- Fondos insuficientes: verifique el saldo y la estimación de gas.
- Nonce demasiado bajo: use el nonce pendiente o espere la confirmación.
- ID de cadena incorrecto: verifique la configuración de la red.
- Método RPC no soportado: use un proveedor con cobertura completa de métodos.
Compensaciones: billeteras calientes, almacenamiento en frío y riesgo operativo
Las billeteras no custodiales trasladan la responsabilidad al usuario. Las billeteras calientes (software conectado a Internet) ofrecen conveniencia pero exponen las claves a malware y phishing. Las billeteras frías (hardware o con aislamiento de red) reducen la superficie de ataque en línea pero complican los flujos de trabajo de transacciones. Las billeteras multifirma y MPC distribuyen la confianza entre múltiples partes o dispositivos, eliminando puntos únicos de falla a costa de una sobrecarga de coordinación.
No existe una elección universalmente correcta; el modelo apropiado depende del valor de los activos, la frecuencia de las transacciones y el modelo de amenaza. Para tenencias de alto valor, el aislamiento de hardware y la redundancia geográfica de las copias de seguridad de la semilla son estándar. Para transacciones pequeñas frecuentes, una billetera caliente con estricta higiene operativa puede ser aceptable.
Próximos pasos: integración con infraestructura y medición de confiabilidad
Una vez verificada la firma local, conecte la billetera a una infraestructura RPC confiable. OnFinality proporciona puntos finales RPC gestionados en muchas redes; revise las redes soportadas y las opciones de servicio API. Para aplicaciones de alto rendimiento o sensibles a la latencia, considere nodos dedicados. Los detalles de precios están disponibles para la planificación de capacidad.
Para medir la confiabilidad, ejecute un script que consulte periódicamente eth_blockNumber y registre la latencia y las tasas de error durante una ventana definida. Compare proveedores utilizando una metodología idéntica. Para recomendaciones concretas de puntos finales, consulte el Asistente RPC en lugar de confiar en listas genéricas.
- Revisar redes soportadas: /en/networks
- Explorar niveles de servicio API: /en/api-service
- Comparar opciones de nodos dedicados: /en/dedicated-node
- Consultar precios de RPC: /en/pricing/rpc
- Obtener más información sobre los fundamentos de RPC: /en/learn