Publicado en inglés en el sitio web de Vitalik el 9 de junio de 2023.
Agradecimientos especiales a Dan Finlay, Karl Floersch, David Hoffman y a los equipos de Scroll y SoulWallet por sus comentarios, revisiones y sugerencias.
A medida que Ethereum pasa de ser una tecnología experimental joven a un conjunto de tecnologías maduras capaz de ofrecer una experiencia abierta, global y sin permisos a los usuarios promedio, hay tres transiciones técnicas principales que el conjunto necesita experimentar, aproximadamente al mismo tiempo:
La transición de escalabilidad en L2 - todos migrando a rollups
La transición de seguridad en las carteras - todos migrando a carteras de contrato inteligente
La transición de la privacidad - asegurando que las transferencias de fondos preserven la privacidad, y asegurando que todos los demás gadgets que se están desarrollando (recuperación social, identidad, reputación) también sean preservadores de la privacidad.

Sin la primera, Ethereum fracasa porque cada transacción cuesta $3.75 ($82.48 si tenemos otro bull market), y cada producto que apunta al mercado masivo inevitablemente se olvida la cadena y adopta soluciones centralizadas para todo.
Sin la segunda, Ethereum fracasa porque a los usuarios les incomoda almacenar sus fondos (y activos no financieros), y todos se pasan a los intercambios centralizados.
Sin la tercera, Ethereum fracasa porque tener todas las transacciones (y POAPs, etc.) disponibles públicamente para que literalmente cualquiera las vea es un sacrificio de privacidad demasiado alto para muchos usuarios, y todos se pasan a soluciones centralizadas que al menos ocultan algo tus datos.
Estas tres transiciones son cruciales por las razones mencionadas anteriormente. Pero también son un desafío debido a la intensa coordinación necesaria para resolverlas adecuadamente. No solo son características del protocolo las que necesitan mejorar; en algunos casos, la forma en que interactuamos con Ethereum necesita cambiar de manera bastante fundamental, requiriendo cambios profundos por parte de aplicaciones y carteras.
En un mundo de escalabilidad L2, los usuarios existirán en varias L2. ¿Eres miembro de ExampleDAO, que reside en Optimism? ¡Entonces tienes una cuenta en Optimism! ¿Tienes un CDP en un sistema de stablecoin en ZkSync? ¡Entonces tienes una cuenta en ZkSync! ¿Alguna vez probaste una aplicación que residía en Kakarot? ¡Entonces tienes una cuenta en Kakarot! Los días en que un usuario tenía solo una dirección habrán terminado.

