Esta publicación es la segunda de una serie que explica un error que encontré en el cliente go-ethereum (Geth). Si aún no lo entiende, lea el primer artículo (traducción al chino). El error del que trata este artículo está en el descargador de estado del cliente Geth, y se puede usar para engañar al descargador para que no se sincronice correctamente con la red principal. Los atacantes pueden usar este error para establecer trampas para la cadena de bloques de Ethereum y activar arbitrariamente bifurcaciones duras. Cuando desea ejecutar un nodo Ethereum, primero debe sincronizar toda la red, es decir, descargar y calcular todos los datos necesarios para construir el estado de la cadena de bloques en el momento del último bloque. Según las propias necesidades del usuario, el método de sincronización puede ser una compensación entre seguridad y velocidad, por lo que (al momento de escribir este artículo) Geth admite dos modos de sincronización: sincronización completa y sincronización rápida. Como su nombre lo indica, la sincronización completa consiste en ejecutar de forma independiente todo el proceso de sincronización de la cadena de bloques de Ethereum. Esto significa que su nodo Geth descargará y verificará la Prueba de trabajo (PoW) de cada bloque, y además, calculará cada transacción en el bloque, por lo que el nodo puede generar la cadena de bloques localmente El último estado del nodo sin confiar en otros nodos. Este modo es más seguro, pero hay un gran sacrificio en la velocidad. Geth puede tardar días o semanas en sincronizarse por completo. Sin embargo, es posible que algunos usuarios no quieran esperar semanas. Tal vez estén presionados por el tiempo, o tal vez no sientan que el sacrificio valga la pena. Por lo tanto, Geth proporciona un modo: todos los datos de la cadena antes de un bloque reciente (llamado "bloque pivote") se sincronizan con un método más rápido, y solo se sincroniza la cadena de bloques después del bloque pivote. Use el algoritmo totalmente síncrono más lento. En el modo de sincronización rápida, Geth descargará bloques, pero solo seleccionará aleatoriamente algunos bloques para verificar la prueba de trabajo, en lugar de verificar cada bloque; además, ya no ejecutará transacciones por sí mismo, sino desde la red. El árbol de estado se descarga directamente de otros nodos de la red para obtener el estado final de la cadena de bloques. Binance completó la integración de wXRP y abrió depósitos en la red Ethereum: según el anuncio oficial, Binance completó la integración de wXRP y abrió depósitos para wXRP en Ethereum (ERC20). Binance abrirá retiros para wXRP en la red Ethereum (ERC20) en una fecha posterior. [2022/1/17 8:54:49] Por supuesto, Geth no confiará ciegamente en los datos del árbol de estado enviados por otros nodos, porque un nodo malicioso también puede afirmar que una cuenta tiene solo un poco de dinero (pero en realidad tiene un mucho). Para comprender cómo Geth puede saber si los datos que recibe son correctos o no, primero debemos comprender el trie de Merkle-Patricia. Un árbol Merkle Patricia (MPT) es una estructura de datos clave en el cliente Geth, que es una combinación del árbol Merkle y el árbol Patricia. En pocas palabras, Patricia Tree almacena datos en una estructura de árbol basada en el prefijo de los datos. En comparación con otras tecnologías (como la tabla hash, el mapa hash), Patricia Tree en sí es muy adecuado para almacenar datos similares, aunque puede haber un sacrificio en la velocidad. Echemos un vistazo a cómo se almacenan varias palabras que comienzan con r en un árbol de Patricia. A continuación, hablemos del árbol de Merkle. En un árbol de Merkle, cada nodo de hoja es el valor hash de los datos y cada nodo que no es hoja es el valor hash de sus dos nodos secundarios. Si el usuario conoce la raíz de Merkle del árbol de Merkle (es decir, el valor hash superior) y quiere confirmar si ciertos datos están almacenados en el árbol, solo necesita usar una ruta en el árbol, el número de nodos involucrado en este camino es solo proporcional al logaritmo del número de nodos de hoja (no el número de nodos de hoja). Como se muestra en la figura a continuación, suponga que el usuario quiere probar que L2 está almacenado en este árbol, solo necesita proporcionar Hash 0-0 y Hash 1. A continuación, el verificador genera Hash 0-1, Hash 0 y Top Hash, y luego compara Top Hash con su raíz de Merkle esperada. Tether emitió recientemente mil millones de USDT en la red Ethereum: según los datos de Whale Alert, a las 23:39 hora de Beijing el 17 de mayo, Tether emitió recientemente mil millones de USDT en la red Ethereum. El hash adicional es f36e2264e3fc19ba90c2588e27164544cb0d4b79e68bae4661b478fa5fc4f202. [2021/5/18 22:12:37] El árbol Merkle Patricia combina la estructura de almacenamiento basada en prefijos del árbol Patricia con el árbol Merkle para crear una nueva estructura de datos, no solo es compatible con la autenticación criptográfica y mantiene un buen rendimiento en tiempo de ejecución. En un árbol de Merkle Patricia, las claves y los valores son cadenas de bytes arbitrarias. Para obtener el valor de una clave, primero convertimos la clave en una secuencia de caracteres hexadecimales, es decir, convertimos cada byte en dos caracteres hexadecimales. Luego, primero debemos consultar el nodo raíz para el siguiente nodo en función del primer carácter de la secuencia; después de obtener este nodo secundario, luego consultamos el nodo hacia abajo de acuerdo con el segundo carácter, y así sucesivamente hasta que encontremos el último nodo Obtener el último carácter. En el siguiente ejemplo, podemos ver que el árbol de Merkle Patricia en realidad contiene tres nodos diferentes. Los nodos extendidos (también conocidos como nodos cortos en el código base de Geth) están optimizados para almacenar una secuencia de caracteres. En el caso que se muestra en la figura a continuación, el nodo raíz almacena todas las claves que comienzan con a7, por lo que no es necesario usar dos nodos diferentes para representar a y 7. Un nodo de rama (o "nodo completo") contiene punteros a todos los caracteres posibles más una ranura adicional para almacenar el valor del nodo actual. Finalmente, el campo final de clave de un nodo hoja (también conocido como nodo de valor) debe coincidir con el sufijo 1 de la clave que almacena. Tether emitió 200 millones USDT adicionales en la red Ethereum: Jinse Finance informó que los datos de Whale Alert mostraron que a las 02:24 del 16 de diciembre, hora de Beijing, Tether emitió 200 millones USDT adicionales en la red Ethereum, y el hash de emisión adicional fue 86e0b4816d0f9bc78f92409371ea7182b56e363533c5c6cd8ba85ff987e29779. [2020/12/16 15:19:51] Ahora que sabemos cómo funciona un árbol de Merkle Patricia, podemos comenzar a explorar qué es un árbol de estado global. La gran mayoría de los datos de blockchain se almacenan en un árbol de estado global. Si bien puede parecer conveniente concebir el árbol de estado como una entidad única dentro de cada bloque, en la práctica es extremadamente ineficiente replicar el árbol de estado completo para cada bloque porque el estado entre cada árbol de bloque solo tiene matices. Geth adopta un enfoque diferente. Como puede imaginar, Geth mantiene un grupo de nodos MPT. El árbol de estado de cada bloque es solo un subconjunto del grupo completo. Cada vez que se extrae o importa un nuevo bloque, se agregará un nuevo nodo MPT al grupo. Para identificar el nodo raíz en el grupo de nodos, debemos consultar el encabezado del bloque. Cada bloque contiene un campo que apunta a stateRoot, que apunta al nodo raíz del MPT (que almacena los datos de la cuenta ingresados por la dirección de cuenta 2). Esto le permite a Geth consultar la información de la cuenta, como el nonce o el saldo de cualquier dirección, utilizando el algoritmo que describimos anteriormente. Tether imprimió recientemente 60 millones de USDT en Ethereum: los datos de la moneda estable de Tokenview muestran que Tether imprimió 60 millones de USDT en Ethereum a las 16:07 de hoy. [2020/3/19] Tenga en cuenta que si se trata de un contrato, el estado de la cuenta contendrá un campo storageRoot no vacío y un campo codeHash. El campo storageRoot apunta a otro nodo raíz. Sin embargo, el propósito del MPT involucrado en este momento es almacenar los datos del elemento de almacenamiento del contrato; el MPT utilizará la ranura de almacenamiento como clave y los datos originales como valor. Para almacenar el MPT en el disco, Geth eligió usar LevelDB como base de datos. Sin embargo, LevelDB es una base de datos de clave-valor que solo admite el mapeo de cadena a cadena y MPT no es un mapeo de cadena a cadena. Para resolver este problema, Geth escribe cada nodo como un par clave-valor, aplanando así el árbol de estado global: el valor hash del nodo se usa como clave y el nodo serializado se usa como valor. De esta manera, Geth puede consultar el árbol de estado de cualquier bloque, porque el campo stateRoot en el encabezado del bloque es la clave, que se puede usar para buscar el nodo MPT serializado en LevelDB (Nota del traductor: es decir, el nodo raíz de un MPT). Entonces, supongamos que inicia un nodo Geth y se conecta a la red usando el modo de sincronización rápida. Geth descargará rápidamente todos los datos del bloque, pero no realizará ninguna transacción. En poco tiempo, tendrá una cadena de bloques sin información de estado. En este punto, Geth comienza a sincronizarse desde stateRoot del bloque pivote a través del descargador de estado. Noticias | Apartamento de $30 millones en Manhattan a la venta en la cadena pública Ethereum: el primer activo importante de Manhattan en la cadena de bloques es un apartamento de lujo de $30 millones. East Village en Manhattan tiene 12 condominios, cada uno de los cuales está tokenizado en la cadena de bloques Ethereum. El autor de best-sellers Ryan Serhant, quien negoció el trato, dijo a Forbes en una entrevista que a través de la tokenización en blockchain, podemos eliminar la tensión inmanejable del financiamiento bancario tradicional, lo cual es beneficioso tanto para los proyectos como para las partes interesadas. el camino para el desarrollo inmobiliario. [2018/10/5] El descargador de estado solicitará los datos del nodo MPT correspondientes a la clave del nodo MPT del nodo par. Después de recibir el resultado, el descargador de estado realizará un cálculo hash en los datos del nodo y verificará si el valor hash obtenido es el mismo que la clave del nodo. Si son iguales, el descargador de estado sabe que el nodo MPT es correcto y luego envía más solicitudes a cada nodo secundario del nodo MPT. Si se encuentra un nodo de hoja (que contiene un estado de cuenta serializado), el código de la cuenta y el árbol de estado se pondrán en cola para obtenerlos. Tenga en cuenta la diferencia entre el subárbol sincronizado y la entrada original. Si bien ambos descargan fragmentos arbitrarios de datos, si el sincronizador espera sincronizar el árbol original, analiza esos datos en un nodo de árbol y comienza a sincronizar sus elementos secundarios. Por otro lado, si el sincronizador espera sincronizar entradas sin procesar, escribe el bloque de datos en la base de datos y termina. También tenga en cuenta que no es raro que Geth quiera enviar una solicitud al mismo nodo varias veces. Por ejemplo, si dos contratos almacenan los mismos datos, su stateRoot puede ser el mismo y también es posible que dos cuentas tengan el mismo estado de cuenta. En estos casos, Geth no quiere inundar la red con estas solicitudes, por lo que las fusionará. Sin embargo, el sincronizador no combinará el atributo sin procesar de la solicitud. Esto significa que si ya hay una solicitud de elemento original pendiente, pero el sincronizador programa una solicitud de subárbol con el mismo valor hash, este último se fusionará y el resultado final seguirá siendo solo una solicitud de elemento original. Tenga en cuenta que las solicitudes de entrada sin procesar no procesan nodos para sincronizar los nodos secundarios (a diferencia de las solicitudes de subárbol). Esto significa que si de alguna manera podemos causar un conflicto entre la entrada original y el nodo del subárbol, podemos hacer que Geth sincronice un árbol de estado incompleto. Además, Geth no saldrá (informará un error) cuando encuentre un nodo de árbol que no existe localmente, lo que equivale a suponer que si el descargador informa que la sincronización es exitosa, esta situación (datos de estado faltantes locales) no sucederá. . Esto significa que un nodo Geth que carece de un nodo de árbol se comporta de forma muy diferente a otros nodos de árbol totalmente sincronizados. Entonces, ¿cómo provocar un conflicto? Resulta ser muy simple: simplemente implementamos otro contrato con la raíz de estado serializada de un contrato que controlamos, por lo que el hash del código del contrato debe ser el mismo que el hash de raíz de estado (del contrato que controlamos), Esto significa que si el código del contrato se sincroniza primero, el árbol de estado de otro contrato no se descargará por completo. Si alguien explota esta vulnerabilidad para hacer el mal, tomará múltiples pasos y esperará mucho tiempo. Primero, implementamos un contrato (usaremos la laguna para sobrescribir el árbol de estado de este contrato). Este contrato debe tener un stateRoot único, para evitar la sincronización temprana de los nodos MPT relacionados con este stateRoot. Ahora hemos terminado. Cuando los nuevos nodos Geth se unan a la red mediante sincronización rápida, primero solicitarán el contrato Exploit para sincronizar su código y subárbol de estado. Cuando se sincroniza el código del contrato de Exploit, se crea una solicitud de entrada sin formato que se parece exactamente a la solicitud raíz de estado de Discrepancia, pero no se trata como una solicitud de subárbol. Esto significa que el nodo nunca descargará la prueba de estado de discrepancia, por lo que las solicitudes futuras para leer magia devolverán 0 en lugar de 1. Después de que haya transcurrido suficiente tiempo, todo lo que tenemos que hacer es llamar a Hardfork.hardfork (discrepancia). Cada nodo que sincronice correctamente toda la red verá una transacción revertida, mientras que cada nodo Geth que se una a la red mediante sincronización rápida verá una transacción exitosa. Esto dará como resultado dos raíces de estado diferentes para un bloque, lo que significa que podemos activar divisiones de cadena a voluntad. El equipo de Geth resolvió rápidamente el ataque al manejar el error de lectura del árbol en PR #21039 y luego arregló completamente la vulnerabilidad al diferenciar entre la parte del código y la parte del árbol en PR #21080. Esta es una vulnerabilidad muy interesante que permite a un atacante colocar una "bomba" en la red Ethereum y detonarla en cualquier momento, lo que hace que todos los nodos Geth que usan sincronización rápida se bifurquen desde la red principal. Esta trampa explota una lógica extremadamente compleja en el código de sincronización y almacenamiento de datos de Geth, por lo que probablemente pasó desapercibida durante mucho tiempo. Estén atentos al tercer y último artículo de esta serie. En esta publicación, exploraremos los últimos errores en el cliente Geth, sin revelar los detalles. Técnicamente, los nodos de valor en Geth no contienen el sufijo .
Tags:
El 9 de junio llegó un momento histórico.El Salvador votó con una "mayoría absoluta" a favor de aprobar oficialmente el proyecto de ley para hacer de Bitcoin moneda de curso legal en el país.
Esta publicación es la segunda de una serie que explica un error que encontré en el cliente go-ethereum (Geth). Si aún no lo entiende.
Titulares ▌Beijing es el primero en lanzar la función de intercambio mutuo de efectivo y renminbi digital en cajeros automáticos En la actualidad.
El 9 de junio de 2021, el presidente de El Salvador, Nayib Bukele, anunció que el proyecto de ley de Bitcoin del país fue aprobado con una "mayoría absoluta" (62/84).
En 2020, la popularidad de Uniswap v2 no tiene precedentes para los protocolos DeFi.