Files
project-afterlife/docs/aftercoin.md
consultoria-as 7dc1d2e0e5
Some checks failed
Deploy / deploy (push) Has been cancelled
docs: add AfterCoin documentation and MetaMask guides
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>
2026-02-26 01:48:24 +00:00

21 KiB

AfterCoin (AFC) - Blockchain Privada para el Casino de Minecraft

Tabla de Contenidos


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:

  1. MetaMask se conecta al nodo Geth via HTTPS (puerto 8443, movil) o HTTP (puerto 8545, escritorio)
  2. 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
  3. El mainframe CC:Tweaked (Computer 7) se comunica con el Bridge API via HTTP dentro de la red Docker interna
  4. 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 Geth
  • Dockerfile -- Imagen basada en ethereum/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() retorna 0 -- 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 direccion
    • burnFrom(address from, uint256 amount) -- Quema tokens de una direccion especifica
    • bridgeTransfer(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 solcjs version 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-secret con 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.svg para 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 pcall como 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)

  1. Abrir MetaMask en el navegador

  2. Ir a Settings (Configuracion) > Networks (Redes) > Add Network (Agregar red)

  3. Rellenar los campos:

    Campo Valor
    Network Name AfterLife
    RPC URL http://play.consultoria-as.com:8545
    Chain ID 8888
    Currency Symbol ETH
  4. MetaMask mostrara una advertencia sobre el chain ID desconocido -- esto es normal para cadenas privadas, proceder de todas formas

  5. Importar la wallet del juego:

    • Menu de cuentas > Import Account (Importar cuenta)
    • Pegar la clave privada obtenida del endpoint /api/wallet/:diskId o de la terminal del generador de tarjetas (Computer 4)
  6. 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)

  1. Abrir la app de MetaMask

  2. Ir al menu hamburguesa > Settings > Networks > Add Network

  3. Rellenar los campos:

    Campo Valor
    Network Name AfterLife
    RPC URL https://play.consultoria-as.com:8443
    Chain ID 8888
    Currency Symbol ETH

    IMPORTANTE: En movil se DEBE usar la URL HTTPS (puerto 8443), no HTTP. MetaMask movil rechaza conexiones HTTP para endpoints RPC.

  4. Importar la wallet del juego:

    • Icono de cuenta > Add account or hardware wallet > Import account
    • Pegar la clave privada
  5. 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:

  1. 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');
    "
    
  2. 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_DESTINO y CANTIDAD con 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 allow para afc-bridge debe aparecer ANTES de la regla deny para $private en 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.