Las carteras de contrato inteligente añaden más complejidad al hacer que sea mucho más difícil mantener la misma dirección entre L1 y las diversas L2s. Hoy en día, la mayoría de los usuarios utilizan cuentas de propiedad externa, cuya dirección es literalmente un hash de la clave pública que se utiliza para verificar las firmas, por lo que nada cambia entre L1 y L2. Sin embargo, con las carteras de contrato inteligente, mantener una sola dirección se vuelve más difícil. Aunque se ha trabajado mucho para intentar que las direcciones sean hashes de código que puedan ser equivalentes en las redes, notablemente con CREATE2 y la fábrica singleton ERC-2470, es difícil que esto funcione perfectamente. Algunas L2s (por ejemplo, "ZK-EVMs tipo 4") no son tan equivalentes a EVM, a menudo utilizando Solidity o un ensamblado intermedio, lo que impide la equivalencia de hashes. Y aun cuando se puede tener equivalencia de hash, la posibilidad de que las carteras cambien de propietario a través de cambios de claves crea otras consecuencias poco intuitivas.
La privacidad requiere que cada usuario tenga aún más direcciones, y puede incluso cambiar el tipo de direcciones con las que estamos tratando. Si las propuestas de direcciones ocultas (stealth addresses) se vuelven ampliamente utilizadas, en lugar de que cada usuario tenga solo unas pocas direcciones, o una dirección por cada L2, los usuarios podrían tener una dirección por transacción. Otros esquemas de privacidad, incluso los existentes como Tornado Cash, cambian la forma en que los activos se almacenan de una manera diferente: los fondos de muchos usuarios se almacenan en el mismo contrato inteligente (y por lo tanto en la misma dirección). Para enviar fondos a un usuario específico, los usuarios necesitarán depender del sistema de direccionamiento interno del propio esquema de privacidad.
Como hemos visto, cada una de las tres transiciones debilita el modelo mental de "un usuario ≈ una dirección" de diferentes maneras, y algunos de estos efectos retroalimentan la complejidad de ejecutar las transiciones. Dos puntos particulares de complejidad son:
Si quieres pagarle a alguien, ¿cómo obtendrías la información sobre cómo pagarle?
Si los usuarios tienen muchos activos almacenados en diferentes lugares a través de diferentes cadenas, ¿cómo realizan cambios de clave y recuperación social?
Tengo monedas en Scroll y quiero pagar por un café (si el "yo" soy literalmente yo, el escritor de este artículo, entonces "café" es, por supuesto, una metonimia de "té verde"). Tú me vendes el café, pero solo estás configurado para recibir monedas en Taiko. ¿Qué hacemos?
Básicamente hay dos soluciones:
Las carteras receptoras (que podrían ser comerciantes, pero también podrían ser simplemente individuos regulares) intentan arduamente soportar cada L2, y tienen alguna funcionalidad automatizada para consolidar fondos de manera asincrónica.
El receptor proporciona su L2 junto con su dirección, y la cartera del emisor automáticamente envía fondos al L2 de destino a través de algún sistema de puentes entre L2s.
Por supuesto, estas soluciones pueden combinarse: el receptor proporciona la lista de L2s que está dispuesto a aceptar, y la cartera del emisor resuelve el pago, que podría involucrar un envío directo si tienen suerte, o de lo contrario, un camino de puente entre L2s.
Pero este es solo un ejemplo de un desafío clave que introducen las tres transiciones: acciones simples como pagarle a alguien comienzan a requerir mucha más información que solo una dirección de 20 bytes.
Una transición a carteras de contrato inteligente afortunadamente no es una gran carga para el sistema de direcciones, pero aún hay algunos problemas técnicos en otras partes del conjunto de aplicaciones que necesitan ser resueltos. Las carteras necesitarán actualizarse para asegurarse de que no envíen solo 21000 de gas junto con una transacción, y será aún más importante asegurarse de que el lado receptor del pago en una cartera rastree no solo las transferencias de ETH desde cuentas de propiedad externa (EOAs), sino también ETH enviado por código de contrato inteligente. Las aplicaciones que dependen de la suposición de que la propiedad de una dirección es inmutable (por ejemplo, NFTs que prohíben contratos inteligentes para hacer cumplir regalías) tendrán que encontrar otras formas de alcanzar sus objetivos. Las carteras de contrato inteligente también facilitarán algunas cosas; notablemente, si alguien recibe solo un token ERC20 que no es ETH, podrán usar paymasters de ERC-4337 para pagar el gas con ese token.
Por otro lado, la privacidad una vez más plantea grandes desafíos que aún no hemos abordado realmente. Tornado Cash original no introdujo ninguno de estos problemas, porque no admitía transferencias internas: los usuarios solo podían depositar en el sistema y retirar de él. Sin embargo, una vez que se pueden realizar transferencias internas, los usuarios necesitarán utilizar el esquema de direccionamiento interno del sistema de privacidad. En la práctica, la "información de pago" de un usuario necesitaría contener tanto (i) algún tipo de "clave pública de gasto", un compromiso con un secreto que el destinatario podría usar para gastar, y (ii) alguna manera para que el emisor envíe información cifrada que solo el destinatario pueda descifrar, para ayudar al destinatario a descubrir el pago.
Los protocolos de direcciones ocultas (stealth addresses) se basan en un concepto de meta-direcciones, que funcionan de esta manera: una parte de la meta-dirección es una versión enmascarada de la clave de gasto del emisor, y otra parte es la clave de cifrado del emisor (aunque una implementación mínima podría establecer que estas dos claves sean iguales).

