WEB3DEV Español

Cover image for Aleatoriedad en Solidity
Gabriella Alexandra Martinez Viloria
Gabriella Alexandra Martinez Viloria

Posted on

Aleatoriedad en Solidity

Este artículo es una traducción de Kaan Kaçar, hecha por Gabriella Martínez. Puedes encontrar el artículo original aquí
Sería genial escucharte en nuestro Discord, puedes contarnos tus ideas, comentarios, sugerencias y dejarnos saber lo que necesitas.
Si prefieres puedes escribirnos a @web3dev_es en Twitter.

Image description

En el mundo de las aplicaciones descentralizadas, lograr aleatoriedad es un aspecto crucial para varios casos de uso como los videojuegos, las loterías y las operaciones criptográficas. Sin embargo, generar números realmente aleatorios es una manera determinística y transparente posee retos únicos. En este post, exploraré las diversas formas y las mejores prácticas para lograr la aleatoriedad en Solidity.

Pseudoaleatoriedad vs Aleatoriedad Real

Antes de profundizar en las técnicas para lograr aleatoriedad, es importante entender la diferencia entre pseudoaleatoriedad y aleatoriedad real. Números pseudoaleatorios son generados usando algoritmos determinísticos, comenzando con un valor semilla. Dado la misma semilla, la secuencia de números generados, siempre serán los mismos. Por su otra parte, la aleatoriedad real confía en la impredecibilidad y los recursos imparciales de la entropía, asegurándose que los números generados sean realmente azarosos e independientes de cualquier estado anterior.

Retos para Lograr Aleatoriedad

Solidity es un lenguaje de programación determinístico, esto quiere decir que la ejecución del contrato inteligente siempre debe producir el mismo output, dado el mismo input. Lograr aleatoriedad con este entorno determinístico es un reto por la falta de acceso a datos externos, la falta de habilidad para confiar en los timestamps y la necesidad de transparencia y auditabilidad.

Generando Aleatoriedad con Blockhash

Una de las formas simples para introducir aleatoriedad en Solidity es usando la función blockhash. La función `blockhash regresa el hash de un bloque específico en Ethereum. Sin embargo, hay limitaciones para su uso. Sólo puede accederse al hash de los 256 bloques más recientes. Más aún, los mineros pueden manipular el timestamp del bloque dentro de cierto rango, potencialmente afectado el número azaroso generado. Por lo tanto, no es recomendado confiar únicamente en blockhash para aplicaciones críticas.

Para generar números aleatorios usando blockhash, puedes implementar una función como esta:

function generateRandomNumber(uint256 seed) public view returns (uint256) {
uint256 blockNumber = block.number - 1; // Usa el hash del bloque anterior
bytes32 blockHash = blockhash(blockNumber);
return uint256(blockHash) % seed;
}

Utilizar Chainlink VRF (Verifiable Random Function, Verificación de Función Aleatoria)

Para sobreponerse a las limitaciones de blockhash, servicios de oráculos externos pueden ser aprovechados para lograr aleatoriedad real. Chainlink VRF es una solución grandemente usada que posiblemente provee números aleatorios generados por oráculos.

Integrando Chainlink VRF en tu contrato inteligente conlleva los siguientes pasos:

  1. Importa la biblioteca de Solidity Chainlink VRF a tu contrato inteligente. Asegúrate de tener los interfaces del contrato necesarios y las variables del contrato en lugar.

  2. Pedir Aleatoriedad: Invoca la función requestRandomness proveída por Chainlink VRF para pedir un número aleatorio. Esta función requiere una cantidad de tokens LINK como pago por el servicio oráculo. También toma el valor de la semilla y la función callback que será llamada cuando la respuesta aleatoria es recibida.

  3. Recibe Aleatoriedad: La función callback especificada en el pedido es desencadenada cuando la respuesta aleatoria se recibe. Esta función debería manejar el valor aleatorio apropiado recibido dentro de la lógica de tu aplicación.

  4. Verifica la Aleatoriedad: Para asegurarte que la aleatoriedad generada por Chainlink VRF sea legítima, incluye un paso de verificación. Chainlink provee una función fulfillRandomness que verifica la autenticidad del número azaroso recibido, comparándolo con el valor de la semilla.

Para más: https://docs.chain.link/getting-started/intermediates-tutorial

Aleatoriedad desde un Oráculo Externo

Aparte de Chainlink VRF, otros servicios oráculos externos pueden ser usados para lograr la aleatoriedad. Estos servicios proveen interfaces APIs o de contratos inteligentes que exponen capacidades de generar números aleatorios.

Planes Commit-Reveal

Los Planes Commit-Reveal son otra forma de lograr la aleatoriedad en Solidity. El proceso envuelve dos fases: el commitment y la revelación (revelation).

En la fase del commitment, los participantes entregan versiones hash de sus opciones aleatorias. Mantienen los números aleatorios originales secretos hasta que sucede la fase de revelación. El commitment puede ser logrado usando el algoritmo de hash keccak256.

function commit(uint256 randomNumber) public {
bytes32 commitment = keccak256(abi.encodePacked(randomNumber));
// Almacena el commitment para verificarlo luego
// ...
}

En la fase de revelación, los participantes revelan sus números aleatorios originales, los cuales son combinados o procesados para derivar el output azaroso final. Los participantes pueden entregar su valores revelados usando la función reveal:

`
function reveal(uint256 randomNumber) public {
// Retira el commitment y verifica el valor revelado
bytes32 commitment = getCommitment(msg.sender);
require(keccak256(abi.encodePacked(randomNumber)) == commitment, "Invalid commitment");
// Procesa los números revelados para derivar el output azaroso final
// ...
}
`

Los planes Commit-Reveal proveen equidad y previenen que los participantes influyan en el resultado, basado en los valores revelados. Sin embargo, la efectividad de los planes dependen de la coordinación y comportamiento de los participantes.

Aleatoriedad para Contratos Externos

Otro método para lograr aleatoriedad conlleva usar contratos externos, diseñados específicamente para generar números azarosos. Estos contratos se aprovechan de varias técnicas como oráculos, operaciones criptográficas y fuentes de datos externos verificables, para generar números azarosos.

Por ejemplo: https://github.com/axiomzen/eth-random o https://fravoll.github.io/solidity-patterns/randomness.html

Conclusión

En esta guía, exploré las diferentes técnicas para lograr la aleatoriedad, incluyendo utilizar blockhash, integrar Chainlink VRF, depender de oráculos externos, implementar planes commit-reveal y tener interfaces con contratos externos. Cada técnica tiene sus propias ventajas y consideraciones, así que es importante elegir la apropiada que mejor encaje tu caso de uso específico mientras consideras factores como: seguridad, fiabilidad, transparencia y descentralización.

Acuérdate, lograr aleatoriedad en un entorno determinístico es una tarea compleja y de contínua investigación donde es necesario probar y auditar. Es mucho trabajo, así que deberías reconsiderar tu proyecto de juegos con apuestas…

Si encontraste que este artículo fue informativo y te ayudó, por favor considera seguirme para más contenido relacionado a la blockchain y criptomoneda. Puedes también suscribirte a mi lista de email para recibir actualizaciones en mis últimos artículos y proyectos.

Discussion (0)