Imagine que desea conservar y controlar los cambios en un archivo, por ejemplo, un registro de transacciones. Además, imagine que desea verificar un historial ininterrumpido de todos los cambios realizados en el archivo. ¿Cómo lo haces?
Una solución bien entendida para verificar un archivo utiliza funciones hash criptográficas.
La función hash criptográfica ideal tiene cinco propiedades principales:
- Es determinista, por lo que el mismo mensaje siempre da como resultado el mismo hash.
- Es rápido calcular el valor hash para cualquier mensaje dado.
- No es factible generar un mensaje a partir de su valor hash excepto probando todos los mensajes posibles.
- Un pequeño cambio en un mensaje debería cambiar el valor de hash de forma tan amplia que el nuevo valor de hash parezca no estar interrelacionado con el valor de hash anterior.
- No es factible encontrar dos mensajes diferentes con el mismo valor hash.
Tenga en cuenta que existen diferentes algoritmos hash que apuntan a resultados similares a los descritos anteriormente. También observe que a medida que escribe en el cuadro de texto, el hash se actualiza e incluso un cambio minúsculo en la entrada crea un hash completamente diferente. Finalmente, tenga en cuenta que cada algoritmo produce hashes del mismo tamaño de manera constante, independientemente del tamaño de la entrada.
Se puede usar un hash para probar que una entrada coincide exactamente con el original, pero el original no se puede reconstruir a partir de un hash.
Este proceso simple a veces se usa para confirmar la integridad de un archivo grande, como una actualización de software. Una fuente autorizada, como el sitio web de un editor, presentará un hash del archivo legítimo. Con ese hash, los usuarios pueden confirmar que un archivo recibido coincide exactamente con el contenido original. Simplemente procesan ellos mismos el archivo que tienen y comparan el resultado con el resultado esperado.
¿Cómo puede ampliar esta idea para confirmar un historial de transacciones ininterrumpido?
Puede comenzar con la primera versión de un archivo y registrar un hash del contenido del archivo. Esto puede ser tan simple como un registro vacío sin transacciones porque todavía no ha pasado nada. Además, puede suponer que tendrá una regla: solo puede agregar nuevas entradas al final del archivo. Es decir, el historial de transacciones será una estructura de solo agregar. Los contadores han conocido las ventajas de los libros mayores solo para agregar durante siglos.
Los siguientes ejemplos están escritos en pseudocódigo:
versión1Hash = hash(versión1)
En este ejemplo, version1 es el registro inicializado vacío.
¿Cómo puede agregar nuevas transacciones y mostrar un historial ininterrumpido de cambios?
Puede crear una regla que establezca que, además del nuevo contenido, el hash anterior también será una entrada para el próximo hash.
version2Hash = hash(version2Changes + version1Hash)
De esta forma, puede examinar los cambios candidatos y confirmar que el archivo anterior es correcto y que los cambios posteriores se revelan con precisión. Este proceso se repite para todas las versiones posteriores.
version3hash = hash(version3Changes + version2Hash)
En caso de que no quede claro, version3Hash depende de version2Hash y version1Hash. Por lo tanto, si dos partes calculan por separado versiones2Hashes idénticas, sabrán que comparten registros de transacciones idénticos desde el principio.
Si dos nodos están de acuerdo con la versión2Hash y admiten el mismo conjunto de transacciones propuestas en la versión3, definitivamente calcularán la misma versión3Hash.
Cualquier versión del contenido del archivo puede mostrarse como parte de una cadena ininterrumpida de cambios, desde el inicio del archivo. Esto es matemática pura. Cualquier desviación del sistema, como un hash que no se calcula como se esperaba, demuestra una interrupción en el historial y, por lo tanto, no es válido.
Dado que el conocimiento del hash actual de la última versión válida es una entrada para la función hash de la siguiente versión, no es posible generar una nueva versión válida sin conocer la versión válida que la precede. Este proceso obliga a que los cambios se agreguen a una versión anterior válida.
Blockchain funciona de manera similar. Los bloques de transacciones se agregan utilizando hashes de bloques anteriores como entradas en hashes de bloques posteriores. Cualquier participante puede verificar rápidamente una cadena ininterrumpida de bloques (en el orden correcto).
El pedido de transacciones es sorprendentemente desafiante en un sistema de cadena de bloques debido a los objetivos y restricciones del diseño.
- Como red distribuida, todos tienen un poco de autoridad. Por ejemplo, todos los nodos pueden generar transacciones y luego anunciar esa información a otros nodos.
- En una red verdaderamente distribuida, el reloj de nadie se considera más autorizado que el reloj de los demás. Por lo tanto, la red necesita una solución de pedido de transacciones que no involucre marcas de tiempo o tiempo de red.
- Cualquiera puede escuchar propuestas de transacciones y organizar un bloque válido que contenga una opinión sobre el orden correcto de los eventos.
- Debido a la física y la latencia de la red, todos en la red conocerán las propuestas de transacción en un orden ligeramente diferente.
¿Cómo se puede determinar el orden correcto de las transacciones?
Incluso si asume que todos los miembros de la red tienen buenas intenciones y participan honestamente, seguramente llegarán a opiniones algo diferentes sobre el orden correcto de las transacciones y no hay una manera obvia de resolver el asunto.
El orden de las transacciones debe resolverse porque el procesamiento de las transacciones fuera de orden produce diferencias no triviales en los resultados. Sin acuerdo sobre el orden de la transacción, no puede haber acuerdo sobre los resultados.
Bitcoin utiliza un proceso llamado Proof-of-Work que puede considerarse como una lotería.
El afortunado ganador gana el privilegio de tener autoridad para un bloque de transacciones. El boleto de lotería ganador, llamado nonce, se usa como otra entrada para la función hash. Esto es fácilmente verificado por otros participantes.
La opinión del ganador de la lotería sobre el orden de las transacciones dentro del bloque se convierte en el resultado oficial de facto de la red.
Un bloque válido es un conjunto de transacciones bien ordenado, contiene el hash del bloque anterior y contiene un «billete de lotería ganador» (nonce). Otros participantes reconocen esta combinación improbable (improbable debido al boleto de lotería ganador) y aceptan el bloqueo como una opinión correcta de facto sobre el orden de las transacciones. Este proceso elimina la ambigüedad del orden de las transacciones a pesar de que los nodos bien intencionados llegan de forma independiente a opiniones ligeramente diferentes sobre el asunto.
Las funciones hash criptográficas son fundamentales porque permiten a todos los participantes asegurarse de que poseen un historial no distorsionado de todo. Dado que todos los nodos pueden verificar la cadena de forma independiente, pueden proceder asumiendo que todos los demás nodos eventualmente llegarán a un acuerdo sobre la historia de todo. Esto se conoce como consenso eventual.
Una cadena de bloques comienza con un estado conocido. Una cadena de bloques procede mediante la construcción de un historial verificable y ampliamente aceptado de todo lo que ha sucedido. Los nodos construyen de forma independiente un estado actual del universo al revisar el historial ordenado de cada cambio (las transacciones) que ha ocurrido alguna vez. La historia de todo lo que ha ocurrido avanza en el tiempo a medida que los «ganadores de la lotería» anuncian nuevos bloques de transacciones y son aceptados como válidos por consenso de los participantes de la red.
Pingback:Gobernanza de contratos inteligentes - GREEN
Pingback:DeFi y las pruebas criptográficas - GREEN