Una lección clave aquí es que, en un ecosistema amigable con la privacidad, un usuario tendrá tanto claves públicas de gasto como claves públicas de cifrado, y la "información de pago" de un usuario deberá incluir ambas claves. También hay buenas razones, aparte de los pagos, para expandirse en esta dirección. Por ejemplo, si queremos un correo electrónico cifrado basado en Ethereum, los usuarios necesitarán proporcionar públicamente algún tipo de clave de cifrado. En el "mundo EOA", podríamos reutilizar las claves de las cuentas para esto, pero en un mundo seguro de carteras de contrato inteligente, probablemente deberíamos tener una funcionalidad más explícita para esto. Esto también ayudaría a hacer que la identidad basada en Ethereum sea más compatible con ecosistemas de privacidad descentralizados no basados en Ethereum, notablemente las claves PGP.
La forma predeterminada de implementar cambios de clave y recuperación social en un mundo con múltiples direcciones por usuario es simplemente hacer que los usuarios ejecuten el procedimiento de recuperación en cada dirección por separado. Esto se puede hacer con un solo clic: la cartera puede incluir software para ejecutar el procedimiento de recuperación en todas las direcciones de un usuario al mismo tiempo. Sin embargo, incluso con tales simplificaciones de UX, la recuperación multi-dirección ingenua tiene tres problemas:
Costo de gas poco práctico: esto es autoexplicativo.
Direcciones contrafactuales: direcciones para las cuales el contrato inteligente aún no ha sido publicado (en la práctica, esto significará una cuenta de la que aún no has enviado fondos). Como usuario, tienes un número potencialmente ilimitado de direcciones contrafactuales: una o más en cada L2, incluidas L2s que aún no existen, y todo un conjunto infinito de otras direcciones contrafactuales que surgen de esquemas de direcciones ocultas.
Privacidad: si un usuario intencionalmente tiene muchas direcciones para evitar vincularlas entre sí, ciertamente no querrá vincularlas públicamente recuperándolas todas al mismo tiempo o cerca del mismo tiempo.
Resolver estos problemas es difícil. Afortunadamente, existe una solución algo elegante que funciona razonablemente bien: una arquitectura que separa la lógica de verificación y las tenencias de activos.

Cada usuario tiene un contrato de almacén de claves, que existe en un lugar específico (podría ser la mainnet o una L2 específica). Los usuarios luego tienen direcciones en diferentes L2s, donde la lógica de verificación de cada una de esas direcciones es un puntero al contrato de almacén de claves. Gastar desde esas direcciones requeriría una prueba que se introduzca en el contrato de almacén de claves mostrando la clave pública de gasto actual (o, más realistamente, muy reciente).
La prueba podría implementarse de varias maneras:
Acceso directo de solo lectura a L1 dentro de L2: Es posible modificar los L2 para darles una manera de leer directamente el estado de L1. Si el contrato de almacén de claves está en L1, esto significaría que los contratos dentro de L2 pueden acceder al almacén de claves "gratis".
Ramas de Merkle: Las ramas de Merkle pueden probar el estado de L1 a un L2, o el estado de L2 a un L1, o puedes combinar las dos para probar partes del estado de un L2 a otro L2. La principal debilidad de las pruebas de Merkle es el alto costo de gas debido a la longitud de la prueba: potencialmente 5 kB para una prueba, aunque esto se reducirá a < 1 kB en el futuro debido a los árboles de Verkle.
ZK-SNARKs: Puedes reducir los costos de datos utilizando un ZK-SNARK de una rama de Merkle en lugar de la rama en sí. Es posible construir técnicas de agregación fuera de la cadena (por ejemplo, sobre EIP-4337) para tener un único ZK-SNARK que verifique todas las pruebas de estado entre cadenas en un bloque.
Compromisos KZG: Los L2, o esquemas construidos sobre ellos, podrían introducir un sistema de direccionamiento secuencial, permitiendo que las pruebas de estado dentro de este sistema sean de solo 48 bytes de longitud. Al igual que con los ZK-SNARKs, un esquema de multiprueba podría fusionar todas estas pruebas en una sola prueba por bloque.

Si queremos evitar hacer una prueba por transacción, podemos implementar un esquema más ligero que solo requiera una prueba entre L2 para la recuperación. Gastar desde una cuenta dependería de una clave de gasto cuya clave pública correspondiente se almacena dentro de esa cuenta, pero la recuperación requeriría una transacción que copie la clave pública de gasto actual (spending_pubkey)en el almacén de claves. Los fondos en direcciones contrafactuales están seguros incluso si tus claves antiguas no lo están: "activar" una dirección contrafactual para convertirla en un contrato funcional requeriría hacer una prueba entre L2 para copiar la clave pública de gasto actual. Este hilo en los foros de Safe describe cómo podría funcionar una arquitectura similar.
Para añadir privacidad a este esquema, simplemente ciframos el puntero y realizamos todas nuestras pruebas dentro de los ZK-SNARKs:

