Uno de los desafíos de Ethereum es que, por defecto, el hinchazón y la complejidad del protocolo de cualquier blockchain crecen con el tiempo. Esto sucede en dos lugares:
Para que Ethereum se mantenga a largo plazo, necesitamos una fuerte contra-presión contra ambas tendencias, reduciendo la complejidad y la inflación con el tiempo. Pero al mismo tiempo, necesitamos preservar una de las propiedades clave que hacen que las blockchains sean excelentes: su permanencia. Puedes poner un NFT, una nota de amor en los datos de transacción, o un contrato inteligente que contiene un millón de dólares en la cadena, ir a una cueva durante diez años, salir y encontrarlo todavía allí esperando que lo leas e interactúes con él. Para que las dapps se sientan cómodas y vayan completamente descentralizadas y retiren sus claves de actualización, necesitan estar seguros de que sus dependencias no van a actualizarse de una manera que las rompa, especialmente la L1 en sí.
La Purga, hoja de ruta para 2023.
Equilibrarse entre estas dos necesidades, y minimizar o revertir la hinchazón, complejidad y decadencia mientras se preserva la continuidad, es absolutamente posible si nos lo proponemos. Los organismos vivos pueden hacerlo: mientras que la mayoría envejece con el tiempo,unos pocos afortunados no lo hacenIncluso los sistemas sociales puedentener una longevidad extremaEn algunas ocasiones, Ethereum ya ha mostrado éxitos: la prueba de trabajo ha desaparecido, el código de operación SELFDESTRUCT casi ha desaparecido y los nodos de la cadena de beacon ya almacenan datos antiguos solo hasta seis meses. Encontrar este camino para Ethereum de una manera más generalizada, y avanzar hacia un resultado final que sea estable a largo plazo, es el desafío definitivo de la escalabilidad a largo plazo, la sostenibilidad técnica e incluso la seguridad de Ethereum.
A partir de la hora de escribir esto, un nodo Ethereum completamente sincronizado requiereaproximadamente 1,1 terabytesde espacio en disco para el cliente de ejecución, más algunos cientos de gigabytes adicionales para el cliente de consenso. La gran mayoría de esto es historia: datos sobre bloques históricos, transacciones y recibos, la mayor parte de los cuales tienen muchos años. Esto significa que el tamaño de un nodo sigue aumentando en cientos de gigabytes cada año, incluso si el límite de gas no aumenta en absoluto.
Una característica clave que simplifica el problema de almacenamiento de historial es que cada bloque apunta al bloque anterior a través de un enlace de hash (y otro estructuras) tener consenso sobre el presente es suficiente para tener consenso sobre la historia. Siempre que la red tenga consenso sobre el último bloque, cualquier bloque histórico o transacción o estado (saldo de cuenta, nonce, código, almacenamiento) puede ser proporcionado por cualquier actor individual junto con una prueba de Merkle, y la prueba permite a cualquier otra persona verificar su corrección. Si bien el consenso es un modelo de confianza N/2-de-N, la historia es un modelo de confianza 1-de-N.
Esto abre muchas opciones sobre cómo podemos almacenar el historial. Una opción natural es una red donde cada nodo solo almacena un pequeño porcentaje de los datos. Así es como han funcionado las redes de torrents durante décadas: mientras que en conjunto la red almacena y distribuye millones de archivos, cada participante solo almacena y distribuye algunos de ellos. Tal vez de manera contraintuitiva, este enfoque no necesariamente disminuye la robustez de los datos. Si, al hacer que la ejecución del nodo sea más asequible, podemos llegar a una red con 100.000 nodos, donde cada nodo almacena un 10% aleatorio del historial, entonces cada pieza de datos se replicaría 10.000 veces, exactamente el mismo factor de replicación que una red de 10.000 nodos donde cada nodo almacena todo.
Hoy en día, Ethereum ya ha comenzado a alejarse del modelo en el que todos los nodos almacenan todo el historial para siempre. Los bloques de consenso (es decir, las partes relacionadas con el consenso de participación) solo se almacenan durante aproximadamente 6 meses. Los blobs solo se almacenan durante aproximadamente 18 días.EIP-4444 tiene como objetivo introducir un período de almacenamiento de un año para bloques y recibos históricos. Un objetivo a largo plazo es tener un período armonizado (que podría ser ~18 días) durante el cual cada nodo sea responsable de almacenar todo, y luego tener una red peer-to-peer compuesta por nodos Ethereum que almacenen datos antiguos de manera distribuida.
Los códigos de borrado se pueden utilizar para aumentar la robustez manteniendo el factor de replicación igual. De hecho, los bloques ya vienen codificados por borrado para soportar el muestreo de disponibilidad de datos. La solución más sencilla bien podría ser reutilizar este código de borrado y colocar datos de ejecución y bloque de consenso en los bloques también.
El principal trabajo pendiente consiste en crear e integrar una solución distribuida concreta para almacenar el historial, al menos el historial de ejecución, pero en última instancia también el consenso y los blobs. Las soluciones más fáciles para esto son (i) simplemente introducir una biblioteca de torrents existente, y (ii) una solución nativa de Ethereum llamada la red Portal. Una vez que se haya introducido cualquiera de estos elementos, podremos activar EIP-4444. EIP-4444 en sí no requiere una bifurcación dura, aunque sí requiere una nueva versión del protocolo de red. Por esta razón, tiene valor habilitarlo para todos los clientes al mismo tiempo, porque de lo contrario existen riesgos de que los clientes funcionen incorrectamente al conectarse a otros nodos esperando descargar la historia completa pero sin obtenerla realmente.
El principal compromiso implica cuánto nos esforzamos por hacer que los datos históricos 'antiguos' estén disponibles. La solución más sencilla sería dejar de almacenar el historial antiguo mañana y confiar en los nodos de archivo existentes y en varios proveedores centralizados para la replicación. Esto es fácil, pero debilita la posición de Ethereum como un lugar para hacer registros permanentes. El camino más difícil, pero más seguro, es primero desarrollar e integrar la red torrent para almacenar el historial de manera distribuida. Aquí, hay dos dimensiones de 'cuánto nos esforzamos':
Un enfoque maximalmente paranoico para (1) implicaríaprueba de custodia: en realidad requiere que cada validador de prueba de participación almacene un cierto porcentaje de historial, y verifique criptográficamente con regularidad que lo hagan. Un enfoque más moderado es establecer un estándar voluntario para qué porcentaje de historial almacena cada cliente.
Para (2), una implementación básica implica simplemente tomar el trabajo que ya se realiza hoy: Portal ya almacena archivos ERA que contienen todo el historial de Ethereum. Una implementación más exhaustiva implicaría conectar esto realmente con el proceso de sincronización, de modo que si alguien quisiera sincronizar un nodo que almacene todo el historial o un nodo de archivo, podría hacerlo incluso si no existieran otros nodos de archivo en línea, sincronizando directamente desde la red de Portal.
Reducir los requisitos de almacenamiento de historial es quizás aún más importante que la carencia de estado si queremos que sea extremadamente fácil ejecutar o iniciar un nodo: de los 1.1 TB que un nodo necesita tener, ~300 GB son el estado, y los restantes ~800 GB son historia. La visión de un nodo de Ethereum ejecutándose en un reloj inteligente y tardando solo unos minutos en configurarse solo es posible si se implementan tanto la carencia de estado como la EIP-4444.
Limitar el almacenamiento del historial también hace que sea más viable para las nuevas implementaciones de nodos Ethereum admitir solo las versiones recientes del protocolo, lo que les permite ser mucho más simples. Por ejemplo, muchas líneas de código pueden eliminarse de forma segura ahora que todos los espacios de almacenamiento vacíos creados durante los ataques DoS de 2016 han sidoeliminado. Ahora que el cambio a la prueba de participación es historia antigua, los clientes pueden eliminar de forma segura todo el código relacionado con el trabajo de prueba.
Incluso si eliminamos la necesidad de que los clientes almacenen el historial, el requisito de almacenamiento de un cliente seguirá creciendo, en alrededor de 50 GB por año, debido al crecimiento continuo del estado: saldos de cuentas y números, código de contrato y almacenamiento de contrato. Los usuarios pueden pagar un costo único para imponer una carga a los clientes actuales y futuros de Ethereum para siempre.
El estado es mucho más difícil de "caducar" que la historia, porque el EVM está diseñado fundamentalmente en torno a una suposición de que una vez que se crea un objeto de estado, siempre estará allí y podrá ser leído por cualquier transacción en cualquier momento. Si introducimos la falta de estado, hay un argumento de que tal vez este problema no es tan grave: solo una clase especializada de constructores de bloques necesitaría almacenar realmente el estado, y todos los demás nodos (incluso lista de inclusión¡(producción!) puede ejecutarse sin estado. Sin embargo, hay un argumento de que no queremos depender demasiado de la falta de estado, y eventualmente podemos querer caducar el estado para mantener a Ethereum descentralizado.
Hoy, cuando creas un nuevo objeto de estado (lo cual puede ocurrir de tres maneras: (i) enviando ETH a una nueva cuenta, (ii) creando una nueva cuenta con código, (iii) estableciendo un espacio de almacenamiento previamente no utilizado), ese objeto de estado permanece en el estado para siempre. Lo que queremos en su lugar, es que los objetos expiren automáticamente con el tiempo. El desafío clave es hacer esto de una manera que cumpla tres objetivos:
Es fácil resolver el problema sin satisfacer estos objetivos. Por ejemplo, puede hacer que cada objeto de estado también almacene un contador para su fecha de vencimiento (que podría extenderse mediante la quema de ETH, lo que podría suceder automáticamente cada vez que se lea o escriba) y tener un proceso que recorra el estado para eliminar los objetos de estado caducados. Sin embargo, esto introduce cálculos adicionales (e incluso requisitos de almacenamiento), y definitivamente no satisface el requisito de facilidad de uso. Los desarrolladores también tendrían dificultades para razonar sobre los casos extremos que involucran valores de almacenamiento que a veces se restablecen a cero. Si haces que el temporizador de vencimiento abarque todo el contrato, esto hace la vida técnicamente más fácil para los desarrolladores, pero hace que la economía sea más difícil: los desarrolladores tendrían que pensar en cómo "pasar" los costos continuos de almacenamiento a sus usuarios.
Estos son problemas con los que la comunidad de desarrollo principal de Ethereum ha luchado durante muchos años, incluidas propuestas como "alquiler de blockchain“ y “regenesis“. Finalmente, combinamos las mejores partes de las propuestas y convergimos en dos categorías de “soluciones menos malas conocidas”:
Todas las propuestas de expiración parcial del estado funcionan según el mismo principio. Dividimos el estado en trozos. Todos almacenan permanentemente el "mapa de nivel superior" de qué fragmentos están vacíos o no vacíos. Los datos dentro de cada fragmento solo se almacenan si esos datos han sido recientemente accedidos. Existe un mecanismo de "resurrección" donde si un fragmento ya no se almacena, cualquiera puede recuperar esos datos proporcionando una prueba de cuáles eran los datos.
Las principales diferencias entre estas propuestas son: (i) ¿cómo definimos "recientemente", y (ii) cómo definimos "fragmento"? Una propuesta concreta es,EIP-7736, que se basa en el diseño de “tallo-y-hoja” introducido para árboles Verkle (aunque compatible con cualquier forma de apatridia, por ejemplo, árboles binarios). En este diseño, el encabezado, el código y las ranuras de almacenamiento que son adyacentes entre sí se almacenan bajo el mismo "tallo". Los datos almacenados bajo un tallo pueden ser como máximo 256 * 31 = 7.936 bytes. En muchos casos, todo el encabezado y el código, así como muchas ranuras de almacenamiento de claves, de una cuenta se almacenarán en la misma talla. Si los datos de una raíz determinada no se leen ni escriben durante 6 meses, los datos ya no se almacenan y, en su lugar, solo se almacena un compromiso de 32 bytes ("stub") con los datos. Las transacciones futuras que accedan a esos datos tendrían que "resucitar" los datos, con una prueba que se cotejaría con el talón.
Hay otras formas de implementar una idea similar. Por ejemplo, si la granularidad a nivel de cuenta no es suficiente, podríamos hacer un esquema en el que cada fracción 1/232 del árbol esté gobernada por un mecanismo similar de tallo y hoja.
Esto es más complicado debido a los incentivos: un atacante podría obligar a los clientes a almacenar permanentemente una gran cantidad de estado colocando una gran cantidad de datos en un solo subárbol y enviando una sola transacción cada año para "renovar el árbol". Si hace que el costo de renovación sea proporcional (o la duración de la renovación inversamente proporcional) al tamaño del árbol, entonces alguien podría molestar a otro usuario colocando una gran cantidad de datos en el mismo subárbol que ellos. Se podría intentar limitar ambos problemas haciendo que la granularidad sea dinámica en función del tamaño del subárbol: por ejemplo, cada objeto de estado consecutivo 216 = 65536 podría tratarse como un "grupo". Sin embargo, estas ideas son más complejas; El enfoque basado en STEM es simple y alinea los incentivos, ya que normalmente todos los datos de un STEM están relacionados con la misma aplicación o usuario.
¿Qué pasa si quisiéramos evitar cualquier crecimiento permanente del estado, incluso los puntales de 32 bytes? Este es un problema difícil debido a @vbuterin/state_size_management#Resurrection-conflicts">conflictos de resurrección: ¿qué pasa si se elimina un objeto de estado, la ejecución posterior de EVM pone otro objeto de estado exactamente en la misma posición, pero luego alguien que se preocupa por el objeto de estado original regresa e intenta recuperarlo? Con la caducidad parcial del estado, el "código auxiliar" impide que se creen nuevos datos. Con la caducidad completa del estado, no podemos permitirnos almacenar ni siquiera el talón.
El diseño basado en el período de dirección es la mejor idea conocida para resolver esto. En lugar de tener un árbol de estado que almacene todo el estado, tenemos una lista en constante crecimiento de árboles de estado, y cualquier estado que se lea o escriba se guarda en el árbol de estado más reciente. Un nuevo árbol de estado vacío se agrega una vez por período (piense: 1 año). Los árboles de estado más antiguos quedan congelados sólidamente. Se espera que los nodos completos almacenen solo los dos árboles más recientes. Si un objeto de estado no se tocó durante dos períodos y, por lo tanto, cae en un árbol vencido, aún se puede leer o escribir, pero la transacción debería demostrar un prueba de Merkle para ello, y una vez que lo haga, se guardará una copia en el árbol más reciente de nuevo.
Una idea clave para hacer todo esto amigable para el usuario y el desarrollador es el concepto de períodos de dirección. Un período de dirección es un número que forma parte de una dirección. Una regla clave es que una dirección con un período de dirección N solo puede leerse o escribirse durante o después del período N (es decir, cuando la lista de árboles de estado alcanza la longitud N). Si está guardando un nuevo objeto de estado (por ejemplo, un nuevo contrato o un nuevo saldo ERC20), si se asegura de poner el objeto de estado en un contrato cuyo período de dirección sea N o N-1, entonces puede guardarlo inmediatamente, sin necesidad de proporcionar pruebas de que no había nada allí antes. Cualquier adición o edición de estado en períodos de dirección anteriores, por otro lado, requiere una prueba.
Este diseño preserva la mayoría de las propiedades actuales de Ethereum, es muy ligero en cálculos adicionales, permite que las aplicaciones se escriban casi como lo hacen hoy en día (los ERC20 necesitarán reescribirse, para asegurar que los saldos de las direcciones con periodo de dirección N se almacenen en un contrato secundario que tenga en sí mismo un periodo de dirección N), y resuelve el problema de 'el usuario se mete en una cueva durante cinco años'. Sin embargo, tiene un gran problema: las direcciones deben ampliarse más allá de 20 bytes para ajustarse a los periodos de dirección.
Una propuesta es introducir un nuevo formato de dirección de 32 bytes, que incluye un número de versión, un número de período de dirección y un hash expandido.
0x01000000000157aE408398dF7E5f4552091A69125d5dFcb7B8C2659029395bdF
El rojo es un número de versión. Los cuatro ceros de color naranja aquí están destinados a ser un espacio vacío, que podría contener un número de fragmento en el futuro. El verde es un número de período de dirección. El azul es un hash de 26 bytes.
El desafío clave aquí es la compatibilidad con versiones anteriores. Los contratos existentes están diseñados en torno a direcciones de 20 bytes y, a menudo, utilizan técnicas de empaquetado de bytes ajustado que asumen explícitamente que las direcciones tienen exactamente 20 bytes de longitud. @ipsilonUna idea para resolver esto implica un mapa de traducción, donde los contratos de estilo antiguo que interactúan con direcciones de estilo nuevo verían un hash de 20 bytes de la dirección de estilo nuevo. Sin embargo, hay complejidades significativas involucradas en hacer esto seguro.
Otro enfoque va en la dirección opuesta: inmediatamente prohibimos un subrango de direcciones de tamaño 2128 (por ejemplo, todas las direcciones que comienzan con 0xffffffff), y luego usamos ese rango para introducir direcciones con periodos de dirección y hashes de 14 bytes.
0xfffffff000169125d5dFcb7B8C2659029395bdF
El sacrificio clave que hace este enfoque es queintroduce riesgos de seguridad para las direcciones contrafactuales: direcciones que contienen activos o permisos, pero cuyo código aún no ha sido publicado en la cadena. El riesgo implica que alguien cree una dirección que afirma tener una pieza de código (aún no publicado), pero también tiene otra pieza válida de código que se hash a la misma dirección. Calcular una colisión de este tipo requiere 280hoy en día; la contracción del espacio de direcciones reduciría este número a un 2 muy accesible56 hashes.
El área clave de riesgo, las direcciones contrafactuales que no son billeteras mantenidas por un solo propietario, son un caso relativamente raro hoy en día, pero es probable que se vuelvan más comunes a medida que ingresamos a un mundo multi-L2. La única solución es simplemente aceptar este riesgo, pero identificar todos los casos de uso comunes donde esto pueda ser un problema y encontrar soluciones efectivas.
Veo cuatro caminos viables para el futuro:
Un punto importante es que los problemas difíciles en torno a la expansión y contracción del espacio de direcciones deberán abordarse en algún momento, independientemente de si se implementan o no los esquemas de caducidad del estado que dependen de los cambios de formato de dirección. Hoy en día, lleva aproximadamente 280hashes para generar una colisión de direcciones, una carga computacional que ya es factible para actores extremadamente bien dotados: una GPU puede hacer alrededor de 227hashes, por lo que al ejecutarse durante un año puede calcular 252, así que todo ~2^30 GPUs en el mundopodría calcular una colisión en ~1/4 de año, y los FPGAs y ASICs podrían acelerar esto aún más. En el futuro, tales ataques estarán abiertos a más y más personas. Por lo tanto, el costo real de implementar la expiración completa del estado puede no ser tan alto como parece, ya que tenemos que resolver este problema de direcciones muy desafiante de todos modos.
Hacer que el estado expire potencialmente facilita las transiciones de un formato de árbol de estado a otro, porque no habrá necesidad de un procedimiento de transición: simplemente podrías comenzar a hacer nuevos árboles usando un nuevo formato, y luego más tarde hacer un hard fork para convertir los árboles antiguos. Por lo tanto, aunque la expiración del estado es compleja, tiene beneficios en simplificar otros aspectos del mapa de ruta.
Una de las principales condiciones previas de seguridad, accesibilidad yneutralidad creíblees la simplicidad. Si un protocolo es hermoso y simple, reduce la probabilidad de que haya errores. Aumenta la probabilidad de que nuevos desarrolladores puedan entrar y trabajar con cualquier parte de él. Es más probable que sea justo y más fácil de defender contra intereses especiales. Desafortunadamente, los protocolos, como cualquier sistema social, por defecto se vuelven más complejos con el tiempo. Si no queremos que Ethereum caiga en un agujero negro de complejidad creciente, necesitamos hacer una de dos cosas: (i) dejar de hacer cambios y fosilizar el protocolo, (ii) ser capaces de eliminar realmente características y reducir la complejidad. También es posible un camino intermedio, haciendo menos cambios en el protocolo y también eliminando al menos un poco de complejidad con el tiempo. Esta sección hablará de cómo podemos reducir o eliminar la complejidad.
No existe una solución única que pueda reducir la complejidad del protocolo; La naturaleza inherente del problema es que hay muchas pequeñas soluciones.
Un ejemplo que ya está casi terminado y puede servir como un modelo de cómo manejar los demás es el @vbuterin/selfdestruct">eliminación del código de operación SELFDESTRUCT. El código de operación SELFDESTRUCT era el único código de operación que podía modificar un número ilimitado de ranuras de almacenamiento dentro de un solo bloque, lo que requería que los clientes implementaran una complejidad significativamente mayor para evitar ataques DoS. El propósito original del código de operación era permitir la compensación voluntaria de estados, lo que permitía que el tamaño del estado disminuyera con el tiempo. En la práctica, muy pocos terminaron usándolo. El el código de operación fue reducidosolo permitir cuentas autodestructivas creadas en la misma transacción en la bifurcación Dencun. Esto resuelve el problema de DoS y permite una simplificación significativa en el código del cliente. En el futuro, probablemente tenga sentido eliminar completamente el opcode.
Algunos ejemplos clave de oportunidades de simplificación del protocolo que se han identificado hasta ahora incluyen lo siguiente. En primer lugar, algunos ejemplos que están fuera del EVM; estos son relativamente no invasivos, y por lo tanto más fáciles de consensuar e implementar en un período de tiempo más corto.
Ahora, algunos ejemplos que están dentro del EVM:
El principal compromiso al hacer este tipo de simplificación de características es (i) cuánto simplificamos y qué tan rápido, versus (ii) la compatibilidad con versiones anteriores. El valor de Ethereum como cadena proviene de ser una plataforma en la que puedes implementar una aplicación y estar seguro de que seguirá funcionando muchos años después. Al mismo tiempo, es posible llevar ese ideal demasiado lejos y,parafrasear a William Jennings Bryan«crucificar Ethereum en una cruz de compatibilidad hacia atrás». Si solo hay dos aplicaciones en todo Ethereum que utilizan una determinada función, y una no ha tenido usuarios durante años y la otra se utiliza casi por completo y asegura un valor total de $57, entonces simplemente deberíamos eliminar la función, y si es necesario, pagar a las víctimas $57 de nuestro bolsillo.
El problema social más amplio radica en crear un canalización estandarizada para realizar cambios no urgentes que rompan la compatibilidad hacia atrás. Una forma de abordar esto es examinar y ampliar los precedentes existentes, como el proceso SELFDESTRUCT. La canalización se ve algo así:
Debe haber un canal de varios años entre el paso 1 y el paso 4, con información clara sobre qué elementos se encuentran en cada paso. En ese punto, hay un equilibrio entre cuán vigoroso y rápido es el canal de eliminación de características, en comparación con ser más conservador y asignar más recursos a otras áreas del desarrollo del protocolo, pero aún estamos lejos de la frontera de Pareto.
Un conjunto importante de cambios que se ha propuesto para el EVM es el Formato de Objeto de EVM (EOF). EOF introduce una gran cantidad de cambios, como prohibir la observabilidad del gas, la observabilidad del código (es decir, no CODECOPY), permitiendo solo saltos estáticos. El objetivo es permitir que el EVM se actualice más, de una manera que tenga propiedades más fuertes, al tiempo que se conserva la compatibilidad con versiones anteriores (ya que el EVM anterior a EOF seguirá existiendo).
Esto tiene la ventaja de crear un camino natural para agregar nuevas características de EVM y fomentar la migración a un EVM más restrictivo con garantías más sólidas. Tiene la desventaja de aumentar significativamente la complejidad del protocolo, a menos que podamos encontrar una forma de eventualmente degradar y eliminar el antiguo EVM. Una pregunta importante es: ¿qué papel juega EOF en las propuestas de simplificación de EVM, especialmente si el objetivo es reducir la complejidad del EVM en su conjunto?
Muchas de las propuestas de "mejora" en el resto del plan de trabajo también son oportunidades para simplificar características antiguas. Para repetir algunos ejemplos de arriba:
Una estrategia de simplificación más radical de Ethereum es mantener el protocolo tal como está, pero mover gran parte de sus características de protocolo a ser código de contrato.
La versión más extrema de esto sería hacer que Ethereum L1 "técnicamente" sea solo la cadena de balizas e introducir una VM mínima (por ejemplo, RISC-V, Cairo, o algo aún más minimal especializado para probar sistemas) que permite a cualquier otra persona crear su propio rollup. El EVM se convertiría entonces en el primero de estos rollups. Ironicamente, este es exactamente el mismo resultado que el propuestas de entorno de ejecución de 2019-20, aunque las SNARKs hacen que sea significativamente más viable implementarlo en realidad.
Un enfoque más moderado sería mantener la relación entre la cadena beacon y el entorno de ejecución actual de Ethereum tal como está, pero hacer un intercambio in situ del EVM. Podríamos elegir RISC-V, Cairo u otro VM para que sea el nuevo "VM oficial de Ethereum", y luego forzar la conversión de todos los contratos de EVM en código de nuevo VM que interprete la lógica del código original (compilándolo o interpretándolo). Teóricamente, esto incluso se podría hacer con el "VM de destino" siendo una versión de EOF.
Uno de los desafíos de Ethereum es que, por defecto, el hinchazón y la complejidad del protocolo de cualquier blockchain crecen con el tiempo. Esto sucede en dos lugares:
Para que Ethereum se mantenga a largo plazo, necesitamos una fuerte contra-presión contra ambas tendencias, reduciendo la complejidad y la inflación con el tiempo. Pero al mismo tiempo, necesitamos preservar una de las propiedades clave que hacen que las blockchains sean excelentes: su permanencia. Puedes poner un NFT, una nota de amor en los datos de transacción, o un contrato inteligente que contiene un millón de dólares en la cadena, ir a una cueva durante diez años, salir y encontrarlo todavía allí esperando que lo leas e interactúes con él. Para que las dapps se sientan cómodas y vayan completamente descentralizadas y retiren sus claves de actualización, necesitan estar seguros de que sus dependencias no van a actualizarse de una manera que las rompa, especialmente la L1 en sí.
La Purga, hoja de ruta para 2023.
Equilibrarse entre estas dos necesidades, y minimizar o revertir la hinchazón, complejidad y decadencia mientras se preserva la continuidad, es absolutamente posible si nos lo proponemos. Los organismos vivos pueden hacerlo: mientras que la mayoría envejece con el tiempo,unos pocos afortunados no lo hacenIncluso los sistemas sociales puedentener una longevidad extremaEn algunas ocasiones, Ethereum ya ha mostrado éxitos: la prueba de trabajo ha desaparecido, el código de operación SELFDESTRUCT casi ha desaparecido y los nodos de la cadena de beacon ya almacenan datos antiguos solo hasta seis meses. Encontrar este camino para Ethereum de una manera más generalizada, y avanzar hacia un resultado final que sea estable a largo plazo, es el desafío definitivo de la escalabilidad a largo plazo, la sostenibilidad técnica e incluso la seguridad de Ethereum.
A partir de la hora de escribir esto, un nodo Ethereum completamente sincronizado requiereaproximadamente 1,1 terabytesde espacio en disco para el cliente de ejecución, más algunos cientos de gigabytes adicionales para el cliente de consenso. La gran mayoría de esto es historia: datos sobre bloques históricos, transacciones y recibos, la mayor parte de los cuales tienen muchos años. Esto significa que el tamaño de un nodo sigue aumentando en cientos de gigabytes cada año, incluso si el límite de gas no aumenta en absoluto.
Una característica clave que simplifica el problema de almacenamiento de historial es que cada bloque apunta al bloque anterior a través de un enlace de hash (y otro estructuras) tener consenso sobre el presente es suficiente para tener consenso sobre la historia. Siempre que la red tenga consenso sobre el último bloque, cualquier bloque histórico o transacción o estado (saldo de cuenta, nonce, código, almacenamiento) puede ser proporcionado por cualquier actor individual junto con una prueba de Merkle, y la prueba permite a cualquier otra persona verificar su corrección. Si bien el consenso es un modelo de confianza N/2-de-N, la historia es un modelo de confianza 1-de-N.
Esto abre muchas opciones sobre cómo podemos almacenar el historial. Una opción natural es una red donde cada nodo solo almacena un pequeño porcentaje de los datos. Así es como han funcionado las redes de torrents durante décadas: mientras que en conjunto la red almacena y distribuye millones de archivos, cada participante solo almacena y distribuye algunos de ellos. Tal vez de manera contraintuitiva, este enfoque no necesariamente disminuye la robustez de los datos. Si, al hacer que la ejecución del nodo sea más asequible, podemos llegar a una red con 100.000 nodos, donde cada nodo almacena un 10% aleatorio del historial, entonces cada pieza de datos se replicaría 10.000 veces, exactamente el mismo factor de replicación que una red de 10.000 nodos donde cada nodo almacena todo.
Hoy en día, Ethereum ya ha comenzado a alejarse del modelo en el que todos los nodos almacenan todo el historial para siempre. Los bloques de consenso (es decir, las partes relacionadas con el consenso de participación) solo se almacenan durante aproximadamente 6 meses. Los blobs solo se almacenan durante aproximadamente 18 días.EIP-4444 tiene como objetivo introducir un período de almacenamiento de un año para bloques y recibos históricos. Un objetivo a largo plazo es tener un período armonizado (que podría ser ~18 días) durante el cual cada nodo sea responsable de almacenar todo, y luego tener una red peer-to-peer compuesta por nodos Ethereum que almacenen datos antiguos de manera distribuida.
Los códigos de borrado se pueden utilizar para aumentar la robustez manteniendo el factor de replicación igual. De hecho, los bloques ya vienen codificados por borrado para soportar el muestreo de disponibilidad de datos. La solución más sencilla bien podría ser reutilizar este código de borrado y colocar datos de ejecución y bloque de consenso en los bloques también.
El principal trabajo pendiente consiste en crear e integrar una solución distribuida concreta para almacenar el historial, al menos el historial de ejecución, pero en última instancia también el consenso y los blobs. Las soluciones más fáciles para esto son (i) simplemente introducir una biblioteca de torrents existente, y (ii) una solución nativa de Ethereum llamada la red Portal. Una vez que se haya introducido cualquiera de estos elementos, podremos activar EIP-4444. EIP-4444 en sí no requiere una bifurcación dura, aunque sí requiere una nueva versión del protocolo de red. Por esta razón, tiene valor habilitarlo para todos los clientes al mismo tiempo, porque de lo contrario existen riesgos de que los clientes funcionen incorrectamente al conectarse a otros nodos esperando descargar la historia completa pero sin obtenerla realmente.
El principal compromiso implica cuánto nos esforzamos por hacer que los datos históricos 'antiguos' estén disponibles. La solución más sencilla sería dejar de almacenar el historial antiguo mañana y confiar en los nodos de archivo existentes y en varios proveedores centralizados para la replicación. Esto es fácil, pero debilita la posición de Ethereum como un lugar para hacer registros permanentes. El camino más difícil, pero más seguro, es primero desarrollar e integrar la red torrent para almacenar el historial de manera distribuida. Aquí, hay dos dimensiones de 'cuánto nos esforzamos':
Un enfoque maximalmente paranoico para (1) implicaríaprueba de custodia: en realidad requiere que cada validador de prueba de participación almacene un cierto porcentaje de historial, y verifique criptográficamente con regularidad que lo hagan. Un enfoque más moderado es establecer un estándar voluntario para qué porcentaje de historial almacena cada cliente.
Para (2), una implementación básica implica simplemente tomar el trabajo que ya se realiza hoy: Portal ya almacena archivos ERA que contienen todo el historial de Ethereum. Una implementación más exhaustiva implicaría conectar esto realmente con el proceso de sincronización, de modo que si alguien quisiera sincronizar un nodo que almacene todo el historial o un nodo de archivo, podría hacerlo incluso si no existieran otros nodos de archivo en línea, sincronizando directamente desde la red de Portal.
Reducir los requisitos de almacenamiento de historial es quizás aún más importante que la carencia de estado si queremos que sea extremadamente fácil ejecutar o iniciar un nodo: de los 1.1 TB que un nodo necesita tener, ~300 GB son el estado, y los restantes ~800 GB son historia. La visión de un nodo de Ethereum ejecutándose en un reloj inteligente y tardando solo unos minutos en configurarse solo es posible si se implementan tanto la carencia de estado como la EIP-4444.
Limitar el almacenamiento del historial también hace que sea más viable para las nuevas implementaciones de nodos Ethereum admitir solo las versiones recientes del protocolo, lo que les permite ser mucho más simples. Por ejemplo, muchas líneas de código pueden eliminarse de forma segura ahora que todos los espacios de almacenamiento vacíos creados durante los ataques DoS de 2016 han sidoeliminado. Ahora que el cambio a la prueba de participación es historia antigua, los clientes pueden eliminar de forma segura todo el código relacionado con el trabajo de prueba.
Incluso si eliminamos la necesidad de que los clientes almacenen el historial, el requisito de almacenamiento de un cliente seguirá creciendo, en alrededor de 50 GB por año, debido al crecimiento continuo del estado: saldos de cuentas y números, código de contrato y almacenamiento de contrato. Los usuarios pueden pagar un costo único para imponer una carga a los clientes actuales y futuros de Ethereum para siempre.
El estado es mucho más difícil de "caducar" que la historia, porque el EVM está diseñado fundamentalmente en torno a una suposición de que una vez que se crea un objeto de estado, siempre estará allí y podrá ser leído por cualquier transacción en cualquier momento. Si introducimos la falta de estado, hay un argumento de que tal vez este problema no es tan grave: solo una clase especializada de constructores de bloques necesitaría almacenar realmente el estado, y todos los demás nodos (incluso lista de inclusión¡(producción!) puede ejecutarse sin estado. Sin embargo, hay un argumento de que no queremos depender demasiado de la falta de estado, y eventualmente podemos querer caducar el estado para mantener a Ethereum descentralizado.
Hoy, cuando creas un nuevo objeto de estado (lo cual puede ocurrir de tres maneras: (i) enviando ETH a una nueva cuenta, (ii) creando una nueva cuenta con código, (iii) estableciendo un espacio de almacenamiento previamente no utilizado), ese objeto de estado permanece en el estado para siempre. Lo que queremos en su lugar, es que los objetos expiren automáticamente con el tiempo. El desafío clave es hacer esto de una manera que cumpla tres objetivos:
Es fácil resolver el problema sin satisfacer estos objetivos. Por ejemplo, puede hacer que cada objeto de estado también almacene un contador para su fecha de vencimiento (que podría extenderse mediante la quema de ETH, lo que podría suceder automáticamente cada vez que se lea o escriba) y tener un proceso que recorra el estado para eliminar los objetos de estado caducados. Sin embargo, esto introduce cálculos adicionales (e incluso requisitos de almacenamiento), y definitivamente no satisface el requisito de facilidad de uso. Los desarrolladores también tendrían dificultades para razonar sobre los casos extremos que involucran valores de almacenamiento que a veces se restablecen a cero. Si haces que el temporizador de vencimiento abarque todo el contrato, esto hace la vida técnicamente más fácil para los desarrolladores, pero hace que la economía sea más difícil: los desarrolladores tendrían que pensar en cómo "pasar" los costos continuos de almacenamiento a sus usuarios.
Estos son problemas con los que la comunidad de desarrollo principal de Ethereum ha luchado durante muchos años, incluidas propuestas como "alquiler de blockchain“ y “regenesis“. Finalmente, combinamos las mejores partes de las propuestas y convergimos en dos categorías de “soluciones menos malas conocidas”:
Todas las propuestas de expiración parcial del estado funcionan según el mismo principio. Dividimos el estado en trozos. Todos almacenan permanentemente el "mapa de nivel superior" de qué fragmentos están vacíos o no vacíos. Los datos dentro de cada fragmento solo se almacenan si esos datos han sido recientemente accedidos. Existe un mecanismo de "resurrección" donde si un fragmento ya no se almacena, cualquiera puede recuperar esos datos proporcionando una prueba de cuáles eran los datos.
Las principales diferencias entre estas propuestas son: (i) ¿cómo definimos "recientemente", y (ii) cómo definimos "fragmento"? Una propuesta concreta es,EIP-7736, que se basa en el diseño de “tallo-y-hoja” introducido para árboles Verkle (aunque compatible con cualquier forma de apatridia, por ejemplo, árboles binarios). En este diseño, el encabezado, el código y las ranuras de almacenamiento que son adyacentes entre sí se almacenan bajo el mismo "tallo". Los datos almacenados bajo un tallo pueden ser como máximo 256 * 31 = 7.936 bytes. En muchos casos, todo el encabezado y el código, así como muchas ranuras de almacenamiento de claves, de una cuenta se almacenarán en la misma talla. Si los datos de una raíz determinada no se leen ni escriben durante 6 meses, los datos ya no se almacenan y, en su lugar, solo se almacena un compromiso de 32 bytes ("stub") con los datos. Las transacciones futuras que accedan a esos datos tendrían que "resucitar" los datos, con una prueba que se cotejaría con el talón.
Hay otras formas de implementar una idea similar. Por ejemplo, si la granularidad a nivel de cuenta no es suficiente, podríamos hacer un esquema en el que cada fracción 1/232 del árbol esté gobernada por un mecanismo similar de tallo y hoja.
Esto es más complicado debido a los incentivos: un atacante podría obligar a los clientes a almacenar permanentemente una gran cantidad de estado colocando una gran cantidad de datos en un solo subárbol y enviando una sola transacción cada año para "renovar el árbol". Si hace que el costo de renovación sea proporcional (o la duración de la renovación inversamente proporcional) al tamaño del árbol, entonces alguien podría molestar a otro usuario colocando una gran cantidad de datos en el mismo subárbol que ellos. Se podría intentar limitar ambos problemas haciendo que la granularidad sea dinámica en función del tamaño del subárbol: por ejemplo, cada objeto de estado consecutivo 216 = 65536 podría tratarse como un "grupo". Sin embargo, estas ideas son más complejas; El enfoque basado en STEM es simple y alinea los incentivos, ya que normalmente todos los datos de un STEM están relacionados con la misma aplicación o usuario.
¿Qué pasa si quisiéramos evitar cualquier crecimiento permanente del estado, incluso los puntales de 32 bytes? Este es un problema difícil debido a @vbuterin/state_size_management#Resurrection-conflicts">conflictos de resurrección: ¿qué pasa si se elimina un objeto de estado, la ejecución posterior de EVM pone otro objeto de estado exactamente en la misma posición, pero luego alguien que se preocupa por el objeto de estado original regresa e intenta recuperarlo? Con la caducidad parcial del estado, el "código auxiliar" impide que se creen nuevos datos. Con la caducidad completa del estado, no podemos permitirnos almacenar ni siquiera el talón.
El diseño basado en el período de dirección es la mejor idea conocida para resolver esto. En lugar de tener un árbol de estado que almacene todo el estado, tenemos una lista en constante crecimiento de árboles de estado, y cualquier estado que se lea o escriba se guarda en el árbol de estado más reciente. Un nuevo árbol de estado vacío se agrega una vez por período (piense: 1 año). Los árboles de estado más antiguos quedan congelados sólidamente. Se espera que los nodos completos almacenen solo los dos árboles más recientes. Si un objeto de estado no se tocó durante dos períodos y, por lo tanto, cae en un árbol vencido, aún se puede leer o escribir, pero la transacción debería demostrar un prueba de Merkle para ello, y una vez que lo haga, se guardará una copia en el árbol más reciente de nuevo.
Una idea clave para hacer todo esto amigable para el usuario y el desarrollador es el concepto de períodos de dirección. Un período de dirección es un número que forma parte de una dirección. Una regla clave es que una dirección con un período de dirección N solo puede leerse o escribirse durante o después del período N (es decir, cuando la lista de árboles de estado alcanza la longitud N). Si está guardando un nuevo objeto de estado (por ejemplo, un nuevo contrato o un nuevo saldo ERC20), si se asegura de poner el objeto de estado en un contrato cuyo período de dirección sea N o N-1, entonces puede guardarlo inmediatamente, sin necesidad de proporcionar pruebas de que no había nada allí antes. Cualquier adición o edición de estado en períodos de dirección anteriores, por otro lado, requiere una prueba.
Este diseño preserva la mayoría de las propiedades actuales de Ethereum, es muy ligero en cálculos adicionales, permite que las aplicaciones se escriban casi como lo hacen hoy en día (los ERC20 necesitarán reescribirse, para asegurar que los saldos de las direcciones con periodo de dirección N se almacenen en un contrato secundario que tenga en sí mismo un periodo de dirección N), y resuelve el problema de 'el usuario se mete en una cueva durante cinco años'. Sin embargo, tiene un gran problema: las direcciones deben ampliarse más allá de 20 bytes para ajustarse a los periodos de dirección.
Una propuesta es introducir un nuevo formato de dirección de 32 bytes, que incluye un número de versión, un número de período de dirección y un hash expandido.
0x01000000000157aE408398dF7E5f4552091A69125d5dFcb7B8C2659029395bdF
El rojo es un número de versión. Los cuatro ceros de color naranja aquí están destinados a ser un espacio vacío, que podría contener un número de fragmento en el futuro. El verde es un número de período de dirección. El azul es un hash de 26 bytes.
El desafío clave aquí es la compatibilidad con versiones anteriores. Los contratos existentes están diseñados en torno a direcciones de 20 bytes y, a menudo, utilizan técnicas de empaquetado de bytes ajustado que asumen explícitamente que las direcciones tienen exactamente 20 bytes de longitud. @ipsilonUna idea para resolver esto implica un mapa de traducción, donde los contratos de estilo antiguo que interactúan con direcciones de estilo nuevo verían un hash de 20 bytes de la dirección de estilo nuevo. Sin embargo, hay complejidades significativas involucradas en hacer esto seguro.
Otro enfoque va en la dirección opuesta: inmediatamente prohibimos un subrango de direcciones de tamaño 2128 (por ejemplo, todas las direcciones que comienzan con 0xffffffff), y luego usamos ese rango para introducir direcciones con periodos de dirección y hashes de 14 bytes.
0xfffffff000169125d5dFcb7B8C2659029395bdF
El sacrificio clave que hace este enfoque es queintroduce riesgos de seguridad para las direcciones contrafactuales: direcciones que contienen activos o permisos, pero cuyo código aún no ha sido publicado en la cadena. El riesgo implica que alguien cree una dirección que afirma tener una pieza de código (aún no publicado), pero también tiene otra pieza válida de código que se hash a la misma dirección. Calcular una colisión de este tipo requiere 280hoy en día; la contracción del espacio de direcciones reduciría este número a un 2 muy accesible56 hashes.
El área clave de riesgo, las direcciones contrafactuales que no son billeteras mantenidas por un solo propietario, son un caso relativamente raro hoy en día, pero es probable que se vuelvan más comunes a medida que ingresamos a un mundo multi-L2. La única solución es simplemente aceptar este riesgo, pero identificar todos los casos de uso comunes donde esto pueda ser un problema y encontrar soluciones efectivas.
Veo cuatro caminos viables para el futuro:
Un punto importante es que los problemas difíciles en torno a la expansión y contracción del espacio de direcciones deberán abordarse en algún momento, independientemente de si se implementan o no los esquemas de caducidad del estado que dependen de los cambios de formato de dirección. Hoy en día, lleva aproximadamente 280hashes para generar una colisión de direcciones, una carga computacional que ya es factible para actores extremadamente bien dotados: una GPU puede hacer alrededor de 227hashes, por lo que al ejecutarse durante un año puede calcular 252, así que todo ~2^30 GPUs en el mundopodría calcular una colisión en ~1/4 de año, y los FPGAs y ASICs podrían acelerar esto aún más. En el futuro, tales ataques estarán abiertos a más y más personas. Por lo tanto, el costo real de implementar la expiración completa del estado puede no ser tan alto como parece, ya que tenemos que resolver este problema de direcciones muy desafiante de todos modos.
Hacer que el estado expire potencialmente facilita las transiciones de un formato de árbol de estado a otro, porque no habrá necesidad de un procedimiento de transición: simplemente podrías comenzar a hacer nuevos árboles usando un nuevo formato, y luego más tarde hacer un hard fork para convertir los árboles antiguos. Por lo tanto, aunque la expiración del estado es compleja, tiene beneficios en simplificar otros aspectos del mapa de ruta.
Una de las principales condiciones previas de seguridad, accesibilidad yneutralidad creíblees la simplicidad. Si un protocolo es hermoso y simple, reduce la probabilidad de que haya errores. Aumenta la probabilidad de que nuevos desarrolladores puedan entrar y trabajar con cualquier parte de él. Es más probable que sea justo y más fácil de defender contra intereses especiales. Desafortunadamente, los protocolos, como cualquier sistema social, por defecto se vuelven más complejos con el tiempo. Si no queremos que Ethereum caiga en un agujero negro de complejidad creciente, necesitamos hacer una de dos cosas: (i) dejar de hacer cambios y fosilizar el protocolo, (ii) ser capaces de eliminar realmente características y reducir la complejidad. También es posible un camino intermedio, haciendo menos cambios en el protocolo y también eliminando al menos un poco de complejidad con el tiempo. Esta sección hablará de cómo podemos reducir o eliminar la complejidad.
No existe una solución única que pueda reducir la complejidad del protocolo; La naturaleza inherente del problema es que hay muchas pequeñas soluciones.
Un ejemplo que ya está casi terminado y puede servir como un modelo de cómo manejar los demás es el @vbuterin/selfdestruct">eliminación del código de operación SELFDESTRUCT. El código de operación SELFDESTRUCT era el único código de operación que podía modificar un número ilimitado de ranuras de almacenamiento dentro de un solo bloque, lo que requería que los clientes implementaran una complejidad significativamente mayor para evitar ataques DoS. El propósito original del código de operación era permitir la compensación voluntaria de estados, lo que permitía que el tamaño del estado disminuyera con el tiempo. En la práctica, muy pocos terminaron usándolo. El el código de operación fue reducidosolo permitir cuentas autodestructivas creadas en la misma transacción en la bifurcación Dencun. Esto resuelve el problema de DoS y permite una simplificación significativa en el código del cliente. En el futuro, probablemente tenga sentido eliminar completamente el opcode.
Algunos ejemplos clave de oportunidades de simplificación del protocolo que se han identificado hasta ahora incluyen lo siguiente. En primer lugar, algunos ejemplos que están fuera del EVM; estos son relativamente no invasivos, y por lo tanto más fáciles de consensuar e implementar en un período de tiempo más corto.
Ahora, algunos ejemplos que están dentro del EVM:
El principal compromiso al hacer este tipo de simplificación de características es (i) cuánto simplificamos y qué tan rápido, versus (ii) la compatibilidad con versiones anteriores. El valor de Ethereum como cadena proviene de ser una plataforma en la que puedes implementar una aplicación y estar seguro de que seguirá funcionando muchos años después. Al mismo tiempo, es posible llevar ese ideal demasiado lejos y,parafrasear a William Jennings Bryan«crucificar Ethereum en una cruz de compatibilidad hacia atrás». Si solo hay dos aplicaciones en todo Ethereum que utilizan una determinada función, y una no ha tenido usuarios durante años y la otra se utiliza casi por completo y asegura un valor total de $57, entonces simplemente deberíamos eliminar la función, y si es necesario, pagar a las víctimas $57 de nuestro bolsillo.
El problema social más amplio radica en crear un canalización estandarizada para realizar cambios no urgentes que rompan la compatibilidad hacia atrás. Una forma de abordar esto es examinar y ampliar los precedentes existentes, como el proceso SELFDESTRUCT. La canalización se ve algo así:
Debe haber un canal de varios años entre el paso 1 y el paso 4, con información clara sobre qué elementos se encuentran en cada paso. En ese punto, hay un equilibrio entre cuán vigoroso y rápido es el canal de eliminación de características, en comparación con ser más conservador y asignar más recursos a otras áreas del desarrollo del protocolo, pero aún estamos lejos de la frontera de Pareto.
Un conjunto importante de cambios que se ha propuesto para el EVM es el Formato de Objeto de EVM (EOF). EOF introduce una gran cantidad de cambios, como prohibir la observabilidad del gas, la observabilidad del código (es decir, no CODECOPY), permitiendo solo saltos estáticos. El objetivo es permitir que el EVM se actualice más, de una manera que tenga propiedades más fuertes, al tiempo que se conserva la compatibilidad con versiones anteriores (ya que el EVM anterior a EOF seguirá existiendo).
Esto tiene la ventaja de crear un camino natural para agregar nuevas características de EVM y fomentar la migración a un EVM más restrictivo con garantías más sólidas. Tiene la desventaja de aumentar significativamente la complejidad del protocolo, a menos que podamos encontrar una forma de eventualmente degradar y eliminar el antiguo EVM. Una pregunta importante es: ¿qué papel juega EOF en las propuestas de simplificación de EVM, especialmente si el objetivo es reducir la complejidad del EVM en su conjunto?
Muchas de las propuestas de "mejora" en el resto del plan de trabajo también son oportunidades para simplificar características antiguas. Para repetir algunos ejemplos de arriba:
Una estrategia de simplificación más radical de Ethereum es mantener el protocolo tal como está, pero mover gran parte de sus características de protocolo a ser código de contrato.
La versión más extrema de esto sería hacer que Ethereum L1 "técnicamente" sea solo la cadena de balizas e introducir una VM mínima (por ejemplo, RISC-V, Cairo, o algo aún más minimal especializado para probar sistemas) que permite a cualquier otra persona crear su propio rollup. El EVM se convertiría entonces en el primero de estos rollups. Ironicamente, este es exactamente el mismo resultado que el propuestas de entorno de ejecución de 2019-20, aunque las SNARKs hacen que sea significativamente más viable implementarlo en realidad.
Un enfoque más moderado sería mantener la relación entre la cadena beacon y el entorno de ejecución actual de Ethereum tal como está, pero hacer un intercambio in situ del EVM. Podríamos elegir RISC-V, Cairo u otro VM para que sea el nuevo "VM oficial de Ethereum", y luego forzar la conversión de todos los contratos de EVM en código de nuevo VM que interprete la lógica del código original (compilándolo o interpretándolo). Teóricamente, esto incluso se podría hacer con el "VM de destino" siendo una versión de EOF.