Integrar tokens no fungibles como recompensas dentro de un juego en blockchain es una forma práctica de entender cómo interactúan múltiples contratos inteligentes. A partir de un Tic Tac Toe ya funcional en Solidity, se incorpora un sistema de achievements que premia al jugador que acumule cinco victorias con la emisión automática de un NFT basado en el estándar ERC-721.
¿Cómo verificar que la lógica del contrato funciona correctamente?
Antes de agregar nuevas funcionalidades, es fundamental probar la lógica existente. En la versión anterior del contrato se identificaron dos ajustes importantes [0:25]:
- La condición de comprobación del ganador usaba una comparación de diferencia cuando debía ser de igualdad respecto al valor cero (casilla vacía).
- Al guardar un movimiento en el almacenamiento del contrato, la copia en memoria no se actualizaba, por lo que era necesario traer una versión actualizada después de cada cambio.
Para probar el contrato en Remix, se utilizan dos cuentas con saldo disponible [1:38]. Se ejecuta el deploy, se crea una partida con ambos jugadores y se realizan movimientos alternados hasta que uno gana. La transacción de retorno indica el número de partida (en este caso, cero). Cuando un jugador gana, cualquier movimiento posterior del oponente falla automáticamente porque la partida ya terminó [3:07].
¿Qué herramientas ofrece Remix para depurar contratos?
Si no hay certeza de que el juego funciona bien, Remix permite hacer debug del código [3:38]. Se puede ir paso a paso revisando el valor de las variables, incluyendo la partida almacenada en memoria, para tener visibilidad completa sobre el estado interno del contrato.
¿Qué es un achievement y cómo se implementa con NFTs?
Un achievement es un logro dentro del juego que se otorga cuando se cumple una condición específica [4:00]. En este caso, el logro se emite cuando un jugador gana cinco partidas. Para implementarlo se utilizan:
- Tokens no fungibles (NFTs): objetos únicos identificables por un atributo, generalmente asociados a coleccionables.
- Estándar ERC-721: define la interfaz que debe cumplir un contrato de NFTs en Solidity [4:22].
- OpenZeppelin: librería de contratos ya auditados y confiables que implementan el ERC-721, evitando escribir código desde cero [4:48].
¿Cómo se estructura el contrato de achievement?
El contrato hereda de dos contratos de OpenZeppelin mediante la palabra clave is [5:48]:
solidity
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
La herencia del ERC-721 requiere definir un nombre y un símbolo para el token en el constructor. En este ejemplo se usa "Token Achievement" con el símbolo "TA" [6:30]. El contrato Ownable agrega el modificador onlyOwner, que restringe la emisión de tokens exclusivamente al contrato del Tic Tac Toe [6:00].
La función de emisión utiliza un autoincremental para generar IDs únicos [7:50]:
solidity
function emitir(address destino) public onlyOwner returns (uint256) {
uint256 indice = ultimoIndice;
ultimoIndice++;
_safeMint(destino, indice);
return indice;
}
¿Cómo se conecta el achievement al contrato del juego?
Dentro del contrato del Tic Tac Toe se agregan dos elementos clave [9:18]:
- Un mapping que asocia cada dirección de jugador con su cantidad de partidas ganadas:
mapping(address => uint256) partidasGanadas.
- Una referencia al contrato de achievement, inicializada en el constructor con la dirección del contrato ya desplegado en la red [10:00].
solidity
constructor(address contratoAchievement) {
achievement = Achievement(contratoAchievement);
}
En la función que determina al ganador, se incrementa el contador de victorias y se verifica si alcanzó exactamente cinco [11:08]. Solo en ese momento se llama a la función de emisión:
solidity
partidasGanadas[ganador]++;
if (partidasGanadas[ganador] == 5) {
achievement.emitir(ganador);
}
La condición debe ser exactamente igual a cinco: si tiene cuatro aún no califica, y si tiene seis significa que el NFT ya fue emitido previamente [11:25].
El jugador puede verificar sus NFTs directamente en el contrato de achievement consultando la cantidad de tokens asociados a su dirección. Si quieres practicar más, intenta agregar un logro adicional para el jugador que gane sin completar toda la grilla. Comparte tu solución en los comentarios.