Con más trabajo (por ejemplo, usando este trabajo como punto de partida), también podríamos eliminar la mayor parte de la complejidad de los ZK-SNARKs y crear un esquema basado en KZG más básico.
Estos esquemas pueden volverse complejos. En el lado positivo, hay muchas sinergias potenciales entre ellos. Por ejemplo, el concepto de "contratos de almacén de claves" (keystore contracts) también podría ser una solución al desafío de las "direcciones" mencionado en la sección anterior: si queremos que los usuarios tengan direcciones persistentes, que no cambien cada vez que el usuario actualiza una clave, podríamos poner meta-direcciones ocultas, claves de cifrado y otra información en el contrato de almacén de claves, y usar la dirección del contrato de almacén de claves como la "dirección" de un usuario.
Usar ENS es costoso. Hoy, en junio de 2023, la situación no es tan grave: la tarifa de transacción es significativa, pero sigue siendo comparable a la tarifa del dominio ENS. Registrar zuzalu.eth me costó aproximadamente $27, de los cuales $11 fueron tarifas de transacción. Pero si tenemos otro mercado alcista, las tarifas se dispararán. Incluso sin aumentos en el precio de ETH, que el gas vuelva a 200 gwei elevaría la tarifa de transacción de un registro de dominio a $104. Por lo tanto, si queremos que la gente realmente use ENS, especialmente para casos de uso como los medios sociales descentralizados donde los usuarios exigen un registro casi gratuito (y la tarifa del dominio ENS no es un problema porque estas plataformas ofrecen a sus usuarios subdominios), necesitamos que ENS funcione en L2.
Afortunadamente, el equipo de ENS ha dado un paso adelante, ¡y ENS en L2 está sucediendo! ERC-3668 (también conocido como "el estándar CCIP"), junto con ENSIP-10, proporcionan una manera de que los subdominios de ENS en cualquiera L2 sean automáticamente verificables. El estándar CCIP requiere configurar un contrato inteligente que describa un método para verificar pruebas de datos en L2, y un dominio (por ejemplo, Optinames usa ecc.eth) puede ser puesto bajo el control de dicho contrato. Una vez que el contrato CCIP controla ecc.eth en L1, acceder a algún subdominio.ecc.eth implicará automáticamente encontrar y verificar una prueba (por ejemplo, rama de Merkle) del estado en L2 que realmente almacena ese subdominio particular.

