Tokens
š Introducción a los Tokens SEP-41 en Stellar
š¤ ĀæQuĆ© es un Token SEP-41?
El SEP-41 es un estĆ”ndar para tokens fungibles en la red Stellar que utiliza contratos inteligentes Soroban. Pero, ĀæquĆ© significa "fungible"? š¤·āāļø
šŖ Fungibilidad Explicada de Forma Simple
Imagina que tienes billetes de $10 pesos en tu billetera. Cada billete de $10 es intercambiable por cualquier otro billete de $10 - todos tienen el mismo valor y función. Esto es fungibilidad: cada unidad es idéntica e intercambiable con otra del mismo tipo.
Pero aquĆ viene algo sĆŗper importante: Los tokens fungibles tambiĆ©n son divisibles āļø
š¢ Divisibilidad y Unidad MĆnima
Al igual que el dinero fĆsico, los tokens fungibles pueden dividirse en partes mĆ”s pequeƱas, pero siempre hay un lĆmite:
š° Ejemplo con dinero fĆsico:
1 peso se puede dividir en 100 centavos
El centavo es la unidad mĆnima - no puedes tener 0.5 centavos fĆsicos
šŖ Ejemplo con tokens digitales:
1 token puede dividirse segĆŗn sus decimales configurados
Si un token tiene 6 decimales: 1 token = 1,000,000 unidades mĆnimas
Si un token tiene 2 decimales: 1 token = 100 unidades mĆnimas
𧮠Casos prÔcticos:
Bitcoin: 8 decimales ā 1 BTC = 100,000,000 satoshis
USDC: 6 decimales ā 1 USDC = 1,000,000 micro-USDC
Tu token: TĆŗ decides cuĆ”ntos decimales ā flexibilidad total
ā ļø Regla de oro: No puedes tener fracciones de la unidad mĆnima. Si tu token tiene 2 decimales, no puedes enviar 0.001 tokens (necesitarĆas al menos 0.01).
Ejemplos de tokens fungibles:
š° Monedas digitales (como USDC, Bitcoin)
š³ Puntos de recompensa
š® Monedas de videojuegos
š Tokens de inversión
¿Por qué son importantes? Los tokens fungibles son perfectos para crear:
š± Monedas digitales
š¦ Sistemas de pagos
šø Programas de lealtad
š Activos financieros
š§āāļø OpenZeppelin: Tu Escudo de Seguridad
š”ļø ĀæPor quĆ© usar OpenZeppelin?
OpenZeppelin es como tener un equipo de expertos en seguridad trabajando para ti 24/7. Aquà te explico por qué es crucial:
š Contratos Ultra-Seguros:
āļø Batalla-probados: Millones de dólares protegidos en producción
š§Ŗ Testeo exhaustivo: Cada lĆnea de código probada por expertos
š EstĆ”ndar de la industria: Usado por los proyectos mĆ”s grandes
š„ Revisión comunitaria: Miles de desarrolladores revisando el código
š° ĀæSabes cuĆ”nto dinero se ha perdido por contratos inseguros?
š„ +$3 billones USD perdidos en hacks de DeFi desde 2020
šø The DAO Hack (2016): $60 millones robados
šØ Poly Network (2021): $600 millones hackeados
ā ļø Y muchos mĆ”s...
š ļø El Trabajo Pesado Ya EstĆ” Hecho: OpenZeppelin hace el trabajo que tĆŗ no quieres (ni debes) hacer:
š Protección contra reentrancy attacks
š”ļø Validación de permisos y roles
┠Optimización de gas
𧩠Compatibilidad con estÔndares
š§ Patrones de actualización seguros
š¦ Controles de acceso robustos
š§āāļø OpenZeppelin Wizard para Stellar
OpenZeppelin ha creado un wizard (asistente) sĆŗper Ćŗtil para generar tokens SEP-41: š https://wizard.openzeppelin.com/stellar#
š ĀæQuĆ© hace el wizard por ti?
šØ Interfaz visual: Sin necesidad de escribir código desde cero
āļø Configuración simple: Solo selecciona las funciones que necesitas
š Código generado: Listo para usar en minutos
š§ Personalizable: Agrega tus propias funciones despuĆ©s
ā ļø Importante: Limitaciones Actuales
Aunque el wizard es genial para empezar, todavĆa tiene algunos errores š. Por eso, es mejor usar los ejemplos oficiales como referencia:
š https://github.com/OpenZeppelin/stellar-contracts/
Instructivo para poder utilizar el código de OpenZeppelin
Pre-requisitos
Tener instalado Rust.
Tener instalado El cliente Stellar
tener instalado el cliente de GIt
Copiar el repositorio de github de OpenZeppelin en una carpeta previamente seleccionada con la siguiente instrucción.
Con el editor favorito de código abrimos el folder stellar-contracts.
En el directorio raiz abrir el archivo Cargo.toml

