¿Cómo crear ADN aleatorio para un NFT en Solidity?
La aleatoriedad es un componente fundamental en muchos contextos, como en videojuegos y aplicaciones descentralizadas. Sin embargo, en el ámbito de blockchain, la naturaleza determinista de las redes complica la generación de valores realmente aleatorios. Para responder a esta necesidad, se ha desarrollado una técnica para generar un ADN pseudoaleatorio en Solidity, el lenguaje para contratos inteligentes de Ethereum. Aquí te mostramos cómo hacerlo.
¿Qué papel juega la aleatoriedad en blockchain?
La aleatoriedad es esencial para evitar que resultados sean predecibles, algo que contrasta con las necesidades de blockchain, donde la determinación es clave para mantener el consenso en la red. Por ejemplo, en minería, todos los nodos deben coincidir en el resultado de un bloque, que implica predicciones deterministas. Esto crea un desafío cuando se necesita introducir elementos aleatorios.
¿Cómo se resuelve el problema del no determinismo en blockchain?
Proyectos como Chainlink desarrollan oráculos, que son mecanismos para consumir aleatoriedad o datos externos de manera determinista. Estos oráculos procesan datos fuera de la cadena (off-chain) y los introducen en la blockchain con autenticación, asegurando la integridad. Chainlink ofrece soluciones para integrar datos externos, incluso aleatorios, a los smart contracts, todo ello manteniendo los principios de blockchain.
¿Cómo implementar una función pseudoaleatoria en Solidity?
Para simular la aleatoriedad en Solidity, puedes utilizar una función determinista que introduzca ruido en el cálculo del ADN del NFT. A continuación, se muestra cómo crear una tal función:
Variables y Dirección: Se utilizan el tokenId y la dirección (address) del creador del token para generar diversidad. Aunque el tokenId es secuencial, la dirección del usuario genera variabilidad.
Función abi.encodePacked: Convierte datos a un formato bytes, necesario para proceder a hashing.
Función keccak256: Genera un hash del input, que, aunque determinista, complica cualquier intento de revertir al estado inicial sólo a partir del hash. Esta función es estándar en Solidity para obtención de hashes.
Función Tipo pure: Estas funciones no interactúan con la blockchain, sólo procesan entradas y retornan resultados sin costo de gas.
¿Por qué no debe usarse en producción?
Esta función, aunque simula la aleatoriedad, no es completamente segura para proyectos dependientes de datos realmente aleatorios. En aplicaciones productivas, se recomienda usar soluciones de oráculos como Chainlink, quienes poseen infraestructura robusta para asegurar aleatoriedad verdadera.
¿Cómo conectar el ADN con el estándar ERC721?
El siguiente paso sería vincular el ADN generado con los tokens ERC721 para asignar atributos únicos a cada NFT. Esto se puede realizar durante el minteo, y asegurar que cada iteración del proceso produce resultados personalizados basados en los parámetros proporcionados.
La implementación detallada de esta conexión y la atribución de características será desarrollada en posteriores lecciones, permitiéndote seguir explorando el potencial de los contratos inteligentes en blockchain. ¡Adelante, aventúrate en el mundo de los NFTs y el desarrollo blockchain!
OJO, abajo en respuesta a otro comentario el profe indica por qué no se debe utilizar block.timestamp como fuente de "pseudoaleatoridad".
No he terminado esta clase pero, no es posible obtener el momento en el que se ejecuta la funcion? como por ejemplo lo hace la libreria moment.
Sí, existe un objeto global que se llama block, que contiene el timestamp del bloque.
Adicional, puedes usar now, que regresa el mismo timestamp.
No obstante, no es recomendado utilizarlo porque es una vulnerabilidad de timestamp dependance. Recuerda que las funciones se ejecutan en todos y cada uno de los nodos. Cada minero tiene una ventana de tiempo pequeña para manipular el momento en el que se ejecuta.
nota: no he resuelto el reto aún pq son las 3am y hay que implementar varios detalles de herencia y agregar elementos al constructor y al script de deploy xd pero esto es lo que he encontrado xd regresaré más tarde a completarlo
El step by step lo indica Chainlink acá, pero he aquí un resumen:
Paso 1: para resolver el reto tienes que usar la testnet de Goerli y agregar unos tokens de prueba usando faucets para GoerliEth o LINK. Sino tienes habilitado el token de Chainlink puedes hacerlo aquí.
Paso 2: Crear una suscripción en Chainlink que servirá para el cálculo off-chain del número aleatorio. Cuando lo hagas tendrás que confirmar la petición con Metamask y también agregar unos cuantos LINKS de fee, también abrirá Metamask.
Paso 3: En la interfaz para manejar la suscripción tienes que agregar un consumer, que sera la dirección pública de tu contrato desplegado.
Paso 4: tienes que agregar la librería de de chainlink que habilita esto, puedes hacer la prueba en remix después de seguir estos pasos, sólo que antes de hacer el deploy necesitarás el id de tu suscripción y después de eso hacer una llamada a la función requestRandomWords.
Prueba en local: no olvides primero instalar la dependencia de Chainlink
npm i @chainlink/contracts
y luego importar las librerías donde harás las llamadas del número aleatorio, en nuestro caso PlatziPunks.sol
.
.
.
Acá chainlink deja un diagrama de flujo sobre cómo funciona:
Un poco de documentación oficial donde también encontrarán un video tutorial. O acá
Nota
¿Es importante familiarizarnos con los oráculos como Chainlink? Sí. Definitivamente. Esto permitirá darle mucha versatilidad a tus contratos inteligentes, consumir data off-chain lo que puede habilitar ciertas features en nuestros SC, como en este caso números aleatorios. Aunque también puede funcionar para hacer NFTs dinámicos cuya metadata cambie cada intervalo de tiempo.
.
Espero esta info te sirva.
Salu2
Clase complementario:
¿Por qué no se debe utilizar un timestamp o el número de bloque para determinar aleatoriedad?
:( Alguien que me explique porfavor la parte que dice de:
1 byte no es mas que una cadena hexadecimal que es traducible de base16 a base decimal y cabe en un entero de 256
min 8:50
¡Hola Luis Alejandro! 😄
Te comparto la súper clase: Qué son Bits y Bytes con el mismísimo Freddy Vega (la mejor explicación que puedes encontrar en todo internet 😏)
¡Nunca pares de aprender! 💚
No he terminado de ver el video, pero no puede hacerse este calculo de numeros aleatorios en el front con javascript?
Es un poco irónico que lo que le da valor a los nfts no exista en blockchain como tal, ¿existen otras alternativas además de Chainlink?
¿No sé por qué no entiendo nada, que debo estudiar antes de hacer este curso?
no te sientas mal, veras, tal como lo indica este curso, está en la categoría de "Avanzados", o sea se supone que ya sabes programar orientado a objetos en al menos un lenguaje de programación (no necesasriamente solidity). Si te salteaste los tutoriales basicos e intermedios, es normal que no entiendas nada. Saludos y a no desanimarse que vale la pena!