Obtener realmente las pruebas implica ir a una lista de URLs almacenadas en el contrato, lo que admitidamente parece centralización, aunque yo argumentaría que realmente no lo es: es un modelo de confianza 1-de-N (las pruebas inválidas son detectadas por la lógica de verificación en la función de callback del contrato CCIP, y mientras al menos una de las URLs devuelva una prueba válida, todo está bien). La lista de URLs podría contener docenas de ellas.
El esfuerzo de ENS CCIP es una historia de éxito y debería ser visto como una señal de que las reformas radicales que necesitamos son realmente posibles. Pero hay muchas más reformas en la capa de aplicación que necesitarán ser realizadas. Algunos ejemplos:
Muchas dapps dependen de que los usuarios proporcionen firmas fuera de la cadena (off-chain). Con cuentas de propiedad externa (EOAs), esto es fácil. ERC-1271 proporciona una forma estandarizada de hacer esto para carteras de contrato inteligente. Sin embargo, muchas dapps aún no soportan ERC-1271; necesitarán hacerlo.
Las dapps que usan "¿es esto una EOA?" para discriminar entre usuarios y contratos (por ejemplo, para prevenir transferencias o hacer cumplir regalías) fallarán. En general, aconsejo no intentar encontrar una solución puramente técnica aquí; determinar si una transferencia particular de control criptográfico es una transferencia de propiedad beneficiosa es un problema difícil y probablemente no solucionable sin recurrir a algunos mecanismos fuera de la cadena impulsados por la comunidad. Lo más probable es que las aplicaciones tengan que depender menos de prevenir transferencias y más en técnicas como los impuestos de Harberger.
Cómo interactúan las carteras con las claves de gasto y cifrado tendrá que ser mejorado. Actualmente, las carteras a menudo usan firmas deterministas para generar claves específicas de la aplicación: firmar un nonce estándar (por ejemplo, el hash del nombre de la aplicación) con la clave privada de una EOA genera un valor determinista que no puede ser generado sin la clave privada, y por lo tanto es seguro en un sentido puramente técnico. Sin embargo, estas técnicas son "opacas" para la cartera, impidiendo que la cartera implemente controles de seguridad a nivel de interfaz de usuario. En un ecosistema más maduro, la firma, cifrado y funcionalidades relacionadas tendrán que ser manejadas por las carteras de manera más explícita.
Los clientes ligeros (por ejemplo, Helios) tendrán que verificar L2s y no solo el L1. Hoy en día, los clientes ligeros se centran en verificar la validez de los encabezados de L1 (usando el protocolo de sincronización de clientes ligeros) y verificar las ramas de Merkle del estado de L1 y las transacciones arraigadas en el encabezado de L1. Mañana, también necesitarán verificar una prueba del estado de L2 arraigada en la raíz de estado almacenada en la L1 (una versión más avanzada de esto realmente miraría las pre-confirmaciones de L2).
Hoy en día, las carteras están en el negocio de asegurar activos. Todo vive en la cadena de bloques, y lo único que la cartera necesita proteger es la clave privada que actualmente guarda esos activos. Si cambias la clave, puedes publicar de manera segura tu clave privada anterior en internet al día siguiente. Sin embargo, en un mundo ZK, esto ya no es cierto: la cartera no solo protege las credenciales de autenticación, sino que también almacena tus datos.
Vimos los primeros indicios de tal mundo con Zupass, el sistema de identidad basado en ZK-SNARK que se utilizó en Zuzalu. Los usuarios tenían una clave privada que usaban para autenticarse en el sistema, que podría usarse para hacer pruebas básicas como "probar que soy residente de Zuzalu, sin revelar cuál". Pero el sistema Zupass también comenzó a tener otras aplicaciones construidas encima, más notablemente sellos o “stamps” (la versión de Zupass de los POAPs).

