Introducción: Recientemente, Vitalik y algunos académicos co-publicaron un nuevo documento, mencionando cómo Tornado Cash implementa un esquema contra el lavado de dinero (permitiendo esencialmente al retirante demostrar que su registro de depósito pertenece a un conjunto que no contiene dinero sucio), pero el documento carece de una interpretación detallada de la lógica comercial y los principios de Tornado Cash, dejando a algunos lectores desconcertados.
Vale la pena mencionar que los proyectos de privacidad representados por Tornado son los que realmente utilizan la propiedad de conocimiento cero del algoritmo ZK-SNARK, mientras que la mayoría de los proyectos etiquetados con ZK solo utilizan la concisión de ZK-SNARK. A menudo, las personas confunden la diferencia entre la Prueba de Validez y ZK, y Tornado sirve como un excelente caso para comprender la aplicación de ZK. El autor de este artículo había escrito sobre los principios de Tornado en 2022 para Web3Caff Research, y hoy selecciona y amplía algunas secciones de ese artículo, organizándolo en esta pieza para comprender sistemáticamente Tornado Cash.
Enlace del Artículo Original: https://research.web3caff.com/zh/archives/2663?ref=157
Tornado Cash utiliza un protocolo de mezcla de monedas basado en pruebas de conocimiento cero, con su versión anterior lanzada en 2019 y una nueva versión beta lanzada hacia finales de 2021. La versión anterior de Tornado logró un alto nivel de descentralización, con sus contratos en cadena siendo de código abierto y no controlados por ningún mecanismo de multisig, y su código frontend también siendo de código abierto y respaldado en la red IPFS. Debido a la estructura más simple y comprensible de la versión antigua de Tornado, este artículo se centra en explicarla. La idea principal detrás de Tornado es mezclar un gran número de acciones de depósito y retiro juntas. Después de depositar tokens en Tornado, los depositantes presentan una Prueba de Conocimiento Cero para demostrar que han realizado un depósito y luego retiran a una nueva dirección, rompiendo así el vínculo entre las direcciones de depósito y retiro.
Más específicamente, Tornado actúa como una caja de cristal llena de monedas depositadas por muchas personas. Podemos ver quién depositó las monedas, pero dado que las monedas están altamente homogeneizadas, es difícil rastrear qué moneda fue depositada por quién si alguien desconocido retira una moneda.
(Fuente: rareskills) Este escenario es algo común; por ejemplo, cuando intercambiamos ETH en un pool de Uniswap, no podemos saber de quién estamos obteniendo ETH porque muchos han proporcionado liquidez a Uniswap. Sin embargo, la diferencia es que cada vez que intercambias tokens en Uniswap, necesitas usar otros tokens como costo equivalente, y no puedes transferir fondos 'privadamente' a otra persona; mientras que, con un mezclador, solo necesitas mostrar una prueba de depósito para retirar. Para que las acciones de depósito y retiro aparezcan homogéneas, cada depósito en un pool de Tornado y cada retiro de él se mantiene consistente en cantidad. Por ejemplo, si hay 100 depositantes y 100 retirantes en un pool, aunque sean visibles, parecen no estar vinculados, y la cantidad depositada y retirada por cada uno es la misma.
Esto puede oscurecer la trazabilidad de las transferencias de fondos, ofreciendo una conveniencia natural para anonimizar transacciones. La pregunta clave es: ¿cómo demuestra un retirante que ha realizado un depósito?
La dirección que realiza el retiro no está vinculada a ninguna dirección de depósito, entonces, ¿cómo se puede determinar su elegibilidad para el retiro? El método más directo parece ser que el retirante revele qué registro de depósito es suyo, pero esto revelaría directamente su identidad. Aquí es donde entran en juego las pruebas de conocimiento cero. Al presentar una prueba ZK de que tiene un registro de depósito en el contrato Tornado que aún no se ha retirado, un retiro puede iniciar con éxito un retiro. Las pruebas de conocimiento cero protegen inherentemente la privacidad, revelando solo que la persona ha realizado un depósito en el fondo común, sin revelar a qué depositante corresponde.
Para demostrar "He hecho un depósito en el fondo común de Tornado" se puede traducir como "Mi registro de depósito se puede encontrar en el contrato de Tornado". Si usamos Cn para representar un registro de depósito, el problema es: dado que el conjunto de registros de depósito de Tornado es {C1, C2, ... C100...}, el retirante, Bob, demuestra que usó su clave para generar algo de Cn en los registros de depósito sin revelar qué Cn específico es. Esto implica la propiedad especial de Merkle Proof. Todos los registros de depósito de Tornado se incorporan a un árbol de Merkle construido en la cadena, con estos registros como sus nodos hoja de nivel inferior. El número total de hojas es de aproximadamente 2^20 > 1 millón, la mayoría de las cuales están en un estado en blanco (se les asigna un valor inicial). Cada vez que se produce un nuevo depósito, el contrato registra su valor único, Compromiso, en una hoja, y luego actualiza la raíz del Árbol de Merkle.
Por ejemplo, si el depósito de Bob fue el 10,000º en la historia de Tornado, el valor característico Cn asociado con este depósito se introduciría en el 10,000º nodo hoja del Árbol de Merkle, es decir, C10000 = Cn. El contrato luego calcula automáticamente una nueva Raíz y la actualiza. Para ahorrar recursos computacionales, el contrato de Tornado almacena en caché datos de un lote de nodos cambiados previamente, como Fs1, Fs2 y Fs0 en el diagrama a continuación.
(Fuente: RareSkills)
La prueba de Merkle, por su naturaleza, es concisa y ligera, aprovechando la simplicidad de las estructuras de datos de árbol en procesos de búsqueda/rastreo. Para demostrar externamente que una transacción TD existe en un árbol de Merkle, solo se necesita proporcionar una prueba de Merkle correspondiente a la Raíz, lo cual es bastante sencillo. Si el árbol de Merkle es especialmente grande, con 2^20 hojas en el nivel inferior (es decir, 1 millón de registros de depósitos), una prueba de Merkle solo necesitaría incluir los valores de 21 nodos, lo cual es muy corto.
Para demostrar que una transacción H3 está realmente contenida dentro de un Árbol de Merkle, se debe demostrar que usando H3 y otras partes de datos en el Árbol de Merkle, se puede generar la Raíz, y los datos necesarios para generar la Raíz (incluido Td) constituyen la Prueba de Merkle. Cuando Bob retira, necesita demostrar que su certificado corresponde a un hash de depósito Cn registrado en el Árbol de Merkle en el libro mayor de Tornado. En otras palabras, debe demostrar dos cosas: Cn existe dentro del Árbol de Merkle ficticio en la cadena de Tornado, específicamente construyendo una Prueba de Merkle que contenga Cn; Cn está asociado con el certificado de depósito de Bob.
En el código frontend de la interfaz de usuario de Tornado, muchas funcionalidades están pre-implementadas. Cuando un depositante abre la página web de Tornado Cash y hace clic en el botón de depósito, el código frontend acompañante genera dos números aleatorios, K y r, localmente. Luego calcula el valor de Cn=Hash(K, r) y pasa Cn (referido como el compromiso en el diagrama a continuación) al contrato Tornado, que lo inserta en el Árbol de Merkle registrado por este último. Básicamente, K y r actúan como claves privadas. Son cruciales, y el sistema insta a los usuarios a guardarlos de forma segura. K y r son necesarios nuevamente durante la retirada.
(La opción de encryptedNote permite a los usuarios cifrar el credencial K y r con una clave privada y almacenarla en la cadena de bloques para evitar olvidos) Es importante destacar que todas estas operaciones ocurren fuera de la cadena, lo que significa que el contrato de Tornado y los observadores externos no son conscientes de K y r. Si K y r se filtran, es similar al robo de claves privadas de billetera.
Al recibir un depósito de un usuario y la presentación de Cn=Hash(K, r), el contrato Tornado registra Cn en la capa inferior del Árbol de Merkle como un nuevo nodo hoja, actualizando también el valor de la Raíz. Por lo tanto, Cn está directamente vinculado a la acción de depósito del usuario, permitiendo que los externos sepan qué usuario corresponde a cada Cn, quién ha depositado tokens en el mezclador y los registros de depósito Cn de cada depositante.
Durante el proceso de retiro, el retirante ingresa la credencial/clave privada (los números aleatorios K y r generados durante el depósito) en la página web frontal. El programa en el código frontal de Tornado Cash utiliza K y r, Cn=Hash(K, r), y la Prueba de Merkle correspondiente a Cn como parámetros de entrada para generar una Prueba de Conocimiento Cero. Esto demuestra que Cn existe en el Árbol de Merkle como un registro de depósito, y K y r son las credenciales correspondientes a Cn. Este paso básicamente demuestra: Conozco la clave correspondiente a un registro de depósito en el Árbol de Merkle. Cuando la Prueba de Conocimiento Cero se envía al contrato de Tornado, estos cuatro parámetros están ocultos, protegiendo la privacidad. La generación de la Prueba de Conocimiento Cero implica parámetros adicionales, incluyendo la raíz de Merkle registrada en el contrato de Tornado en el momento del retiro, una dirección de destinatario personalizada A y un identificador nf para evitar ataques de repetición. Estos tres parámetros se publican en la cadena de bloques, lo que no compromete la privacidad.
Un detalle a tener en cuenta es el uso de dos números aleatorios, K y r, para generar Cn en lugar de un solo número aleatorio, lo que proporciona una mayor seguridad contra colisiones. A representa la dirección del destinatario de la retirada, elegida por el retirante. El identificador nf, diseñado para prevenir ataques de repetición, se calcula como nf=Hash(K), donde K es uno de los dos números aleatorios utilizados en el paso de depósito para generar Cn. Esto vincula nf directamente a Cn, estableciendo una correlación uno a uno entre cada Cn y su nf correspondiente. El propósito de prevenir ataques de repetición se debe a la característica de diseño del mezclador, que mantiene desconocida la asociación entre las cantidades retiradas y las hojas específicas del árbol de Merkle (Cn), lo que permite el potencial abuso de retiradas repetidas hasta que el fondo se agote.
El identificador nf funciona de manera similar al nonce asociado con cada dirección Ethereum, evitando repeticiones de transacciones. Cuando se realiza un retiro, se verifica que el nf enviado no haya sido utilizado previamente; si no se ha usado, el retiro es válido y se registra el nf. Cualquier intento de generar un nf no asociado con ningún depósito registrado Cn no logrará producir una Prueba ZK válida, lo que hará que el retiro no tenga éxito.
Si alguien genera aleatoriamente un contrato no fungible (nf) no registrado, ¿funcionaría? Claro que no. Cuando el retirante genera una prueba de conocimiento cero (prueba ZK), debe asegurarse de que nf sea igual al hash (K), donde el número aleatorio K está asociado con el registro de depósito Cn. Esto significa que nf está vinculado a un depósito registrado Cn. Si alguien fabrica un nf arbitrariamente, este nf no coincidirá con ningún registro de depósito, lo que hace imposible generar una prueba ZK válida. En consecuencia, el proceso de retiro no se puede completar con éxito y la operación de retiro fallará. Algunos podrían preguntarse: ¿Es posible proceder sin nf? Dado que el retirante debe presentar una prueba de ZK durante el retiro para demostrar su asociación con un determinado Cn, ¿por qué no verificar si la prueba de ZK correspondiente se ha enviado a la cadena de bloques cada vez que se produce un retiro? Sin embargo, este enfoque es muy costoso porque el contrato de Tornado Cash no almacena permanentemente las pruebas ZK pasadas debido a un importante desperdicio de espacio de almacenamiento. Comparar cada nueva prueba ZK enviada a la cadena de bloques con las pruebas existentes es menos eficiente que establecer un identificador pequeño como nf y almacenarlo permanentemente.
Según el ejemplo de código de la función de retiro, los parámetros necesarios y la lógica empresarial son los siguientes: El usuario envía una Prueba de Conocimiento Cero (ZK Proof) y nf (NullifierHash) = Hash (K), especifica una dirección de destinatario para el retiro, y la ZK Proof oculta los valores de Cn, K y r, lo que hace imposible que los externos determinen la identidad del usuario. El destinatario a menudo utiliza una dirección nueva y limpia, que no revela información personal.
Sin embargo, hay un problema menor: cuando los usuarios retiran fondos para permanecer anónimos, a menudo inician la transacción de retiro desde una dirección recién creada. En este momento, la nueva dirección carece de ETH para pagar las tarifas de gas. Por lo tanto, al iniciar un retiro, la dirección de retiro debe declarar explícitamente a un relevo para pagar la tarifa de gas en su nombre. Posteriormente, el contrato de mezcla deduce una parte del retiro del usuario para compensar al relevo.
En resumen, Tornado Cash puede oscurecer la conexión entre los retirantes y los depositantes. En situaciones con una gran base de usuarios, es como un criminal mezclándose en una multitud en un área concurrida, lo que dificulta que la policía rastree. El proceso de retiro implica el uso de ZK-SNARKs, con la parte del testigo oculto que contiene información crítica sobre el retirante, que es un aspecto clave de todo el mezclador. Actualmente, Tornado parece ser uno de los proyectos de capa de aplicación más ingeniosos relacionados con ZK.
Поділіться
Introducción: Recientemente, Vitalik y algunos académicos co-publicaron un nuevo documento, mencionando cómo Tornado Cash implementa un esquema contra el lavado de dinero (permitiendo esencialmente al retirante demostrar que su registro de depósito pertenece a un conjunto que no contiene dinero sucio), pero el documento carece de una interpretación detallada de la lógica comercial y los principios de Tornado Cash, dejando a algunos lectores desconcertados.
Vale la pena mencionar que los proyectos de privacidad representados por Tornado son los que realmente utilizan la propiedad de conocimiento cero del algoritmo ZK-SNARK, mientras que la mayoría de los proyectos etiquetados con ZK solo utilizan la concisión de ZK-SNARK. A menudo, las personas confunden la diferencia entre la Prueba de Validez y ZK, y Tornado sirve como un excelente caso para comprender la aplicación de ZK. El autor de este artículo había escrito sobre los principios de Tornado en 2022 para Web3Caff Research, y hoy selecciona y amplía algunas secciones de ese artículo, organizándolo en esta pieza para comprender sistemáticamente Tornado Cash.
Enlace del Artículo Original: https://research.web3caff.com/zh/archives/2663?ref=157
Tornado Cash utiliza un protocolo de mezcla de monedas basado en pruebas de conocimiento cero, con su versión anterior lanzada en 2019 y una nueva versión beta lanzada hacia finales de 2021. La versión anterior de Tornado logró un alto nivel de descentralización, con sus contratos en cadena siendo de código abierto y no controlados por ningún mecanismo de multisig, y su código frontend también siendo de código abierto y respaldado en la red IPFS. Debido a la estructura más simple y comprensible de la versión antigua de Tornado, este artículo se centra en explicarla. La idea principal detrás de Tornado es mezclar un gran número de acciones de depósito y retiro juntas. Después de depositar tokens en Tornado, los depositantes presentan una Prueba de Conocimiento Cero para demostrar que han realizado un depósito y luego retiran a una nueva dirección, rompiendo así el vínculo entre las direcciones de depósito y retiro.
Más específicamente, Tornado actúa como una caja de cristal llena de monedas depositadas por muchas personas. Podemos ver quién depositó las monedas, pero dado que las monedas están altamente homogeneizadas, es difícil rastrear qué moneda fue depositada por quién si alguien desconocido retira una moneda.
(Fuente: rareskills) Este escenario es algo común; por ejemplo, cuando intercambiamos ETH en un pool de Uniswap, no podemos saber de quién estamos obteniendo ETH porque muchos han proporcionado liquidez a Uniswap. Sin embargo, la diferencia es que cada vez que intercambias tokens en Uniswap, necesitas usar otros tokens como costo equivalente, y no puedes transferir fondos 'privadamente' a otra persona; mientras que, con un mezclador, solo necesitas mostrar una prueba de depósito para retirar. Para que las acciones de depósito y retiro aparezcan homogéneas, cada depósito en un pool de Tornado y cada retiro de él se mantiene consistente en cantidad. Por ejemplo, si hay 100 depositantes y 100 retirantes en un pool, aunque sean visibles, parecen no estar vinculados, y la cantidad depositada y retirada por cada uno es la misma.
Esto puede oscurecer la trazabilidad de las transferencias de fondos, ofreciendo una conveniencia natural para anonimizar transacciones. La pregunta clave es: ¿cómo demuestra un retirante que ha realizado un depósito?
La dirección que realiza el retiro no está vinculada a ninguna dirección de depósito, entonces, ¿cómo se puede determinar su elegibilidad para el retiro? El método más directo parece ser que el retirante revele qué registro de depósito es suyo, pero esto revelaría directamente su identidad. Aquí es donde entran en juego las pruebas de conocimiento cero. Al presentar una prueba ZK de que tiene un registro de depósito en el contrato Tornado que aún no se ha retirado, un retiro puede iniciar con éxito un retiro. Las pruebas de conocimiento cero protegen inherentemente la privacidad, revelando solo que la persona ha realizado un depósito en el fondo común, sin revelar a qué depositante corresponde.
Para demostrar "He hecho un depósito en el fondo común de Tornado" se puede traducir como "Mi registro de depósito se puede encontrar en el contrato de Tornado". Si usamos Cn para representar un registro de depósito, el problema es: dado que el conjunto de registros de depósito de Tornado es {C1, C2, ... C100...}, el retirante, Bob, demuestra que usó su clave para generar algo de Cn en los registros de depósito sin revelar qué Cn específico es. Esto implica la propiedad especial de Merkle Proof. Todos los registros de depósito de Tornado se incorporan a un árbol de Merkle construido en la cadena, con estos registros como sus nodos hoja de nivel inferior. El número total de hojas es de aproximadamente 2^20 > 1 millón, la mayoría de las cuales están en un estado en blanco (se les asigna un valor inicial). Cada vez que se produce un nuevo depósito, el contrato registra su valor único, Compromiso, en una hoja, y luego actualiza la raíz del Árbol de Merkle.
Por ejemplo, si el depósito de Bob fue el 10,000º en la historia de Tornado, el valor característico Cn asociado con este depósito se introduciría en el 10,000º nodo hoja del Árbol de Merkle, es decir, C10000 = Cn. El contrato luego calcula automáticamente una nueva Raíz y la actualiza. Para ahorrar recursos computacionales, el contrato de Tornado almacena en caché datos de un lote de nodos cambiados previamente, como Fs1, Fs2 y Fs0 en el diagrama a continuación.
(Fuente: RareSkills)
La prueba de Merkle, por su naturaleza, es concisa y ligera, aprovechando la simplicidad de las estructuras de datos de árbol en procesos de búsqueda/rastreo. Para demostrar externamente que una transacción TD existe en un árbol de Merkle, solo se necesita proporcionar una prueba de Merkle correspondiente a la Raíz, lo cual es bastante sencillo. Si el árbol de Merkle es especialmente grande, con 2^20 hojas en el nivel inferior (es decir, 1 millón de registros de depósitos), una prueba de Merkle solo necesitaría incluir los valores de 21 nodos, lo cual es muy corto.
Para demostrar que una transacción H3 está realmente contenida dentro de un Árbol de Merkle, se debe demostrar que usando H3 y otras partes de datos en el Árbol de Merkle, se puede generar la Raíz, y los datos necesarios para generar la Raíz (incluido Td) constituyen la Prueba de Merkle. Cuando Bob retira, necesita demostrar que su certificado corresponde a un hash de depósito Cn registrado en el Árbol de Merkle en el libro mayor de Tornado. En otras palabras, debe demostrar dos cosas: Cn existe dentro del Árbol de Merkle ficticio en la cadena de Tornado, específicamente construyendo una Prueba de Merkle que contenga Cn; Cn está asociado con el certificado de depósito de Bob.
En el código frontend de la interfaz de usuario de Tornado, muchas funcionalidades están pre-implementadas. Cuando un depositante abre la página web de Tornado Cash y hace clic en el botón de depósito, el código frontend acompañante genera dos números aleatorios, K y r, localmente. Luego calcula el valor de Cn=Hash(K, r) y pasa Cn (referido como el compromiso en el diagrama a continuación) al contrato Tornado, que lo inserta en el Árbol de Merkle registrado por este último. Básicamente, K y r actúan como claves privadas. Son cruciales, y el sistema insta a los usuarios a guardarlos de forma segura. K y r son necesarios nuevamente durante la retirada.
(La opción de encryptedNote permite a los usuarios cifrar el credencial K y r con una clave privada y almacenarla en la cadena de bloques para evitar olvidos) Es importante destacar que todas estas operaciones ocurren fuera de la cadena, lo que significa que el contrato de Tornado y los observadores externos no son conscientes de K y r. Si K y r se filtran, es similar al robo de claves privadas de billetera.
Al recibir un depósito de un usuario y la presentación de Cn=Hash(K, r), el contrato Tornado registra Cn en la capa inferior del Árbol de Merkle como un nuevo nodo hoja, actualizando también el valor de la Raíz. Por lo tanto, Cn está directamente vinculado a la acción de depósito del usuario, permitiendo que los externos sepan qué usuario corresponde a cada Cn, quién ha depositado tokens en el mezclador y los registros de depósito Cn de cada depositante.
Durante el proceso de retiro, el retirante ingresa la credencial/clave privada (los números aleatorios K y r generados durante el depósito) en la página web frontal. El programa en el código frontal de Tornado Cash utiliza K y r, Cn=Hash(K, r), y la Prueba de Merkle correspondiente a Cn como parámetros de entrada para generar una Prueba de Conocimiento Cero. Esto demuestra que Cn existe en el Árbol de Merkle como un registro de depósito, y K y r son las credenciales correspondientes a Cn. Este paso básicamente demuestra: Conozco la clave correspondiente a un registro de depósito en el Árbol de Merkle. Cuando la Prueba de Conocimiento Cero se envía al contrato de Tornado, estos cuatro parámetros están ocultos, protegiendo la privacidad. La generación de la Prueba de Conocimiento Cero implica parámetros adicionales, incluyendo la raíz de Merkle registrada en el contrato de Tornado en el momento del retiro, una dirección de destinatario personalizada A y un identificador nf para evitar ataques de repetición. Estos tres parámetros se publican en la cadena de bloques, lo que no compromete la privacidad.
Un detalle a tener en cuenta es el uso de dos números aleatorios, K y r, para generar Cn en lugar de un solo número aleatorio, lo que proporciona una mayor seguridad contra colisiones. A representa la dirección del destinatario de la retirada, elegida por el retirante. El identificador nf, diseñado para prevenir ataques de repetición, se calcula como nf=Hash(K), donde K es uno de los dos números aleatorios utilizados en el paso de depósito para generar Cn. Esto vincula nf directamente a Cn, estableciendo una correlación uno a uno entre cada Cn y su nf correspondiente. El propósito de prevenir ataques de repetición se debe a la característica de diseño del mezclador, que mantiene desconocida la asociación entre las cantidades retiradas y las hojas específicas del árbol de Merkle (Cn), lo que permite el potencial abuso de retiradas repetidas hasta que el fondo se agote.
El identificador nf funciona de manera similar al nonce asociado con cada dirección Ethereum, evitando repeticiones de transacciones. Cuando se realiza un retiro, se verifica que el nf enviado no haya sido utilizado previamente; si no se ha usado, el retiro es válido y se registra el nf. Cualquier intento de generar un nf no asociado con ningún depósito registrado Cn no logrará producir una Prueba ZK válida, lo que hará que el retiro no tenga éxito.
Si alguien genera aleatoriamente un contrato no fungible (nf) no registrado, ¿funcionaría? Claro que no. Cuando el retirante genera una prueba de conocimiento cero (prueba ZK), debe asegurarse de que nf sea igual al hash (K), donde el número aleatorio K está asociado con el registro de depósito Cn. Esto significa que nf está vinculado a un depósito registrado Cn. Si alguien fabrica un nf arbitrariamente, este nf no coincidirá con ningún registro de depósito, lo que hace imposible generar una prueba ZK válida. En consecuencia, el proceso de retiro no se puede completar con éxito y la operación de retiro fallará. Algunos podrían preguntarse: ¿Es posible proceder sin nf? Dado que el retirante debe presentar una prueba de ZK durante el retiro para demostrar su asociación con un determinado Cn, ¿por qué no verificar si la prueba de ZK correspondiente se ha enviado a la cadena de bloques cada vez que se produce un retiro? Sin embargo, este enfoque es muy costoso porque el contrato de Tornado Cash no almacena permanentemente las pruebas ZK pasadas debido a un importante desperdicio de espacio de almacenamiento. Comparar cada nueva prueba ZK enviada a la cadena de bloques con las pruebas existentes es menos eficiente que establecer un identificador pequeño como nf y almacenarlo permanentemente.
Según el ejemplo de código de la función de retiro, los parámetros necesarios y la lógica empresarial son los siguientes: El usuario envía una Prueba de Conocimiento Cero (ZK Proof) y nf (NullifierHash) = Hash (K), especifica una dirección de destinatario para el retiro, y la ZK Proof oculta los valores de Cn, K y r, lo que hace imposible que los externos determinen la identidad del usuario. El destinatario a menudo utiliza una dirección nueva y limpia, que no revela información personal.
Sin embargo, hay un problema menor: cuando los usuarios retiran fondos para permanecer anónimos, a menudo inician la transacción de retiro desde una dirección recién creada. En este momento, la nueva dirección carece de ETH para pagar las tarifas de gas. Por lo tanto, al iniciar un retiro, la dirección de retiro debe declarar explícitamente a un relevo para pagar la tarifa de gas en su nombre. Posteriormente, el contrato de mezcla deduce una parte del retiro del usuario para compensar al relevo.
En resumen, Tornado Cash puede oscurecer la conexión entre los retirantes y los depositantes. En situaciones con una gran base de usuarios, es como un criminal mezclándose en una multitud en un área concurrida, lo que dificulta que la policía rastree. El proceso de retiro implica el uso de ZK-SNARKs, con la parte del testigo oculto que contiene información crítica sobre el retirante, que es un aspecto clave de todo el mezclador. Actualmente, Tornado parece ser uno de los proyectos de capa de aplicación más ingeniosos relacionados con ZK.