Generación de números aleatorios en Solidity con Chainlink
Clase 11 de 15 • Curso de Programación de Smart Contracts con Solidity
Resumen
¿Cómo se generan números aleatorios en Solidity con Chainlink?
En Solidity, generar números aleatorios no es una tarea sencilla debido a la ausencia de un reloj interno que garantice una verdadera aleatoriedad. Sin embargo, a través del uso de fuentes externas, es posible obtener números confiables. Aquí es donde Chainlink, un reputado oráculo, juega un papel crucial. Veamos los pasos esenciales y el enfoque adoptado para implementar esta funcionalidad en un contrato de Tic-Tac-Toe.
¿Qué es Chainlink y cómo se integra a los contratos?
Chainlink es uno de los oráculos más conocidos en el ecosistema blockchain. Su función principal es proporcionar datos del mundo real a contratos inteligentes a través de una red descentralizada. En este contexto, se utiliza para obtener números aleatorios que se emplearán en el contrato de Tic-Tac-Toe, en particular para decidir cuál de los dos jugadores comenzará la partida.
Pasos para integrar Chainlink:
-
Importación de contratos externos:
- Coordinador: Este contrato ya existente en la red es el encargado de generar el número aleatorio. Su dirección es necesaria y se puede consultar en la documentación de Chainlink.
- Consumer Base: Ofrece la estructura necesaria mediante herencia para consumir números aleatorios.
-
Configuración de la red: Se trabajará sobre la testnet de Sepolia utilizando el modelo de suscripción de Chainlink para los números aleatorios.
¿Cómo se realiza la solicitud de un número aleatorio?
Para solicitar un número aleatorio, se debe seguir una serie de pasos específicos:
-
Definición de parámetros en el constructor: Se almacena la dirección del coordinador y un ID de suscripción que se utilizará para las solicitudes.
-
Solicitud al contrato coordinador: En la creación de una partida de Tic-Tac-Toe, se dispara una solicitud utilizando la función
Request Random Words
del contrato Consumer Base. Se definen varios parámetros cruciales:- KeyHash: Dependiente de la red, este hash debe actualizarse según la red en uso.
- ID de suscripción: Guardado en el constructor.
- Cantidad de confirmaciones: Más confirmaciones ofrecen mayor confianza en la aleatoriedad. Tres es un número coherente y el valor por defecto.
- Límite de gas: 100,000 es un valor razonable.
- Cantidad de números aleatorios: En este caso, se necesita solo uno.
-
Asignación del Request ID: Se guarda el Request ID asociado a la solicitud en una estructura de datos separada para facilitar la identificación de la respuesta.
¿Cómo se gestiona la respuesta del número aleatorio?
Una vez realizada la solicitud, se espera la respuesta:
-
Estructura de la respuesta: Se utiliza un mapping para enlazar el Request ID con el ID de la partida. Esto permite asignar el jugador inicial de cada partida dependiendo del número aleatorio recibido.
-
Determinación del jugador inicial: Se utiliza un simple truco: evaluar si el número aleatorio es par o impar para decidir el turno del jugador.
-
Restricciones de juego: Se limita que un jugador pueda hacer un movimiento antes de recibir un número aleatorio gestionando adecuadamente el estado de las partidas.
Ejemplo de implementación en código
function requestRandomness() external {
RequestID = COORDINATOR.requestRandomWords(
keyHash,
subscriptionId,
3, // Confirmaciones
100000, // Límite de gas
1 // Cantidad de números aleatorios
);
requests[RequestID] = gameID;
}
function fulfillRandomWords(uint requestId, uint[] memory randomWords) internal override {
uint gameId = requests[requestId];
if (randomWords[0] % 2 == 0) {
games[gameId].lastTurn = games[gameId].player1;
} else {
games[gameId].lastTurn = games[gameId].player2;
}
delete requests[requestId];
}
Esta implementación demuestra cómo usar Chainlink para obtener y utilizar números aleatorios en Solidity. Este enfoque no solo mejora la funcionalidad del contrato de Tic-Tac-Toe, sino que también ofrece una lección valiosa sobre la importancia de los oráculos en la blockchain.