La característica clave que los sellos ofrecen sobre los POAPs es que los sellos son privados: mantienes los datos localmente y solo pruebas en ZK un sello (o algún cálculo sobre los sellos) a alguien si quieres que esa persona tenga esa información sobre ti. Pero esto crea un riesgo adicional: si pierdes esa información, pierdes tus sellos.
Por supuesto, el problema de mantener los datos puede reducirse al problema de mantener una sola clave de cifrado: un tercero (o incluso la cadena) puede mantener una copia cifrada de los datos. Esto tiene la ventaja conveniente de que las acciones que realizas no cambian la clave de cifrado, y por lo tanto no requieren ninguna interacción con el sistema que mantiene segura tu clave de cifrado. Pero aún así, si pierdes tu clave de cifrado, lo pierdes todo. Y por otro lado, si alguien ve tu clave de cifrado, ven todo lo que estaba cifrado con esa clave.
La solución de facto de Zupass fue alentar a las personas a almacenar su clave en múltiples dispositivos (por ejemplo, laptop y teléfono), ya que la posibilidad de que pierdan acceso a todos los dispositivos al mismo tiempo es mínima. Podríamos ir más allá y usar el reparto de secretos para almacenar la clave, dividida entre varios guardianes.
Este tipo de recuperación social a través de MPC no es una solución suficiente para las carteras, porque significa que no solo los guardianes actuales, sino también los guardianes anteriores podrían coludir para robar tus activos, lo cual es un riesgo inaceptablemente alto. Pero las filtraciones de privacidad generalmente son un riesgo menor que la pérdida total de activos, y alguien con un caso de uso que demande alta privacidad siempre podría aceptar un riesgo mayor de pérdida al no hacer una copia de seguridad de la clave asociada con esas acciones que demandan privacidad.
Para evitar abrumar al usuario con un sistema bizantino de múltiples caminos de recuperación, las carteras que soporten la recuperación social probablemente necesitarán gestionar tanto la recuperación de activos y la recuperación de claves de cifrado.
Uno de los hilos comunes de estos cambios es que el concepto de una "dirección", un identificador criptográfico que usas para representarte a ti mismo en la cadena, tendrá que cambiar radicalmente. “Las instrucciones sobre cómo interactuar conmigo" ya no serían solo una dirección ETH; tendrían que ser, de alguna forma, una combinación de múltiples direcciones en múltiples L2s, meta-direcciones ocultas, claves de cifrado y otros datos.
Una forma de hacer esto es convertir ENS en tu identidad: tu registro ENS podría simplemente contener toda esta información, y si envías a alguien bob.eth (o bob.ecc.eth, o...), podrían consultar y ver todo sobre cómo pagar e interactuar contigo, incluyendo las formas más complicadas y preservadoras de privacidad entre dominios.
Pero este enfoque centrado en ENS tiene dos debilidades:
Vincula demasiadas cosas a tu nombre. Tu nombre no eres tú, tu nombre es uno de los muchos atributos que te definen. Debería ser posible cambiar tu nombre sin tener que trasladar todo tu perfil de identidad y actualizar un montón de registros en muchas aplicaciones.
No puedes tener nombres contrafactuales sin confianza. Una característica clave de UX en cualquier blockchain es la capacidad de enviar monedas a personas que aún no han interactuado con la cadena. Sin tal funcionalidad, existe un catch-22 o dilema: interactuar con la cadena requiere pagar tarifas de transacción, lo cual requiere... contar con monedas. Las direcciones ETH, incluidas las direcciones de contratos inteligentes con CREATE2, tienen esta característica. Los nombres ENS no, porque si dos Bobs deciden fuera de la cadena que ambos son bob.ecc.eth, no hay forma de elegir cuál de ellos obtiene el nombre.
Una posible solución es incluir más elementos en el contrato de almacén de claves o contrato keystore mencionado en la arquitectura anteriormente en este post. El contrato de almacén de claves podría contener toda la información variada sobre ti y cómo interactuar contigo (y con CCIP, parte de esa información podría estar fuera de la cadena), y los usuarios utilizarían su contrato de almacén de claves como su identificador principal. Pero los activos reales que reciben estarían almacenados en todo tipo de lugares diferentes. Los contratos de almacén de claves no están vinculados a un nombre y son amigables con los contrafactuales: puedes generar una dirección que solo puede ser inicializada de manera comprobable por un contrato de almacén de claves que tenga ciertos parámetros iniciales fijos.
Otra categoría de soluciones tiene que ver con abandonar por completo el concepto de direcciones orientadas al usuario, en un espíritu similar al protocolo de pago de Bitcoin. Una idea es depender más de los canales de comunicación directa entre el emisor y el receptor; por ejemplo, el emisor podría enviar un enlace de reclamación (ya sea como una URL explícita o un código QR) que el receptor podría usar para aceptar el pago como desee.

Independientemente de si actúa primero el emisor o el receptor, una mayor dependencia de las carteras generando información de pago actualizada en tiempo real podría reducir la fricción. Dicho esto, los identificadores persistentes son convenientes (especialmente con ENS), y la suposición de comunicación directa entre el emisor y el receptor es realmente complicada en la práctica, por lo que podríamos terminar viendo una combinación de diferentes técnicas.
En todos estos diseños, mantener las cosas tanto descentralizadas como comprensibles para los usuarios es primordial. Necesitamos asegurarnos de que los usuarios tengan fácil acceso a una visión actualizada de cuáles son sus activos actuales y qué mensajes se han publicado que están destinados para ellos. Estas vistas deberían depender de herramientas abiertas, no de soluciones propietarias. Requerirá un trabajo arduo evitar que la mayor complejidad de la infraestructura de pagos se convierta en una "torre de abstracción" opaca donde los desarrolladores tengan dificultades para entender qué está sucediendo y adaptarlo a nuevos contextos. A pesar de los desafíos, lograr escalabilidad, seguridad en las carteras y privacidad para los usuarios regulares es crucial para el futuro de Ethereum. No se trata solo de la viabilidad técnica, sino de la accesibilidad real para los usuarios comunes. Necesitamos elevarnos para enfrentar este desafío.

