Comprehensive docs covering architecture, all components, Docker services, environment variables, MetaMask connection (desktop + mobile), administration commands, and troubleshooting. Also adds Lua scripts to repo for version control, including the periodic chain sync loop (every 30s) in the mainframe. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
21 KiB
AfterCoin (AFC) - Blockchain Privada para el Casino de Minecraft
Tabla de Contenidos
- Resumen General
- Arquitectura
- Componentes
- Servicios Docker
- Variables de Entorno
- Guia de Conexion con MetaMask
- Administracion
- Detalles del Contrato
- Solucion de Problemas
Resumen General
AfterCoin (AFC) es un token ERC-20 desplegado en una blockchain privada de Ethereum que utiliza el mecanismo de consenso Clique PoA (Proof of Authority) con chain ID 8888.
Principios fundamentales:
- 1 AFC = 1 diamante en el casino de Minecraft
- 0 decimales (solo valores enteros, sin fracciones)
- Los jugadores pueden ver su saldo del casino en MetaMask como tokens reales en la blockchain
- El mainframe del casino sincroniza los saldos on-chain a traves de un Bridge API
Esto permite que los jugadores tengan una experiencia tangible de sus fondos del casino: pueden abrir MetaMask en su telefono o navegador y ver exactamente cuantos diamantes tienen, con la seguridad y transparencia de una blockchain real.
Arquitectura
+---------------------+ +-----------------------------+
| | HTTPS | |
| MetaMask |--------->| Nginx SSL Proxy |
| (Escritorio/Movil) | :8443 | (rpc-ssl) |
| | +-------------+---------------+
+--------+------------+ |
| | HTTP :8545
| HTTP :8545 v
| (solo escritorio) +--------+---------------+
+--------------------------->| |
| Geth Node |
| (Clique PoA, ID 8888) |
| |
+--------+---------------+
^
| ethers.js (HTTP RPC)
|
+--------+---------------+
| |
| Bridge API |
| (Node.js, :3001) |
| |
| +------------------+ |
| | SQLite DB | |
| | (wallets, config)| |
| +------------------+ |
+--------+---------------+
^
| HTTP (red Docker interna)
|
+----------------+------------------+
| |
| CC:Tweaked Mainframe |
| (Computer 7, Minecraft) |
| |
+---+----------+----------+---------+
| | |
rednet rednet rednet
| | |
+---+--+ +---+---+ +---+---+
| Slots| | BJ | | Poker |
+------+ +-------+ +-------+
(Juegos del casino)
Flujo de datos:
- MetaMask se conecta al nodo Geth via HTTPS (puerto 8443, movil) o HTTP (puerto 8545, escritorio)
- El Bridge API (puerto 3001) se comunica con Geth mediante ethers.js y mantiene una base de datos SQLite con las wallets de los jugadores
- El mainframe CC:Tweaked (Computer 7) se comunica con el Bridge API via HTTP dentro de la red Docker interna
- El mainframe se comunica con los juegos del casino (slots, blackjack, poker, etc.) via rednet (protocolo de red inalambrica de CC:Tweaked)
Componentes
1. Nodo Geth (blockchain/)
El nodo Geth ejecuta la blockchain privada donde vive el token AfterCoin.
| Parametro | Valor |
|---|---|
| Consenso | Clique PoA (Proof of Authority) |
| Chain ID | 8888 |
| Tiempo de bloque | 5 segundos |
| Version de Geth | v1.13.15 (ultima version con soporte para Clique PoA) |
| Limite de memoria | 1 GB |
| Puerto HTTP RPC | 8545 |
| Puerto WebSocket | 8546 |
Archivos clave:
genesis.json-- Configuracion genesis de la cadena (Clique PoA, chain ID 8888, periodo de bloque de 5s)init-geth.sh-- Script de inicializacion que importa la cuenta admin y arranca GethDockerfile-- Imagen basada enethereum/client-go:v1.13.15
Wallet de administrador: Actua como sellador (sealer) de bloques y propietario (owner) del contrato inteligente. Es la unica autoridad en la cadena PoA.
2. Contrato AfterCoin (blockchain/contracts/AfterCoin.sol)
Contrato inteligente ERC-20 autocontenido (sin dependencias de OpenZeppelin).
Caracteristicas principales:
decimals()retorna0-- los tokens son enteros, 1 token = 1 diamante- Funciones restringidas al owner (wallet admin):
mint(address to, uint256 amount)-- Crea nuevos tokens y los asigna a una direccionburnFrom(address from, uint256 amount)-- Quema tokens de una direccion especificabridgeTransfer(address from, address to, uint256 amount)-- Transfiere tokens entre wallets via el bridge
- Cumple con el estandar ERC-20 completo (transfer, approve, transferFrom, allowance, etc.)
Compilacion:
- Compilado con
solcjsversion 0.8.34 - Target: Paris EVM -- No usa el opcode
PUSH0(introducido en Shanghai EVM), ya que Geth v1.13 no lo soporta en cadenas privadas - El contrato se despliega automaticamente por el Bridge API en el primer arranque
3. Bridge API (services/afc-bridge/)
Servicio backend que actua como puente entre el mundo de Minecraft y la blockchain.
Stack tecnologico: Node.js + Express + ethers.js v6 + better-sqlite3
Funcionalidades clave:
- Auto-despliegue del contrato: En el primer arranque, si no existe un contrato desplegado, lo despliega automaticamente y guarda la direccion en la base de datos SQLite
- Cola de nonces: Sistema de cola para transacciones que previene colisiones cuando multiples operaciones ocurren simultaneamente
Endpoints:
| Metodo | Ruta | Descripcion | Autenticacion |
|---|---|---|---|
| POST | /api/register |
Crea una wallet custodial para un jugador | x-bridge-secret |
| POST | /api/deposit |
Acuna (mint) AFC a la wallet del jugador | x-bridge-secret |
| POST | /api/withdraw |
Quema (burn) AFC de la wallet del jugador | x-bridge-secret |
| GET | /api/balance/:diskId |
Lee el saldo on-chain del jugador | Ninguna |
| GET | /api/wallet/:diskId |
Retorna direccion de wallet + clave privada para importar en MetaMask | Ninguna |
Seguridad:
- Los endpoints POST requieren el header
x-bridge-secretcon el secreto configurado en las variables de entorno - Los endpoints GET son publicos para facilitar la consulta de saldos y datos de wallet
Archivo estatico:
- Sirve el icono del token en
/afc-icon.svgpara que MetaMask pueda mostrar el logo del token
4. Proxy SSL para RPC (docker/nginx/rpc-ssl.conf)
Proxy inverso Nginx que proporciona acceso HTTPS al nodo Geth.
| Parametro | Valor |
|---|---|
| Puerto externo | 8443 (HTTPS) |
| Puerto interno | 8545 (HTTP hacia Geth) |
| Certificado | Let's Encrypt via Cloudflare DNS challenge |
Por que es necesario: MetaMask en dispositivos moviles rechaza conexiones HTTP para endpoints RPC. El proxy SSL permite que los jugadores conecten sus wallets desde el telefono usando HTTPS.
5. Mainframe Lua (Computer 7)
El mainframe es el computador central del casino dentro de Minecraft (CC:Tweaked). Coordina todos los juegos y gestiona los saldos de los jugadores.
Funciones principales:
| Funcion | Descripcion |
|---|---|
addPlayer(diskId, name) |
Registra una nueva wallet en el bridge para el jugador |
getPlayerBalance(diskId) |
Sincroniza el saldo desde la blockchain (detecta transferencias hechas desde MetaMask) |
setPlayerBalance(diskId, amount) |
Calcula la diferencia con el saldo actual y ejecuta mint o burn segun corresponda |
Caracteristicas tecnicas:
- Helpers HTTP con
pcallcomo fallback para manejar errores de red - Bucle de sincronizacion periodica cada 30 segundos usando
parallel.waitForAll - Los juegos del casino (slots, blackjack, poker) no necesitan modificaciones -- se comunican con el mainframe via rednet y este se encarga de toda la logica blockchain
6. Generador de Tarjetas Lua (Computer 4)
Computador auxiliar que genera las tarjetas de jugador del casino.
Despues de crear una tarjeta, muestra en pantalla:
- La direccion de wallet del jugador
- Instrucciones para conectar MetaMask y ver el saldo de AFC
Servicios Docker
| Servicio | Puertos | depends_on | Volumenes | Limite de Memoria |
|---|---|---|---|---|
geth |
8545:8545, 8546:8546 | -- | geth_data:/root/.ethereum |
1 GB |
afc-bridge |
3001:3001 | geth |
afc_bridge_data:/app/data |
-- |
rpc-ssl |
8443:8443 | geth |
certbot_etc:/etc/letsencrypt:ro |
-- |
Todos los servicios forman parte de la red Docker compartida con el servidor de Minecraft, permitiendo comunicacion interna por nombre de servicio (ej: http://afc-bridge:3001).
Variables de Entorno
Todas las variables relacionadas con AfterCoin usan el prefijo AFC_ y se definen en el archivo .env del directorio docker/.
| Variable | Descripcion | Ejemplo |
|---|---|---|
AFC_ADMIN_PRIVATE_KEY |
Clave privada de la wallet administradora (sellador + owner del contrato) | 0xabc123... |
AFC_ADMIN_ADDRESS |
Direccion publica de la wallet administradora | 0x742d35Cc... |
AFC_BRIDGE_SECRET |
Secreto compartido entre el mainframe y el Bridge API | mi-secreto-seguro |
AFC_CHAIN_ID |
ID de la cadena (debe coincidir con genesis.json) | 8888 |
AFC_RPC_URL |
URL interna del nodo Geth (dentro de Docker) | http://geth:8545 |
AFC_CONTRACT_ADDRESS |
Direccion del contrato desplegado (se genera automaticamente en el primer arranque) | 0x5458...918C |
Guia de Conexion con MetaMask
Escritorio (Extension)
-
Abrir MetaMask en el navegador
-
Ir a Settings (Configuracion) > Networks (Redes) > Add Network (Agregar red)
-
Rellenar los campos:
Campo Valor Network Name AfterLifeRPC URL http://play.consultoria-as.com:8545Chain ID 8888Currency Symbol ETH -
MetaMask mostrara una advertencia sobre el chain ID desconocido -- esto es normal para cadenas privadas, proceder de todas formas
-
Importar la wallet del juego:
- Menu de cuentas > Import Account (Importar cuenta)
- Pegar la clave privada obtenida del endpoint
/api/wallet/:diskIdo de la terminal del generador de tarjetas (Computer 4)
-
Agregar el token AFC:
- Click en Import Tokens (Importar tokens) > Custom Token (Token personalizado)
- Pegar la direccion del contrato:
0x54583A08C29556d16BA626cbA66101816D79918C - Simbolo:
AFC - Decimales:
0
Movil (App)
-
Abrir la app de MetaMask
-
Ir al menu hamburguesa > Settings > Networks > Add Network
-
Rellenar los campos:
Campo Valor Network Name AfterLifeRPC URL https://play.consultoria-as.com:8443Chain ID 8888Currency Symbol ETHIMPORTANTE: En movil se DEBE usar la URL HTTPS (puerto 8443), no HTTP. MetaMask movil rechaza conexiones HTTP para endpoints RPC.
-
Importar la wallet del juego:
- Icono de cuenta > Add account or hardware wallet > Import account
- Pegar la clave privada
-
Agregar el token AFC:
- En la pantalla principal, hacer scroll hacia abajo
- Import Tokens > Custom Token
- Pegar la direccion del contrato:
0x54583A08C29556d16BA626cbA66101816D79918C
Vincular una Wallet Personal
Por defecto, el bridge crea wallets custodiales para cada jugador (el bridge genera y almacena las claves privadas). Si un jugador quiere vincular su propia wallet de MetaMask:
-
Actualizar la direccion en la base de datos del bridge:
docker exec docker-afc-bridge-1 node -e " const db = require('./src/db'); db.db.prepare('UPDATE wallets SET address = ? WHERE disk_id = ?').run('0xDIRECCION_DEL_JUGADOR', 'DISK_ID'); " -
Acunar (mint) el saldo actual del jugador a la nueva direccion para sincronizar:
curl -s localhost:3001/api/deposit \ -H "Content-Type: application/json" \ -H "x-bridge-secret: TU_SECRETO" \ -d '{"diskId":"DISK_ID","amount":SALDO_ACTUAL}'
Nota: Al vincular una wallet personal, el jugador tendra control total sobre sus tokens y podra transferirlos libremente. Esto puede tener implicaciones en la economia del casino.
Administracion
Comandos de Verificacion
# Verificar el chain ID (debe retornar 0x22b8 = 8888)
curl -s -X POST localhost:8545 \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}'
# Registrar un jugador de prueba
curl -s localhost:3001/api/register \
-H "Content-Type: application/json" \
-H "x-bridge-secret: SECRET" \
-d '{"diskId":"99","name":"Test"}'
# Depositar 50 AFC (= 50 diamantes) al jugador
curl -s localhost:3001/api/deposit \
-H "Content-Type: application/json" \
-H "x-bridge-secret: SECRET" \
-d '{"diskId":"99","amount":50}'
# Consultar saldo de un jugador
curl -s localhost:3001/api/balance/99
# Obtener informacion de wallet (direccion + clave privada)
curl -s localhost:3001/api/wallet/99
# Listar todas las wallets registradas
docker exec docker-afc-bridge-1 node -e \
"const db=require('./src/db');db.getAllWallets().forEach(w=>console.log(w.disk_id,w.name,w.address))"
Operaciones Directas con Tokens
Para operaciones que requieren interaccion directa con el contrato inteligente (sin pasar por el Bridge API):
# Acunar tokens directamente a cualquier direccion
cd /tmp && node -e "
const {ethers}=require('ethers');
const artifact=require('/home/AfterlifeProject/services/afc-bridge/contracts/AfterCoin.json');
async function main(){
const provider=new ethers.JsonRpcProvider('http://localhost:8545');
const admin=new ethers.Wallet('ADMIN_PRIVATE_KEY',provider);
const contract=new ethers.Contract('CONTRACT_ADDRESS',artifact.abi,admin);
await (await contract.mint('DIRECCION_DESTINO',CANTIDAD)).wait();
console.log('Saldo:',Number(await contract.balanceOf('DIRECCION_DESTINO')));
}
main();
"
Nota: Reemplazar
ADMIN_PRIVATE_KEY,CONTRACT_ADDRESS,DIRECCION_DESTINOyCANTIDADcon los valores reales.
Renovacion de Certificado SSL
El certificado de Let's Encrypt expira cada 90 dias. Para renovarlo:
# Renovar el certificado
docker run --rm \
-v docker_certbot_etc:/etc/letsencrypt \
-v /tmp/certbot/cloudflare.ini:/run/secrets/cloudflare.ini:ro \
certbot/dns-cloudflare:latest renew
# Reiniciar el proxy SSL para cargar el nuevo certificado
docker compose -f docker-compose.dev.yml restart rpc-ssl
Whitelist HTTP de CC:Tweaked
La regla de whitelist en computercraft-server.toml (dentro del volumen de datos de Minecraft) permite que el mainframe se comunique con el Bridge API. Si Minecraft se reinstala, la regla se pierde y debe recrearse:
# Agregar la regla de whitelist para afc-bridge
docker exec minecraft-ftb sed -i '/\$private/i \\t[[http.rules]]\n\t\t host = "afc-bridge"\n\t\t action = "allow"\n' /data/config/computercraft-server.toml
# Reiniciar el servidor de Minecraft para aplicar cambios
docker restart minecraft-ftb
IMPORTANTE: La regla
allowparaafc-bridgedebe aparecer ANTES de la regladenypara$privateen el archivo de configuracion. De lo contrario, la conexion sera bloqueada por la regla de denegacion general.
Despliegue de Scripts Lua
Para actualizar los scripts de los computadores CC:Tweaked dentro de Minecraft:
# Copiar el script del mainframe (Computer 7)
docker cp /tmp/mainframe_startup.lua minecraft-ftb:/data/world/computercraft/computer/7/startup.lua
# Copiar el script del generador de tarjetas (Computer 4)
docker cp /tmp/cardgen_startup.lua minecraft-ftb:/data/world/computercraft/computer/4/startup.lua
Luego, reiniciar los computadores dentro del juego presionando Ctrl+R en cada terminal.
Detalles del Contrato
| Campo | Valor |
|---|---|
| Direccion | 0x54583A08C29556d16BA626cbA66101816D79918C |
| ABI | services/afc-bridge/contracts/AfterCoin.json |
| Codigo fuente | blockchain/contracts/AfterCoin.sol |
| Compilador | solcjs 0.8.34 |
| Target EVM | Paris (sin opcode PUSH0) |
| Desplegado en | Primer arranque del Bridge API |
| Almacenamiento de direccion | Base de datos SQLite del Bridge API |
Solucion de Problemas
"invalid opcode: PUSH0"
Causa: El contrato fue compilado para Shanghai EVM pero la cadena ejecuta Paris EVM. El opcode PUSH0 fue introducido en Shanghai y no esta disponible en Geth v1.13 para cadenas privadas.
Solucion: Recompilar el contrato con la opcion --evm-version paris:
solcjs --bin --abi --evm-version paris AfterCoin.sol
Geth termina por OOM (Out of Memory)
Causa: El nodo Geth supera el limite de memoria asignado (actualmente 1 GB).
Solucion: Incrementar el limite de memoria en el docker-compose. La flag --lightkdf ya esta habilitada para reducir el uso de memoria durante la importacion de claves.
Bridge no puede conectar con Geth
Causa: El nodo Geth aun no ha terminado de inicializar cuando el bridge intenta conectarse.
Solucion: Verificar que depends_on esta configurado correctamente en docker-compose. El bridge incluye logica de reintentos (waitForGeth()) que espera a que Geth este disponible antes de continuar.
CC:Tweaked bloquea peticiones HTTP
Causa: El archivo computercraft-server.toml no tiene la regla de whitelist para afc-bridge, o la regla esta ubicada despues de la regla de denegacion $private.
Solucion: Verificar que la regla allow para afc-bridge existe y esta posicionada antes de la regla deny para $private. Ver la seccion Whitelist HTTP de CC:Tweaked para los comandos de correccion.
MetaMask movil no puede conectar
Causa: Se esta usando la URL HTTP (puerto 8545) en lugar de HTTPS (puerto 8443). MetaMask en dispositivos moviles requiere conexiones HTTPS para endpoints RPC.
Solucion: Cambiar la URL de la red en MetaMask a https://play.consultoria-as.com:8443.
Transacciones fallan con "nonce too low"
Causa: Multiples transacciones se enviaron simultaneamente y los nonces colisionaron.
Solucion: El Bridge API incluye una cola de nonces que deberia prevenir esto. Si ocurre, reiniciar el servicio del bridge:
docker compose -f docker-compose.dev.yml restart afc-bridge
El saldo en MetaMask no coincide con el casino
Causa: El jugador realizo una transferencia desde MetaMask que aun no ha sido sincronizada por el mainframe.
Solucion: El mainframe ejecuta un bucle de sincronizacion cada 30 segundos. Esperar a que se complete el siguiente ciclo, o forzar la sincronizacion reiniciando el Computer 7 con Ctrl+R en el juego.