Prueba de Trabajo (Proof-of-work)
Para implementar un servidor de marcas de tiempo distribuido en una base peer-to-peer, necesitaremos usar un sistema de prueba de trabajo similar al Hashcash de Adam Back [6], en lugar de publicaciones en periódicos o Usenet. La prueba de trabajo implica buscar un valor que, al ser hasheado, por ejemplo, con SHA-256, el hash comience con una cantidad de bits cero. El trabajo promedio requerido es exponencial en el número de bits cero necesarios y puede ser verificado ejecutando un solo hash. Para nuestra red de marcas de tiempo, implementamos la prueba de trabajo incrementando un nonce en el bloque hasta encontrar un valor que haga que el hash del bloque tenga los bits cero requeridos. Una vez que se ha invertido el esfuerzo de la CPU para cumplir con la prueba de trabajo, el bloque no puede ser cambiado sin rehacer el trabajo. A medida que se encadenan bloques posteriores, el trabajo para cambiar el bloque incluiría rehacer todos los bloques posteriores.
Block: Bloque
Prev Hash: Hash del Bloque Anterior
Nonce: Valor Temporal
Tx (Transaction): Transacción
La prueba de trabajo también resuelve el problema de determinar la representación en la toma de decisiones mayoritarias. Si la mayoría se basara en una dirección IP por voto, podría ser subvertida por cualquiera que pueda asignar muchas IPs. La prueba de trabajo es esencialmente un CPU por voto. La decisión mayoritaria está representada por la cadena más larga, que tiene el mayor esfuerzo de prueba de trabajo invertido en ella. Si la mayoría del poder de CPU está controlada por nodos honestos, la cadena honesta crecerá más rápido y superará a cualquier cadena competidora. Para modificar un bloque pasado, un atacante tendría que rehacer la prueba de trabajo del bloque y de todos los bloques posteriores, y luego ponerse al día y superar el trabajo de los nodos honestos. Demostraremos más adelante que la probabilidad de que un atacante más lento se ponga al día disminuye exponencialmente a medida que se añaden bloques subsecuentes.
Para compensar el aumento de la velocidad del hardware y el interés variable en ejecutar nodos a lo largo del tiempo, la dificultad de la prueba de trabajo se determina mediante un promedio móvil que apunta a un número promedio de bloques por hora. Si se generan demasiado rápido, la dificultad aumenta.