Una cartera de contrato inteligente es una cuenta de blockchain cuyas reglas de autorización y ejecución residen en código de contrato desplegado en lugar de en una única clave de cuenta de propiedad externa (EOA). Esa distinción cambia cómo se firman, patrocinan, agrupan y recuperan las transacciones, e introduce una nueva clase de modos de fallo en torno a los nonces, la estimación de gas y el comportamiento del bundler. Este artículo explica el modelo de cuenta, recorre un procedimiento de verificación ejecutable contra un endpoint RPC y muestra cómo diagnosticar los errores que aparecen cuando una cuenta inteligente se comporta mal. Separa el comportamiento documentado del protocolo de las mediciones que debes realizar tú mismo en tu propia infraestructura.
Qué es realmente una cartera de contrato inteligente
Una cartera de contrato inteligente, a menudo llamada cuenta inteligente, es una cuenta en cadena cuya lógica de control está implementada como bytecode desplegado. Los fondos residen en la dirección del contrato, y el contrato decide si una acción determinada está autorizada: puede verificar una firma, varias firmas, una passkey, una clave de sesión con caducidad o una política arbitraria codificada por el desarrollador. Esta es la diferencia principal con una cuenta de propiedad externa, donde la posesión de una clave privada es el único primitivo de autorización que entiende el protocolo.
La consecuencia práctica es que el comportamiento de la cartera se vuelve actualizable y programable a nivel de cuenta. Los umbrales de aprobación multifirma, los guardianes de recuperación social, los límites de gasto y las llamadas agrupadas son lógica de contrato en lugar de características del protocolo. La contrapartida es que cada una de esas características ahora es superficie de ataque: un error en la implementación de la cuenta, un módulo mal configurado o una ruta de actualización insegura pueden comprometer los fondos incluso cuando la clave del usuario nunca se expone.
Este artículo se centra en cuentas inteligentes de EVM que utilizan ERC-4337, porque ese es el modelo al que apuntan la mayoría de las herramientas y proveedores de infraestructura. La abstracción de cuenta en otros entornos de ejecución, como los contratos de cuenta nativos en Starknet, sigue el mismo modelo mental pero reemplaza la maquinaria de bundler y EntryPoint por semánticas de cuenta a nivel de entorno de ejecución.
- Los fondos los posee el código del contrato, no una dirección controlada por una clave.
- La autorización es una decisión del contrato, por lo que puede ser multiparte, limitada en el tiempo o basada en políticas.
- La actualización y los sistemas de módulos añaden potencia y riesgo al mismo tiempo.
Supuestos y requisitos previos para el flujo de trabajo
El procedimiento siguiente asume que tienes un endpoint RPC compatible con EVM para la red de destino, una dirección de implementación de cuenta que deseas inspeccionar y familiaridad básica con JSON-RPC. No necesitas una clave con fondos para ejecutar los pasos de verificación de solo lectura; solo la necesitas si pretendes enviar una UserOperation real.
Utiliza un endpoint de marcador de posición como RPC_URL en todo el artículo y sustituye tu propia URL de proveedor. Si aún estás eligiendo infraestructura, la guía de endpoints RPC multicadena cubre cómo difiere el comportamiento de los endpoints entre redes, y el servicio API de OnFinality describe el acceso gestionado. Para cargas de trabajo en producción donde importan la latencia del bundler y del nodo, revisa las opciones de nodo dedicado antes de comprometerte con un endpoint compartido.
El modelo mental de ERC-4337: UserOperations y el EntryPoint
ERC-4337 evita cambiar el protocolo base introduciendo un objeto de transacción de nivel superior llamado UserOperation. Un usuario o una aplicación firma una UserOperation que describe la llamada prevista, y un bundler empaqueta una o más de ellas en una transacción ordinaria enviada a un contrato EntryPoint único. El EntryPoint luego llama a la función de validación de la cuenta inteligente, opcionalmente llama a un paymaster para cubrir el gas y finalmente ejecuta la llamada solicitada.
Esta estratificación es lo que hace posible el patrocinio de gas y el agrupamiento sin cambios en el protocolo. También significa que hay tres partes distintas cuyo comportamiento debes razonar: el contrato de cuenta que valida, el paymaster que acepta pagar y el bundler que decide si incluir la operación. Un fallo en cualquier capa se manifiesta como una UserOperation rechazada o descartada, y el texto del error generalmente indica qué capa lo rechazó.
El nonce de la cuenta lo gestiona el EntryPoint en lugar de la red, lo que es una fuente frecuente de confusión. Dos UserOperations de la misma cuenta pueden ser válidas con nonces de EntryPoint diferentes aunque el nonce subyacente de la EOA no haya cambiado, y una operación atascada puede bloquear las posteriores hasta que se reemplace o se invalide.
- Contrato de cuenta: valida firmas y ejecuta llamadas.
- Paymaster: opcionalmente patrocina gas, sujeto a sus propias comprobaciones de política.
- Bundler: simula, agrupa y envía al EntryPoint.
- EntryPoint: el singleton que orquesta la validación y la ejecución.
Inspeccionar una cuenta inteligente con curl
Antes de confiar en cualquier integración de cartera, confirma que la dirección que estás tratando como cuenta inteligente realmente tiene código y expone la interfaz esperada. Las siguientes llamadas de solo lectura funcionan contra cualquier endpoint JSON-RPC de EVM estándar. Reemplaza RPC_URL y ACCOUNT_ADDRESS con tus propios valores.
La primera llamada devuelve bytecode si la dirección es un contrato y 0x si es una EOA. La segunda lee la referencia al EntryPoint de la cuenta si la implementación expone un getter público; no todas las implementaciones lo hacen, así que trata un resultado vacío como no concluyente en lugar de como prueba de mala configuración.
curl -s RPC_URL \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_getCode","params":["ACCOUNT_ADDRESS","latest"]}'
curl -s RPC_URL \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":2,"method":"eth_call","params":[{"to":"ACCOUNT_ADDRESS","data":"0xENTRYPOINT_GETTER_SELECTOR"},"latest"]}'Verificar un despliegue con una comprobación mediante script
Una sola llamada curl es útil para comprobaciones puntuales, pero un script de verificación repetible es mejor para CI y para comparar el comportamiento entre endpoints. El ejemplo de Python a continuación comprueba que la dirección tiene código, lee su saldo y confirma el ID de cadena para que sepas con qué red estás hablando realmente. Utiliza solo la biblioteca estándar y un endpoint de marcador de posición.
Ejecuta esto contra cada endpoint que planees usar en producción. Si dos endpoints discrepan en el ID de cadena o devuelven bytecode diferente para la misma dirección en el mismo bloque, detente e investiga antes de desplegar cualquier cosa que dependa de ellos.
import json, urllib.request
RPC_URL = "RPC_URL"
ACCOUNT = "ACCOUNT_ADDRESS"
def rpc(method, params):
body = json.dumps({"jsonrpc": "2.0", "id": 1, "method": method, "params": params}).encode()
req = urllib.request.Request(RPC_URL, data=body, headers={"Content-Type": "application/json"})
with urllib.request.urlopen(req, timeout=10) as resp:
payload = json.loads(resp.read())
if "error" in payload:
raise RuntimeError(payload["error"])
return payload["result"]
chain_id = int(rpc("eth_chainId", []), 16)
code = rpc("eth_getCode", [ACCOUNT, "latest"])
balance = int(rpc("eth_getBalance", [ACCOUNT, "latest"]), 16)
print("chain_id:", chain_id)
print("is_contract:", code not in ("0x", "0x0"))
print("code_bytes:", (len(code) - 2) // 2)
print("balance_wei:", balance)Resultado de verificación esperado y cómo interpretarlo
Una cuenta inteligente correctamente configurada debería devolver un ID de cadena que coincida con la red que pretendías, una cadena de bytecode no vacía y un saldo consistente con tus registros. Anota la longitud en bytes del código y el número de bloque en el que lo leíste, porque las implementaciones proxy pueden cambiar el bytecode después de una actualización y una discrepancia posterior suele ser la primera señal de que una cuenta se actualizó inesperadamente.
Cuando ejecutes la misma comprobación en varios endpoints, captura los resultados en una tabla para que las diferencias sean visibles en lugar de recordadas. Una plantilla como la siguiente es suficiente; rellena tus propios valores medidos en lugar de confiar en cualquier cifra publicada.
| Etiqueta del endpoint | chain_id | is_contract | code_bytes | bloque | latencia (ms) |
|---|---|---|---|---|---|
| primario | (medido) | (medido) | (medido) | (medido) | (medido) |
| secundario | (medido) | (medido) | (medido) | (medido) | (medido) |
La latencia en esa tabla debe medirse con tu propio cliente a lo largo de varias solicitudes, no copiarse de la página de marketing de un proveedor. El propósito de la tabla es la consistencia: si un endpoint se retrasa muchos bloques respecto a los demás, los resultados de simulación de UserOperation diferirán según qué endpoint use tu bundler.
Simular una UserOperation antes de enviarla
La mayoría de los bundlers exponen un método RPC para simular una UserOperation, comúnmente eth_estimateUserOperationGas o un equivalente específico del proveedor. La simulación detecta fallos de firma, rechazos del paymaster y condiciones de gas insuficiente antes de que gastes nada. La forma exacta de la solicitud depende de tu bundler, así que consulta su documentación para los nombres de los campos; la estructura siguiente ilustra el patrón con marcadores de posición.
Trata la simulación como una puerta obligatoria en tu pipeline de despliegue. Una UserOperation que falla la simulación casi con certeza fallará en cadena, y el mensaje de error de la simulación suele ser más específico que el motivo de reversión en cadena.
curl -s BUNDLER_URL \
-H 'Content-Type: application/json' \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "eth_estimateUserOperationGas",
"params": [
{
"sender": "ACCOUNT_ADDRESS",
"nonce": "0x0",
"callData": "0xCALLDATA",
"callGasLimit": "0x0",
"verificationGasLimit": "0x0",
"preVerificationGas": "0x0",
"maxFeePerGas": "0x0",
"maxPriorityFeePerGas": "0x0",
"signature": "0xSIGNATURE"
},
"ENTRYPOINT_ADDRESS"
]
}'Solución de problemas comunes de cuentas inteligentes
Los fallos se agrupan en torno a un pequeño número de causas. Los errores de validación de firma suelen significar que la cuenta espera un esquema de firma diferente al que usó tu cliente, o que el hash de la UserOperation se calculó sobre campos diferentes a los que la cuenta reconstruye. Los rechazos del paymaster significan que la política de patrocinio rechazó la operación, a menudo porque el contrato o selector de destino no está en una lista de permitidos, o porque la cuenta ha superado un límite de velocidad.
Los conflictos de nonce aparecen cuando una UserOperation anterior sigue pendiente en el mempool del bundler. Debido a que el EntryPoint rastrea los nonces por separado de la red, debes consultar el EntryPoint para obtener el nonce actual de la cuenta en lugar de leer eth_getTransactionCount en la EOA. Si una operación está atascada, reemplázala por una que use el mismo nonce y una tarifa más alta, o espera a que se descarte.
Los fallos de estimación de gas con frecuencia son causados por un estado que cambia entre la simulación y la ejecución. Un saldo del paymaster suficiente durante la simulación puede agotarse para cuando se incluya el paquete, y una aprobación de token que existe en la simulación puede revocarse antes de la inclusión. Construye reintentos que vuelvan a simular en lugar de reenviar a ciegas.
- Error de firma: confirma el esquema de firma y los campos exactos del hash de la UserOperation.
- Error del paymaster: verifica la política de patrocinio, las listas de permitidos y el depósito del paymaster.
- Error de nonce: consulta el EntryPoint, no la EOA, para el nonce actual.
- Error de gas: vuelve a simular inmediatamente antes del envío y maneja la deriva del estado.
Limitaciones y contrapartidas de las carteras de contrato inteligente
Las cuentas inteligentes añaden una capa de dependencia que las EOA no tienen. Tus usuarios dependen de la corrección de la implementación de la cuenta, de la disponibilidad continua del EntryPoint y de que los bundlers sigan incluyendo sus operaciones. Una cuenta actualizable introduce una clave de administrador o un proceso de gobernanza que puede cambiar las reglas después de depositar fondos, lo cual es una suposición de confianza significativa incluso cuando la ruta de actualización tiene bloqueo temporal.
Los costes de gas también son diferentes. La validación es más cara que una simple comprobación de firma, y el patrocinio del paymaster traslada el coste a quien financia el paymaster en lugar de eliminarlo. El agrupamiento puede reducir la sobrecarga por llamada, pero el ahorro depende de cuántas llamadas agrupes realmente y del tamaño de los datos de llamada de cada una.
Por último, la portabilidad no es automática. Una UserOperation firmada para una cadena no es válida en otra a menos que la cuenta y el EntryPoint estén desplegados allí y el esquema de firma tenga en cuenta el ID de cadena. La protección contra repetición entre cadenas es una propiedad de la implementación de la cuenta, no de ERC-4337 en sí.
Próximos pasos para construir y operar cuentas inteligentes
Empieza fijando las direcciones de implementación de cuenta y de EntryPoint que pretendes soportar, luego ejecuta el script de verificación contra cada endpoint de tu stack y registra los resultados. A partir de ahí, añade la simulación a tu ruta de envío, instrumenta las respuestas del bundler para que los fallos sean atribuibles a una capa específica y monitoriza los saldos y niveles de depósito del paymaster como métricas operativas de primer nivel.
Si estás seleccionando infraestructura para la capa de bundler y nodo, la guía de endpoints RPC explica qué evaluar, y los precios de RPC te ayudan a modelar el coste frente al volumen esperado de UserOperations. Para detalles de despliegue específicos de cada red, consulta la lista de redes soportadas antes de asumir que una cadena determinada soporta la implementación de cuenta que has elegido. Las recomendaciones concretas de endpoints y proveedores las gestiona por separado RPC Assistant, así que usa este artículo para la metodología y ese recurso para la elección específica.