Para cada ejemplo, por facilidad vamos a crear una subcarpeta
Ejemplo 1: Un token sencillo
Vamos a crear el token MYT (My token).
MyToken usa la funcionalidad limitada ( capped ) de un token fungible, en esta ocasión la función set_cap, en esta le indicamos cual es el maximo de monedas posibles a generar del token.
En el archivo Cargo.toml del directorio raiz. en members, agregamos

Dentro de la carpeta examples creamos la carpeta "myt"
En el folder myt creamos el archivo Cargo.toml con lo siguiente
En el caso de ser un token fungible es con
En el caso de ser un NFT se pone
Dentro de myt creamos una carpeta llamada src con los siguientes archivos:
contract.rs ( Contrato del token)
lib.rs ( archivo que engancha el contrato y su respectivo test)

Escribimos lo siguiente dentro de lib.rs
Código de contract.rs
Explicación del Contrato MyToken
¿Qué es este contrato?
Este es un token fungible (como una moneda digital) que funciona en la blockchain de Stellar. Piensa en Ć©l como crear tu propia criptomoneda, pero con reglas especĆficas que tĆŗ defines.
Estructura General del Código
1. Importaciones (Las herramientas que necesitamos)
¿Qué significa esto?
soroban_sdk: Es como la "caja de herramientas" bƔsica para crear contratos en Stellarstellar_fungible: Son las funciones pre-construidas para crear tokens (como plantillas ya hechas)capped: Funciones para limitar la cantidad mƔxima de tokens que se pueden crear
2. Definición del Contrato
Explicación simple:
Mytes el nombre de nuestro contrato (puedes cambiarlo por el que quieras)#[contract]le dice a Stellar "esto es un contrato inteligente"Es como crear una "fƔbrica" que va a producir tokens
Partes MƔs Importantes
šļø Constructor (La función que inicializa todo)
¿Qué hace?
Base::set_metadata(...): Define las caracterĆsticas bĆ”sicas del token:2: Decimales (como los centavos de las monedas)
"MyToken": El nombre completo del token"MYT": El sĆmbolo corto (como "USD" para dólares)
set_cap(e, cap): Establece el lĆmite mĆ”ximo de tokens que se pueden crearEjemplo: Si pones
cap = 1000000, nunca se podrÔn crear mÔs de 1 millón de tokens
AnalogĆa: Es como registrar una nueva moneda en el banco central, definiendo su nombre, sĆmbolo y cuĆ”ntas unidades mĆ”ximo pueden existir.
šŖ Función Mint (Crear nuevos tokens)
¿Qué hace?
check_cap(e, amount): Verifica que no se exceda el lĆmite mĆ”ximoBase::mint(...): Crea los tokens y los asigna a una cuenta especĆfica
AnalogĆa: Es como una mĆ”quina impresora de billetes, pero que primero verifica que no imprimas mĆ”s de lo permitido.
š Implementación de FungibleToken (Las funciones estĆ”ndar)
Esta parte implementa todas las funciones que cualquier token debe tener:
Funciones de Consulta (Solo leen información):
total_supply(): ĀæCuĆ”ntos tokens existen en total?balance(): ĀæCuĆ”ntos tokens tiene una cuenta especĆfica?decimals(): ĀæCuĆ”ntos decimales tiene el token?name()ysymbol(): ĀæCómo se llama el token?
Funciones de Transferencia:
transfer(): Enviar tokens de una cuenta a otratransfer_from(): Permitir que alguien mÔs mueva tus tokens (con permiso previo)approve(): Dar permiso a alguien para que use tus tokensallowance(): ¿CuÔntos tokens puede usar alguien en mi nombre?
¿Por qué este diseño es inteligente?
1. Reutilización de código
En lugar de escribir todas las funciones desde cero, usa Base que ya tiene todo implementado y probado.
2. Seguridad con lĆmites
La función check_cap asegura que nunca se puedan crear mÔs tokens de los permitidos.
3. EstƔndar compatible
Al implementar FungibleToken, tu token funciona con todas las aplicaciones que esperan tokens estƔndar.
Compilación del contrato
Nos ubicamos dentro de ../stellar-contracts/examples/myt allĆ en consola ejecutamos:

