Una acuñación en blockchain es un cambio de estado: un contrato inteligente escribe nuevas unidades de un activo en su libro mayor y las asigna a una dirección. A diferencia de la minería, que asegura una cadena de prueba de trabajo mediante trabajo computacional, la acuñación es una ejecución de contrato ordinaria cuyas reglas están fijadas en el código. Este artículo explica el mecanismo, recorre un procedimiento ejecutable de acuñación y verificación contra un endpoint RPC, y muestra cómo comprobar que el suministro total varió exactamente en la cantidad deseada. También cubre los modos de fallo que producen saldos fantasma o emisión ilimitada, y las ventajas y desventajas entre distintos modelos de acuñación.
Alcance y la respuesta directa
En terminología blockchain, acuñar significa crear nuevas unidades de un activo en cadena mediante una llamada a un contrato inteligente en lugar de mediante recompensas de bloque. El contrato actualiza su propio almacenamiento, típicamente un mapeo de saldos y un contador de suministro total, y el cambio se vuelve definitivo una vez que la transacción se incluye en un bloque. Para tokens fungibles, la interfaz canónica es mint(address,uint256) de ERC-20 o una equivalente; para NFT, suele ser una función mint o safeMint que asigna un nuevo ID de token.
Esta guía está escrita para desarrolladores y operadores que necesitan hacer más que leer una definición. Cubre el modelo mental, un procedimiento reproducible que puedes ejecutar contra cualquier cadena compatible con EVM, las invariantes que indican que una acuñación se comportó correctamente y los modos de fallo contra los que conviene diseñar. La selección concreta de endpoints queda fuera del alcance aquí; cuando necesites una recomendación específica de proveedor o red, las respuestas del RPC Assistant son el lugar adecuado para buscar.
- Se asume: familiaridad básica con JSON-RPC, recibos de transacción y codificación ABI.
- Se asume: acceso a un RPC_URL para la cadena objetivo y una clave de prueba con fondos.
- No cubierto: precio del token, datos de mercado o productos físicos de almacenamiento en frío que comparten el nombre.
Acuñación versus minería: dos mecanismos de suministro diferentes
La minería es una actividad de consenso. En cadenas de prueba de trabajo, los mineros gastan energía para proponer bloques y reciben monedas nativas recién emitidas como subsidio. El calendario de emisión es una regla del protocolo, no una función de contrato. La acuñación es una actividad de aplicación: un contrato ejecuta lógica que incrementa el suministro de un token, y esa lógica puede ser cualquier cosa que sus autores hayan escrito, desde una emisión única fija hasta un rol de acuñador con permisos o una stablecoin respaldada por colateral.
La consecuencia práctica es que la acuñación hereda la seguridad del contrato, no solo la seguridad de la cadena. Un ERC-20 correctamente implementado en una red bien asegurada aún puede ser drenado si su función de acuñación carece de control de acceso. Cuando evalúes cualquier acuñación, haz dos preguntas separadas: ¿la transacción se ejecutó según lo previsto? y ¿el contrato tenía permitido hacer esto en absoluto?
El modelo mental: escrituras de almacenamiento detrás de una ABI
Cada acuñación es una transacción que llama a un selector de función con argumentos codificados. La EVM ejecuta el cuerpo de la función, que normalmente realiza cuatro pasos: comprobar la autorización (un rol, un propietario, una firma o un pago), comprobar invariantes (un límite máximo, un tiempo de espera, una regla de uno por dirección), escribir el nuevo saldo y el suministro total, y emitir un evento como Transfer(address(0), recipient, amount) o un evento dedicado Minted.
Dos detalles importan para la verificación. Primero, muchas implementaciones de ERC-20 señalan la acuñación como una transferencia desde la dirección cero, por lo que los indexadores y exploradores de bloques lo mostrarán así. Segundo, el recibo de la transacción te dice si la ejecución tuvo éxito, pero no si la cantidad fue correcta. Debes leer el post-estado tú mismo: llama a totalSupply() y balanceOf(recipient) después de que la transacción se mine y compara con el pre-estado que capturaste.
- Pre-estado: totalSupply y saldo del destinatario antes de la transacción.
- Delta: la diferencia después de que el estado del recibo sea 1.
- Invariante: el delta es igual a la cantidad acuñada prevista, y ningún otro saldo cambió inesperadamente.
Requisitos previos y una configuración de prueba segura
Ejecuta el procedimiento primero en una testnet o en un fork local. Necesitas un endpoint RPC que soporte eth_call, eth_sendRawTransaction y eth_getTransactionReceipt; la mayoría de los endpoints públicos y dedicados lo hacen. Si estás eligiendo entre proveedores para un pipeline de acuñación en producción, compara latencia y profundidad de archivo en lugar de asumir que cualquier endpoint sirve, y consulta las notas sobre infraestructura de nodos dedicada para cargas de trabajo que necesitan un rendimiento constante.
Mantén la clave privada fuera del control de código fuente. Los ejemplos a continuación leen RPC_URL y PRIVATE_KEY del entorno y nunca imprimen la clave. Para la verificación de solo lectura no necesitas ninguna clave, que es la opción más segura por defecto cuando auditas la acuñación de otra persona.
export RPC_URL="https://your-endpoint.example"
export PRIVATE_KEY="0x..."
export TOKEN="0xYourTokenAddress"
export RECIPIENT="0xRecipientAddress"Procedimiento ejecutable: leer estado, acuñar, verificar el recibo
El siguiente script de Python usa solo la biblioteca estándar más eth-account para firmar. Captura el pre-estado, envía una transacción de acuñación, espera el recibo e imprime los deltas del post-estado. Reemplaza el fragmento de ABI si tu contrato usa una firma de acuñación diferente. El script deliberadamente no asume éxito: comprueba status antes de leer los saldos.
import os, json, time, urllib.request
from eth_account import Account
from eth_utils import keccak, to_checksum_address
RPC = os.environ["RPC_URL"]
TOKEN = to_checksum_address(os.environ["TOKEN"])
RECIPIENT = to_checksum_address(os.environ["RECIPIENT"])
AMOUNT = 10**18 # 1 token at 18 decimals
def rpc(method, params):
req = urllib.request.Request(RPC, data=json.dumps({
"jsonrpc": "2.0", "id": 1, "method": method, "params": params
}).encode(), headers={"Content-Type": "application/json"})
return json.load(urllib.request.urlopen(req))["result"]
def call(to, data):
return rpc("eth_call", [{"to": to, "data": data}, "latest"])
SEL_TOTAL = "0x18160ddd" # totalSupply()
SEL_BAL = "0x70a08231" # balanceOf(address)
SEL_MINT = "0x" + keccak(text="mint(address,uint256)")[:4].hex()
def total_supply():
return int(call(TOKEN, SEL_TOTAL), 16)
def balance_of(addr):
return int(call(TOKEN, SEL_BAL + addr[2:].rjust(64, "0")), 16)
pre_supply = total_supply()
pre_bal = balance_of(RECIPIENT)
print("pre", pre_supply, pre_bal)
acct = Account.from_key(os.environ["PRIVATE_KEY"])
nonce = int(rpc("eth_getTransactionCount", [acct.address, "pending"]), 16)
gas_price = int(rpc("eth_gasPrice", []), 16)
data = SEL_MINT + RECIPIENT[2:].rjust(64, "0") + hex(AMOUNT)[2:].rjust(64, "0")
tx = {
"to": TOKEN, "data": data, "value": 0, "chainId": int(rpc("eth_chainId", []), 16),
"nonce": nonce, "gas": 200000, "gasPrice": gas_price
}
signed = acct.sign_transaction(tx)
tx_hash = rpc("eth_sendRawTransaction", [signed.raw_transaction.hex()])
print("sent", tx_hash)
receipt = None
while receipt is None:
receipt = rpc("eth_getTransactionReceipt", [tx_hash])
time.sleep(2)
assert int(receipt["status"], 16) == 1, "mint reverted"
post_supply = total_supply()
post_bal = balance_of(RECIPIENT)
print("post", post_supply, post_bal)
print("supply delta", post_supply - pre_supply)
print("balance delta", post_bal - pre_bal)
assert post_supply - pre_supply == AMOUNT
assert post_bal - pre_bal == AMOUNTResultado de verificación esperado y cómo registrarlo
Una acuñación correcta produce un recibo con status igual a 1, un delta de suministro exactamente igual a la cantidad que codificaste y un delta de saldo del destinatario igual a la misma cantidad. Si el contrato cobra una comisión, refleja un rebase o también acuña para una tesorería, los deltas diferirán de forma predecible; codifica esas expectativas en las aserciones en lugar de relajarlas. Si el estado del recibo es 0, nada cambió y la transacción se revirtió, por lo que ambos deltas deberían ser cero.
Registra los resultados en una tabla para que las ejecuciones repetidas sean comparables. No rellenes números que no hayas observado; la tabla siguiente es una plantilla y los valores deben provenir de tu propia ejecución.
- ID de ejecución | Cadena | Contrato | totalSupply previo | totalSupply posterior | Delta de suministro | Delta del destinatario | Estado del recibo | Número de bloque
- Rellena cada fila a partir de la salida del script y el recibo, luego compara entre ejecuciones para detectar desviaciones.
Procedimiento de diagnóstico con curl
Cuando una acuñación se comporta de forma inesperada, aísla la capa. Primero confirma que el endpoint está sirviendo la cadena que crees comparando eth_chainId con el valor esperado. Luego vuelve a ejecutar la llamada con eth_call en el bloque anterior a la transacción para ver si la función se habría revertido y por qué. Una reversión durante eth_call normalmente incluye una cadena de motivo que el recibo de la transacción minada omite.
La secuencia de curl a continuación comprueba la identidad de la cadena, lee el suministro total y simula una acuñación desde un remitente específico sin difundirla. Usa el número de bloque justo antes de tu transacción para que la simulación refleje el mismo estado.
curl -s -X POST "$RPC_URL" -H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_chainId","params":[]}'
curl -s -X POST "$RPC_URL" -H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":2,"method":"eth_call","params":[{"to":"'"$TOKEN"'","data":"0x18160ddd"},"latest"]}'
curl -s -X POST "$RPC_URL" -H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":3,"method":"eth_call","params":[{"from":"'"$SENDER"'","to":"'"$TOKEN"'","data":"'"$MINT_CALLDATA"'"},"0xBLOCK_HEX"]}'Solución de problemas comunes de acuñación
La mayoría de los problemas de acuñación se engloban en un pequeño conjunto de categorías, y cada una tiene una firma distintiva. Recórrelas en orden, porque un síntoma posterior a menudo enmascara una causa anterior.
- Reversión sin motivo: a menudo una condición de gas insuficiente o un
requiresin mensaje. Aumenta el límite de gas y vuelve a simular coneth_callpara obtener una cadena de motivo. - Permiso o rol insuficiente: el remitente carece de
MINTER_ROLEo equivalente. Comprueba el estado de control de acceso del contrato antes de reintentar. - Límite de suministro excedido: el contrato impone un máximo. Lee el límite y el suministro actual; el delta solicitado puede ser válido pero el total no.
- Problemas de nonce o reemplazo: una transacción pendiente con el mismo nonce bloquea la acuñación. Inspecciona
eth_getTransactionCountcon la etiqueta pending y resuelve primero la transacción atascada. - El indexador muestra un saldo que la cadena no tiene: el indexador puede haber procesado un evento de un bloque reorganizado. Vuelve a leer
balanceOfdirectamente desde el nodo en un bloque finalizado. - Inconsistencia del endpoint: un nodo retrasado devuelve estado obsoleto. Compara dos endpoints o consulta en un número de bloque específico para confirmar.
Modelos de acuñación y sus ventajas y desventajas
No existe un único diseño de acuñación correcto, pero las elecciones tienen consecuencias claras. Un token de suministro fijo acuña una vez en el despliegue y luego desactiva la función, lo que elimina el riesgo de inflación pero también la capacidad de corregir errores. Un token acuñable por el propietario mantiene flexibilidad a costa de confiar en la clave del propietario. Un acuñador basado en roles separa la autoridad de emisión de la administración, lo que es mejor para equipos pero añade una superficie de gestión de claves. La acuñación colateralizada vincula la emisión a una reserva, que es tan fiable como la atestación de que la reserva existe.
Para NFT, la principal división es entre acuñación bajo demanda y acuñación diferida (lazy minting), donde el token se crea solo cuando un comprador lo reclama. La acuñación diferida reduce el gas inicial pero traslada la complejidad a la ruta de reclamo. Sea cual sea el modelo que elijas, el procedimiento de verificación anterior se aplica sin cambios: captura el pre-estado, ejecuta y verifica los deltas.
Limitaciones, riesgos de seguridad y lo que este procedimiento no puede probar
Una transacción de acuñación exitosa prueba que el contrato se ejecutó y que el suministro varió en la cantidad esperada. No prueba que el contrato sea seguro, que el acuñador estuviera autorizado según la política prevista ni que existan reservas fuera de la cadena. Eso requiere una revisión separada: auditorías de control de acceso, procedimientos de custodia de claves y atestaciones de reservas. El fallo clásico es una función de acuñación sin protección o mal protegida que permite a un atacante emitir suministro ilimitado, lo que puede colapsar la economía de un token en una sola transacción.
El procedimiento también depende de que el endpoint devuelva un estado consistente. Un nodo que está por detrás de la cabeza de la cadena puede hacer que una acuñación confirmada parezca pendiente, y un nodo que ha podado estado antiguo no puede responder a consultas históricas de eth_call. Para el monitoreo en producción, usa un endpoint con un comportamiento de finalidad predecible y, cuando sea posible, consulta en etiquetas de bloque finalizadas. Si necesitas ayuda para elegir un endpoint para una red específica, el RPC Assistant cubre preguntas concretas de proveedores y redes, mientras que el directorio de redes enumera las cadenas soportadas.
Próximos pasos: automatizar la verificación y monitorear el suministro
Una vez que una sola acuñación se verifica limpiamente, convierte el procedimiento en una comprobación que se ejecute en cada emisión. Almacena el delta de suministro esperado junto a cada transacción, verifícalo después del recibo y alerta ante cualquier discrepancia. Para acuñaciones de alto volumen, agrupa las lecturas: una eth_call por token por bloque suele ser suficiente, y puedes comparar con la instantánea del bloque anterior para detectar emisiones inesperadas en cualquier parte del sistema.
Si estás construyendo un servicio en torno a la acuñación, revisa las opciones del servicio de API RPC para acceso gestionado y la página de precios de RPC para dimensionar el volumen de solicitudes. Para equipos que ejecutan su propia infraestructura, la guía de alojamiento de nodos cubre el lado operativo, y la guía de endpoints multicadena es útil cuando el mismo pipeline de acuñación debe funcionar en varias cadenas. Cuando estés listo para elegir un endpoint específico en lugar de una metodología, entrega la pregunta al RPC Assistant.