¿Cuándo se puede usar BLOCKHASH de manera segura para un número aleatorio? ¿Cuándo sería inseguro?

He visto formas más complicadas para que un contrato genere un número aleatorio. Pero el propio Ethereum Yellow Paper sugiere una "solución trivial" utilizando el código de operación BLOCKHASH (ver más abajo, la negrita es mía).

Si un contrato solo necesita un par de números aleatorios (no cientos), ¿qué tan seguro sería este método? ¿Qué ejemplos de casos de uso serían satisfactorios con este método? ¿Qué casos de uso son atacables de manera práctica, si se usara este método?

Números al azar. Proporcionar números aleatorios dentro de un sistema determinista es, naturalmente, una tarea imposible. Sin embargo, podemos aproximarnos con números pseudoaleatorios utilizando datos que generalmente no se pueden conocer en el momento de la transacción. Dichos datos pueden incluir el hash del bloque, la marca de tiempo del bloque y la dirección del beneficiario del bloque. Para dificultar que el minero malicioso controle esos valores, se debe usar la operación BLOCKHASH para usar hashes de los 256 bloques anteriores como números pseudoaleatorios. Para una serie de tales números, una solución trivial sería agregar una cantidad constante y modificar el resultado.

Tengo una idea basada en la misma lógica pero un poco más segura ethereum.stackexchange.com/questions/34988/… ¿podrías agregar tu opinión?

Respuestas (1)

Solo para aclarar, la "solución trivial" a la que se hace referencia es sobre cómo producir una serie de números aleatorios a partir de una sola semilla aleatoria.

Como regla general, BLOCKHASH solo se puede usar de manera segura para un número aleatorio si la cantidad total de valor que se basa en la calidad de esa aleatoriedad es menor que lo que gana un minero extrayendo un solo bloque.

Para ver por qué esto es así, podemos imaginar la situación opuesta, donde un valor de quizás millones se basa en la aleatoriedad obtenida de una operación BLOCKHASH (por ejemplo, para seleccionar un ganador de lotería que ganará esa cantidad). Debido a la gran cantidad de dinero en juego, un atacante bien financiado tendría un incentivo financiero para comprar un boleto y luego generar muchos bloques alternativos diferentes (quizás usando millones de instancias de AWS por un período corto pero a un costo sustancial) para la altura del bloque a partir del cual se calculará el dibujo. Cuando se encuentra un bloque con un hash que dará como resultado que el boleto del minero gane, el minero inmediatamente extrae más bloques además de este (para asegurarse de que tenga éxito) y luego lo envía a la red.permitiéndoles garantizarse el premio . Esta operación puede ser muy costosa, pero mientras el premio sea lo suficientemente grande, seguirá siendo un ataque rentable.

Este es un ejemplo extremo, pero la versión aburrida de este ataque en la que un minero extrae ese bloque, verifica si gana y luego descarta la respuesta si no lo hace, aún podría duplicar su total. probabilidades de ganar y sigue siendo una manipulación estadística "injusta", aunque débil. Sin embargo, si tirar el bloque cuesta más de lo que nadie puede esperar ganar, es muy poco probable que alguien realice el ataque , por lo tanto, nuestra regla general.

Es importante tener en cuenta que algunas personas intentan utilizar una combinación de fuentes de aleatoriedad. SOLO IMPORTA EL ÚLTIMO. Cualquier pieza de aleatoriedad, ya sea blockhash o marca de tiempo, que se agregue al final puede romper toda la aleatoriedad del sistema.
Comente la respuesta de Jeff. Cada bloque válido que tira el minero le cuesta 5 eth. Si tiene que tirar 1 000 000 de bloques válidos, le cuesta 5 000 000 eth. Si el premio es 1 000 000, no tiene sentido tirar 5 000 000. Si el premio es 10 000 000, entonces vale.
Esta es la misma regla aplicada repetidamente. Si cada bloque extraído ofrece una "oportunidad" o un "paso", y el minero valora esa "oportunidad" o "paso" en más de 5 BTC, entonces la operación BLOCKHASH no se puede usar para la aplicación (o cualquier otra aplicación donde > 5 oportunidades o pasos de ETH podrían ser parte de una estrategia de manipulación exitosa). Si se necesita un promedio o un total de 1,000,000 de bloques para obtener una recompensa de 10,000,000, entonces hay al menos 10 ETH de valor en cada bloque.
¿La prueba de participación no reduce drásticamente el costo de tirar un bloque para un minero/participante? (básicamente al costo de las tarifas + fracción marginal de interés compuesto para apostar más adelante)
¿Cómo cambia esta respuesta a la luz de mover ethereum de PoW a PoS?
@TjadenHess, si hago uint(keccak256(abi.encodePacked(now, block.coinbase, seed))) % 99; entonces, ¿solo el último parámetro, "semilla" solo se usa para generar un número aleatorio? Gracias :)
El último cronológicamente, quiero decir. Puede pensar abi.encodePacked(...)en una entrada única para su RNG. Entonces, la seguridad está determinada por la cantidad de bits que un atacante puede influir en este valor. En este caso serán bastantes bits, por lo que este esquema es muy inseguro
También tengo curiosidad de cómo PoS influye en esto, con el potencial de penalizar a un minero. @TjadenHess, ¿así que el minero asigna la marca de tiempo del bloque para que sea fácil de manipular? ¿Qué pasa con block.difficulty, se le da esto al minero? Además, ¿no está permitido manipular la marca de tiempo en blockchain y podría descubrirse y el minero podría ser penalizado?