Despliegue del contrato
Para Linux y Mac el salto de lĆnea de la instrucción es con el carĆ”cter " \ " para Windows con el carĆ”cter " ` "
Nota:Para un millón o cualquier cifra se ponen 2 ceros de mÔs que son los centavos


AcÔ podemos ver que se llama al constuctor del contrato y estamos poniendo que el mÔximo de tokens son 1 millón.
No obstante, a pesar que tenemos como mÔximo 1 millón, no hemos acuñado ninguna moneda.
A continuación vamos a invocar la función mint

Para ver el balance

Si queremos ver el saldo de una forma visual en nuestra billetera š
Primero ejecutamos el siguiente comando
En nuetos caso el alias de cuenta o entidad es developer, mandamos a descansar a Bob o Alice š Esto nos da la llave secreta, esta llave secreta la aƱadimos en nuestra billetera favorita, en nuestro caso la billetera freigther

Una vez importada la billetera importamos el contrato de token

Al aƱadir el contrato del token vemos lo siguiente en nuestra billetera:

ā ļø OJO: Si eres detallista, ves un agujero ENORME de seguridad, cualquiera puede hacer la operación de mint, este ejemplo sólo ha sido con fines ilustrativos š .
Ejemplo 2: Un token sencillo, pero sólo el dueño puede acuñarlo
Lo primero que hacemos es copiar la carpeta myt y la renombramos con el nombre mytsf ( My Token Safe version)
dentro de la carpeta mytsv cambiamos el contenido de name en el archivo Cargo.toml
En la carpeta raiz agregamos en el archivo Cargo.toml dentro de members la carpeta que se acabo de crear
El código en en contract.rs
Explicación del Contrato MyToken con Control de Propietario š
Estructura General del Código
1. Importaciones (Las herramientas que necesitamos)
¿Qué significa esto?
soroban_sdk: Es como la "caja de herramientas" bĆ”sica para crear contratos en Stellarstellar_fungible: Son las funciones pre-construidas para crear tokens (como plantillas ya hechas)capped: Funciones para limitar la cantidad mĆ”xima de tokens que se pueden crearš
symbol_short: Para crear identificadores eficientes de datos en el contrato
2. Definición de Constantes (Los valores que no cambian)
¿Qué es esto?
Es como crear una "etiqueta" que identifica quiƩn es el propietario del contrato
symbol_short!("OWNER"): Es una forma eficiente de almacenar esta información en StellarPiĆ©nsalo como la "llave maestra" del contrato šļø
2. Definición del Contrato
Explicación simple:
MyTSVes el nombre de nuestro contrato (cambió deMytaMyTSV)#[contract]le dice a Stellar "esto es un contrato inteligente"Es como crear una "fÔbrica" que va a producir tokens
Partes MƔs Importantes
šļø Constructor (La función que inicializa todo) - Ā”MEJORADO!
ĀæQuĆ© hace ahora? šÆ
Base::set_metadata(...): Define las caracterĆsticas bĆ”sicas del token:2: Decimales ( como los centavos del peso)"My Token Safe Version": El nombre completo del token (Ā”mĆ”s descriptivo!)"MYTSV": El sĆmbolo corto (que coincide con el nombre del struct)
set_cap(e, cap): Establece el lĆmite mĆ”ximo de tokens que se pueden crearš
e.storage().instance().set(&OWNER, &owner): ”Esta es la parte nueva!Guarda quién es el propietario del contrato en la blockchain
Es como escribir en piedra quiƩn tiene el control del contrato
AnalogĆa: Es como registrar una nueva moneda en el banco central, pero ahora tambiĆ©n registras oficialmente quiĆ©n es el director del banco que puede autorizar la impresión de nuevos billetes. š¦
šØ CAMBIO IMPORTANTE: Control de Propietario
šŖ Función Mint (Crear nuevos tokens) - Ā”AHORA MĆS SEGURA!
ĀæQuĆ© hace ahora? š
š
let owner: Address = e.storage().instance().get(&OWNER)...:Busca quiƩn es el propietario registrado del contrato
š
owner.require_auth(): Ā”ESTA ES LA CLAVE! šVerifica que quien estĆ” llamando la función sea realmente el propietario
Si no es el propietario, la transacción falla automÔticamente
check_cap(e, amount): Verifica que no se exceda el lĆmite mĆ”ximo āBase::mint(...): Solo si todo estĆ” bien, crea los tokens
AnalogĆa: Antes era como una mĆ”quina impresora de billetes que cualquiera podĆa usar. Ahora es como una mĆ”quina que requiere la huella dactilar del director del banco para funcionar. š
ĀæPor quĆ© es una EXCELENTE prĆ”ctica? š
š”ļø Seguridad CrĆtica
Antes: Cualquier persona podĆa crear tokens nuevos
Ahora: Solo el propietario puede crear tokens
š° Control de Inflación
Sin control: Los tokens podrĆan volverse sin valor si cualquiera los crea
Con control: El propietario decide cuƔndo y cuƔntos tokens crear
šÆ Casos de Uso Reales
Token de empresa: Solo el CEO puede autorizar nuevas emisiones
Token de recompensas: Solo el sistema de la app puede crear tokens por logros
Token de comunidad: Solo el comitƩ puede crear tokens para nuevos miembros
āļø Transparencia
Todo el mundo puede ver quiƩn es el propietario
Todas las operaciones de mint quedan registradas en la blockchain
La comunidad puede auditar quiƩn y cuƔndo se crean nuevos tokens
Ejemplo de Ataque Prevenido š«
Escenario peligroso sin control de propietario:
Con control de propietario:
š Implementación de FungibleToken (Las funciones estĆ”ndar)
Esta parte implementa todas las funciones que cualquier token debe tener (sin cambios, pero ahora mƔs seguro porque el mint estƔ protegido):
Funciones de Consulta (Solo leen información):
total_supply(): ĀæCuĆ”ntos tokens existen en total?balance(): ĀæCuĆ”ntos tokens tiene una cuenta especĆfica?decimals(): ĀæCuĆ”ntos decimales tiene el token?name()ysymbol(): ĀæCómo se llama el token?
Funciones de Transferencia:
transfer(): Enviar tokens de una cuenta a otratransfer_from(): Permitir que alguien mÔs mueva tus tokens (con permiso previo)approve(): Dar permiso a alguien para que use tus tokensallowance(): ¿CuÔntos tokens puede usar alguien en mi nombre?
ĀæPor quĆ© este diseƱo es inteligente? š§
1. Reutilización de código
En lugar de escribir todas las funciones desde cero, usa Base que ya tiene todo implementado y probado.
2. Seguridad multinivel š
Nivel 1:
check_capasegura que no se excedan los lĆmitesNivel 2:
require_authasegura que solo el propietario pueda crear tokensNivel 3: Todo queda registrado en la blockchain (inmutable y auditable)
3. EstƔndar compatible
Al implementar FungibleToken, tu token funciona con todas las aplicaciones que esperan tokens estƔndar.
Compilación del contrato
Nos ubicamos dentro de ../stellar-contracts\examples\mytsv allĆ en consola ejecutamos:

Despliegue del contrato
Para Linux y Mac el salto de lĆnea de la instrucción es con el carĆ”cter " \ " para Windows con el carĆ”cter " ` "
Nota:Para un millón o cualquier cifra se ponen 2 ceros de mÔs que son los centavos

Haciendo un mint con una cuenta no valida

Haciendo un mint con una cuenta valida

ā ļø OJO: Si eres detallista, ves que se revela la wallet del owner š, esto lo podemos solucionar, si comparamos la billetera que nos envian si es la misma del owner š, si es la misma ok, si no es la misma mensaje de error. AdemĆ”s de la instruccion de la verificación si la firma digital es del owner owner.require_auth().
Last updated
Was this helpful?

