-¿Te unes?- ㊜Suscribete!!!

Build Stellar Elite : Construyendo y desplegando un RWA Launchpad en Stellar Testnet


En este artículo muestro paso a paso cómo trabajé sobre el RWA Launchpad del bootcamp, modifiqué su Smart Contract en Soroban para agregar una regla de inversión mínima de 500 unidades del token de pago, escribí las pruebas correspondientes y finalmente desplegué el contrato en Stellar Testnet.
El objetivo era conseguir que una inversión menor a 500 fuera rechazada con un nuevo error llamado AmountTooLow, mientras que una inversión de 500 pudiera ejecutarse correctamente.

El resultado final fue:
Inversión de 100
↓
❌ AmountTooLow
Inversión de 500
↓
✅ Inversión exitosa
Balance RWA
↓
5


1. Objetivo del ejercicio

El punto de partida fue la carpeta dia-3 del repositorio del bootcamp:
https://github.com/Oppia-Software-Labs/rwa-launchpad-bootcamp
La tarea consistía en modificar el contrato para agregar una regla sencilla:
Cada inversión debe ser de al menos 500 unidades del token de pago.

Por lo tanto:
100 → ❌ Rechazada
499 → ❌ Rechazada
500 → ✅ Aceptada
1000 → ✅ Aceptada

Además de modificar el contrato, había que: Crear un test que comprobara que 100 falla.
Comprobar que 500 funciona.
Desplegar el contrato en Stellar Testnet.
Inicializarlo mediante el flujo de administrador.
Agregar el inversionista a la whitelist.
Intentar invertir 100.
Invertir 500.
Consultar el balance.
Verificar la transacción exitosa en Stellar Expert. 


2. ¿Qué es el RWA Launchpad?

El proyecto utilizado en este ejercicio es un RWA Launchpad desarrollado sobre Soroban, la plataforma de Smart Contracts de Stellar.
El contrato se llama: RwaLaunchpad

Su funcionamiento básico es el siguiente:
Administrador
│
├── Inicializa el Launchpad
├── Configura el activo RWA
└── Autoriza inversionistas
│
▼
Inversionista
│
├── Entrega token de pago
│
▼
RWA Launchpad
│
▼
Recibe tokens RWA

El administrador puede crear el activo RWA, administrar la whitelist y realizar operaciones administrativas.
El inversionista utiliza un token de pago basado en SEP-41 y, cuando la inversión es válida, recibe unidades del activo RWA.


3. Configuración utilizada

En esta implementación el contrato fue inicializado con:
Nombre del activo: RWAToken
Precio por unidad: 100
Total supply declarado: 1 000 000
Token de pago: PAY
El precio es importante para entender el resultado de la prueba.
Si:
1 RWA = 100 PAY
entonces una inversión de:
500 PAY
produce:
500 / 100 = 5 RWA
Por eso, después de invertir 500, el balance final esperado era de 5 unidades RWA.

4. Preparando el proyecto
El código utilizado originalmente se encontraba en:

C:\stellar\rwa-launchpad-bootcamp\dia-3

Para trabajar sobre una copia propia se creó el proyecto de trabajo:

C:\stellar\stellar-Launchpad

Este proyecto pertenece al repositorio:

https://github.com/Pericena/Stellar-Build/tree/main/stellar-Launchpad

La idea fue trabajar sobre una copia del contrato del día 3, realizar las modificaciones y utilizar esa versión para las pruebas y el despliegue.


5. Entendiendo el código original

Antes de modificar el contrato fue necesario revisar cómo funcionaba invest.
Una parte importante del contrato era la función:
check_variation_gate
Esta función funcionaba originalmente como un punto de extensión para agregar una regla personalizada.
Antes de nuestra modificación estaba prácticamente vacía:
fn check_variation_gate(env: &Env, investor: &Address) -> Result<(), Error> {
let _ = (env, investor);
Ok(())
}
Es decir, la función siempre devolvía:
Ok(())
No comprobaba el monto de la inversión.
El método invest ya realizaba otras validaciones:
comprobar que el contrato estuviera inicializado;
exigir autenticación del inversionista;
comprobar que el contrato no estuviera pausado;
comprobar que el monto fuera positivo;
comprobar que el inversionista estuviera en la whitelist;
cobrar el token de pago;
acuñar el activo RWA.
Por eso, la modificación se podía concentrar en check_variation_gate.


6. Crear el error AmountTooLow

El primer cambio realizado fue agregar un nuevo error al contrato:
AmountTooLow = 7,
Los errores anteriores utilizaban los códigos del 1 al 6, por lo que el nuevo error quedó identificado con el número 7.
El resultado en Stellar Testnet aparece como:
HostError: Error(Contract, #7)
Ese #7 corresponde específicamente a:
AmountTooLow
No significa que exista un problema con la red, con la cuenta o con la firma. Es un error generado por nuestro propio Smart Contract.

7. Crear la constante de inversión mínima

Para evitar escribir el número 500 directamente en diferentes partes del código, se definió una constante:
const MIN_INVESTMENT: i128 = 500;
De esta manera, el mínimo queda claramente definido dentro del contrato.
La ventaja es que la regla queda expresada de forma más clara:
MIN_INVESTMENT = 500
y no como un número sin contexto.

8. Modificar check_variation_gate
La función necesitaba conocer cuánto quería invertir el usuario.
Originalmente recibía:
env
investor
Ahora también recibe:
payment_amount
La función quedó conceptualmente así:
const MIN_INVESTMENT: i128 = 500;
fn check_variation_gate(
env: &Env,
investor: &Address,
payment_amount: i128,
) -> Result<(), Error> {
let _ = (env, investor);
if payment_amount < Self::MIN_INVESTMENT {
return Err(Error::AmountTooLow);
}
Ok(())
}
La lógica es muy sencilla.
Si:
payment_amount < 500
el contrato devuelve:
AmountTooLow
Si no:
payment_amount >= 500
la ejecución continúa.
Por ejemplo:
100 < 500
es verdadero:
100 → AmountTooLow
Pero:
500 < 500
es falso:
500 → continúa
Por eso el límite es inclusivo: 500 está permitido.

9. Conectar la nueva validación con invest
No basta con crear check_variation_gate.
El método invest tiene que enviarle el monto que el usuario quiere invertir.
La llamada quedó de esta forma:
if let Err(err) = Self::check_variation_gate(
&env,
&investor,
payment_amount
) {
panic_with_error!(&env, err);
}
Esto hace que el flujo sea:
invest()
│
├── obtiene el monto
│
▼
check_variation_gate()
│
├── ¿menor que 500?
│ │
│ ├── Sí → AmountTooLow
│ │
│ └── No → continuar
│
▼
Whitelist
│
▼
Cobro del token
│
▼
Acuñación del RWA
El orden también es importante.
Si alguien intenta invertir 100, la operación falla antes de cobrar el token de pago y antes de acuñar el RWA.

10. Crear el test
Después de modificar el contrato era necesario comprobar que la nueva regla realmente funcionara.
En:
src/test.rs
se creó el test:
test_invest_minimum_payment_amount
El test realiza dos comprobaciones principales.
Primero prepara:
el contrato;
el token de pago;
un inversionista;
saldo inicial de 1 000 unidades;
whitelist del inversionista.
Después intenta invertir:
100
La operación debe fallar con:
AmountTooLow
También se comprueba que:
Balance RWA = 0
y que el token de pago sigue en:
1000
Esto demuestra que los 100 no fueron cobrados.
Después el mismo inversionista intenta:
500
Esta operación debe funcionar.
Como el precio de cada unidad RWA es 100:
500 / 100 = 5
Por lo tanto:
Balance RWA = 5
Balance PAY = 500
Los tests existentes también continuaron funcionando porque utilizaban inversiones de 500 y, por lo tanto, cumplían con la nueva regla.

11. Ejecutar los tests
Con los cambios realizados se ejecutaron los tests del contrato.
El resultado fue:
running 4 tests
test test::test_invest_not_whitelisted ... ok
test test::test_invest ... ok
test test::test_invest_minimum_payment_amount ... ok
test test::test_withdraw ... ok
test result: ok. 4 passed; 0 failed
Esto confirma que:
4 tests
4 correctos
0 errores
La nueva regla no rompió las funcionalidades que ya existían.

12. Preparar las cuentas de Stellar Testnet
Para realizar las pruebas en Testnet se utilizaron dos cuentas:
Admin
alice
y:
Inversionista
bob
Las claves de estas identidades permanecieron en la configuración local de Stellar CLI y no se incluyeron en el repositorio.
Las direcciones utilizadas fueron:
Admin:
GBLCANYC7VQDIVCTWJPUIPY65JNDBXCJARMK3IVLHX76NOHOMS5VUKU4
Inversionista:
GBCCUOT523IM3O3KZKA6MMMQZRUCHNMKSAFFD4DP2TJ3LQS6RCGFDV2M
Las cuentas fueron creadas y financiadas utilizando Friendbot:
stellar keys generate alice --network testnet --fund
stellar keys generate bob --network testnet --fund

13. Crear el token de pago
El bootcamp esperaba utilizar un token de pago proporcionado por el instructor.
Como esa dirección no estaba disponible en este entorno, se creó un activo clásico propio llamado:
PAY
El emisor fue la cuenta alice.
Después se desplegó el Stellar Asset Contract correspondiente.
El contrato del token de pago quedó en:
CBNZONKIEZBZF4CN3TGQHYRUDEOI6MWNHCHDBX2JUVPXFBEKOLG6JUTL
El activo quedó representado como:
PAY:
GBLCANYC7VQDIVCTWJPUIPY65JNDBXCJARMK3IVLHX76NOHOMS5VUKU4
Esto permitió utilizar PAY como token con el que Bob realizaría las inversiones.

14. Crear la trustline del inversionista
Antes de que Bob pueda recibir el token PAY, necesita establecer una trustline.
Se utilizó:
stellar tx new change-trust `
--source bob `
--network testnet `
--line "PAY:GBLCANYC7VQDIVCTWJPUIPY65JNDBXCJARMK3IVLHX76NOHOMS5VUKU4"
Después de esto, Bob puede recibir unidades del token PAY.

15. Entregar tokens de prueba al inversionista
Como Alice es la cuenta emisora, puede acuñar tokens PAY.
Se enviaron 10 000 unidades a Bob mediante:
stellar contract invoke `
--id CBNZONKIEZBZF4CN3TGQHYRUDEOI6MWNHCHDBX2JUVPXFBEKOLG6JUTL `
--source alice `
--network testnet `
--mint `
--to GBCCUOT523IM3O3KZKA6MMMQZRUCHNMKSAFFD4DP2TJ3LQS6RCGFDV2M `
--amount 10000
De esta forma Bob tuvo fondos suficientes para realizar las pruebas del Launchpad.

16. Compilar el Smart Contract
Con el código modificado y los tests funcionando, llegó el momento de compilar el contrato para desplegarlo en Stellar.
Desde:
C:\stellar\stellar-Launchpad
se ejecutó:
stellar contract build
Esto genera el WebAssembly que será utilizado para desplegar el Smart Contract en Stellar Testnet.
El Wasm generado tuvo un tamaño aproximado de 7.8 KB.

17. Desplegar el token de pago
El token PAY se publicó en Testnet mediante:
stellar contract asset deploy `
--asset "PAY:GBLCANYC7VQDIVCTWJPUIPY65JNDBXCJARMK3IVLHX76NOHOMS5VUKU4" `
--source alice `
--network testnet
El contrato resultante fue:
CBNZONKIEZBZF4CN3TGQHYRUDEOI6MWNHCHDBX2JUVPXFBEKOLG6JUTL

18. Desplegar el RWA Launchpad
Después se desplegó el contrato modificado:
stellar contract deploy `
--wasm "<ruta del wasm generado por stellar contract build>" `
--source alice `
--network testnet `
--alias rwa-launchpad
El despliegue produjo las transacciones correspondientes a la publicación del Wasm y la creación de la instancia.
Finalmente obtuvimos nuestro Contract ID:
CB5SEQH4REXIVHLGZ5MW7O7TFRZV5JM4RWIZAOIMDLA2NHFZDOQ55FUS
Este es el contrato que posteriormente utilizamos para realizar las pruebas.
También podemos consultarlo directamente en Stellar Expert:
https://stellar.expert/explorer/testnet/contract/CB5SEQH4REXIVHLGZ5MW7O7TFRZV5JM4RWIZAOIMDLA2NHFZDOQ55FUS

19. Configurar el flujo del administrador
El proyecto ya incluía scripts para facilitar las operaciones:
scripts/admin-tool.sh
scripts/user-tool.sh
El script de administrador se utiliza para preparar el contrato.
Las variables utilizadas fueron:
$env:NETWORK="testnet"
$env:ADMIN_KEY="alice"
$env:CONTRACT_ID="CB5SEQH4REXIVHLGZ5MW7O7TFRZV5JM4RWIZAOIMDLA2NHFZDOQ55FUS"
$env:PAYMENT_TOKEN="CBNZONKIEZBZF4CN3TGQHYRUDEOI6MWNHCHDBX2JUVPXFBEKOLG6JUTL"
$env:INVESTOR="GBCCUOT523IM3O3KZKA6MMMQZRUCHNMKSAFFD4DP2TJ3LQS6RCGFDV2M"
Como los scripts están escritos para Bash, en Windows se ejecutaron utilizando Git Bash:
& "C:\Program Files\Git\bin\bash.exe" scripts/admin-tool.sh

20. Inicializar el contrato
La primera operación del administrador fue:
initialize
Esta operación configura el Launchpad.
En nuestro caso se estableció:
Activo: RWAToken
Precio: 100
Supply: 1 000 000
Token de pago: PAY
Esta operación solo puede ejecutarse una vez.
Si intentamos inicializar nuevamente el contrato, recibiremos:
AlreadyInitialized
Después de la inicialización, el administrador agregó la dirección de Bob a la whitelist.
El resultado fue:
Admin
↓
initialize
↓
set_whitelist
↓
Bob autorizado

21. Primer prueba: invertir 100
Ahora llega la parte más importante del ejercicio.
Bob intenta invertir:
100 PAY
La llamada utilizada fue:
stellar contract invoke `
--id CB5SEQH4REXIVHLGZ5MW7O7TFRZV5JM4RWIZAOIMDLA2NHFZDOQ55FUS `
--source bob `
--network testnet `
--send yes `
--invest `
--investor GBCCUOT523IM3O3KZKA6MMMQZRUCHNMKSAFFD4DP2TJ3LQS6RCGFDV2M `
--payment_amount 100
El resultado fue:
❌ error: transaction simulation failed:
HostError: Error(Contract, #7)
En los logs también se puede observar:
fn_call ... invest ... 100
y:
failing with contract error, 7
Esto demuestra que el Smart Contract recibió una inversión de 100 y respondió con el error número 7:
AmountTooLow

22. ¿Por qué la inversión de 100 no aparece en Stellar Expert?
Este punto es importante para entender cómo funciona la simulación de transacciones.
Aunque utilizamos:
--send yes
la CLI primero realiza una simulación.
En este caso la simulación ejecutó el contrato y descubrió que la inversión de 100 provocaba:
AmountTooLow
Como la simulación falló, la transacción no llegó a ser enviada exitosamente al ledger.
Por eso no existe un hash de una transacción exitosa de 100 para buscar en Stellar Expert.
La evidencia correcta para esta prueba es la salida de la terminal.
Ahí podemos mostrar:
invest(..., 100)
junto con:
Error(Contract, #7)
Esto demuestra que la regla funcionó.

23. Segunda prueba: invertir 500
Después de comprobar que 100 era rechazado, realizamos la prueba del límite exacto:
500 PAY
Esta vez la condición:
payment_amount < 500
es falsa.
Por lo tanto, el contrato permite continuar con el proceso.
La inversión fue confirmada correctamente.
La transacción generada fue:
3b8ea15f82b7065ff2358bda74bfbd24d5032703595ea837810d904d79a4cfe8
Puede verificarse en Stellar Expert:
https://stellar.expert/explorer/testnet/tx/3b8ea15f82b7065ff2358bda74bfbd24d5032703595ea837810d904d79a4cfe8
La transacción ocurrió en el ledger:
4923038
y la llamada registrada fue:
invest(Bob, 500) → 5
Es decir:
500 PAY
↓
RWA Launchpad
↓
5 RWAToken
Además, el evento del token de pago muestra la transferencia de 500 desde Bob hacia el contrato.

24. Consultar el balance
Después de la inversión se consultó el balance de Bob.
El resultado fue:
=== balance ===
"5"
Esto significa que Bob recibió:
5 RWAToken
La operación balance es de solo lectura, por lo que no necesita escribir una nueva transacción en el ledger.
El resultado coincide con el cálculo:
500 PAY / 100 PAY por RWA = 5 RWA

25. Resultado final
Al finalizar todo el proceso conseguimos exactamente el comportamiento solicitado:
RWA LAUNCHPAD
│
▼
Mínimo: 500 PAY
│
┌─────────┴─────────┐
│ │
< 500 >= 500
│ │
▼ ▼
❌ AmountTooLow ✅ Aceptado
│
▼
500 PAY
│
▼
5 RWA
La prueba de 100 demuestra que la nueva regla bloquea inversiones por debajo del mínimo.
La prueba de 500 demuestra que el límite es inclusivo y que una inversión válida continúa normalmente.

26. Archivos modificados
Durante la implementación se trabajó principalmente sobre estos archivos:
ArchivoCambio
src/lib.rsSe agregó AmountTooLow = 7, la constante mínima y la validación en check_variation_gate.
src/test.rsSe agregó el test que rechaza 100 y acepta 500.
scripts/admin-tool.shSe ajustó el formato de los valores i128 utilizados por la CLI.
scripts/user-tool.shSe configuró el flujo de prueba con 100, 500 y consulta de balance.
docs/invest-500-stellar-expert.pngCaptura de la inversión exitosa.
.gitignoreSe mantienen fuera del repositorio archivos generados y datos locales.

27. Evidencias del ejercicio
Para demostrar el resultado final se pueden presentar tres evidencias principales.
1. Inversión de 100
Captura de la terminal mostrando:
invest(..., 100)
y:
Error(Contract, #7)
Esto demuestra el rechazo por AmountTooLow.
2. Inversión de 500
Transacción exitosa en Stellar Expert:
https://stellar.expert/explorer/testnet/tx/3b8ea15f82b7065ff2358bda74bfbd24d5032703595ea837810d904d79a4cfe8
Aquí se puede verificar:
invest(..., 500) → 5
3. Balance
La terminal muestra:
"5"
confirmando que Bob recibió las 5 unidades RWA correspondientes a su inversión.

28. Datos finales del despliegue
Los principales datos del proyecto quedaron así:
Repositorio:
https://github.com/Pericena/Stellar-Build
Directorio local:
C:\stellar\stellar-Launchpad
Contract ID:
CB5SEQH4REXIVHLGZ5MW7O7TFRZV5JM4RWIZAOIMDLA2NHFZDOQ55FUS
Stellar Expert:
https://stellar.expert/explorer/testnet/contract/CB5SEQH4REXIVHLGZ5MW7O7TFRZV5JM4RWIZAOIMDLA2NHFZDOQ55FUS
Transacción de inversión de 500:
https://stellar.expert/explorer/testnet/tx/3b8ea15f82b7065ff2358bda74bfbd24d5032703595ea837810d904d79a4cfe8
Resultado:
100 PAY → ❌ AmountTooLow
500 PAY → ✅ 5 RWAToken

29. Conclusión
Este ejercicio permitió modificar un Smart Contract existente de Soroban y agregar una regla de negocio sencilla pero importante: establecer un monto mínimo para las inversiones.
La modificación se concentró en check_variation_gate, donde ahora se comprueba que:
payment_amount >= 500
Si el monto no cumple la condición, el contrato devuelve:
AmountTooLow
Además de implementar la lógica, se creó una prueba automatizada para comprobar ambos escenarios: una inversión de 100 debe fallar y una de 500 debe funcionar.
Finalmente, el contrato modificado fue desplegado en Stellar Testnet y se comprobó el comportamiento mediante una ejecución real. La inversión de 100 fue rechazada durante la simulación y la inversión de 500 fue confirmada en la red, generando 5 unidades del activo RWA.
De esta manera, el flujo completo quedó demostrado:
Modificar
↓
Probar
↓
Compilar
↓
Desplegar
↓
Inicializar
↓
Whitelist
↓
Invertir 100 → ❌
↓
Invertir 500 → ✅
↓
Consultar balance → 5 RWA
↓
Verificar en Stellar Expert
Crear un nuevo error llamado AmountTooLow.

Comentarios

¿Hay algo que quieras buscar?

Entradas populares de este blog

Problemas Resuelto Recursividad Programación II - Capitulo 1

Droid Jack control sobre los dispositivos Android

Doxing Espionaje y Recopilación de Información

WhatScriptApp: Automatización de Mensajería y Su Impacto

Ciberseguridad en Desarrollo Web: Lo Que Muchos Ignoran

Instalar DoxWeb con Termux

Hackear contraseñas WiFi con Python fácilmente con este sencillo script

Instalar Framework Shellphish

¡Bienvenido!

Sockberus Autentificación de proxys

Comentarios

Ofertas y Descuentos

Curso Esteganografía Hot
Certificado Acceso vitalicio

Curso Exploit: Esteganografía y Encriptación

Domina técnicas de ocultación y cifrado en hacking avanzado. Aprende a esconder información en archivos e imágenes.

Instructor: pericena Duración: 2h/sesión Modalidad: Online Alumnos: 1,240+
$50 USD $40 USD -20%
Curso OSINT Popular
Certificado Acceso vitalicio

Curso OSINT: Inteligencia de Datos Públicos

Aprende a recolectar, analizar y explotar información pública. Descubre cómo rastrear personas y empresas.

Instructor: pericena Duración: 2h/sesión Modalidad: Online Alumnos: 980+
$50 USD $40 USD -20%

Mira este video y descubre la verdad

📌 Tú y las redes sociales

💡 ¿Realmente eres libre en el mundo digital?

Publicada por 🚀 Servicio Técnico "The Seven Codes" en Martes, 5 de diciembre de 2019

Es momento de cuestionarlo todo… ¿Eres realmente libre o solo sigues el juego de las redes sociales?

El arte de la guerra nos enseña a no confiar en la posibilidad de que el enemigo no venga, sino en nuestra propia preparación para recibirlo; no confiar en el azar de que no ataque, sino mejor en que hemos hecho inaccesible nuestra posición. — El arte de la guerra, Sun Tzu

¡Conéctate con la comunidad!

Únete a nuestro chat en vivo para compartir ideas, hacer preguntas y conocer a otros apasionados como tú. 🚀

Blog Populares

Instalar DoxWeb con Termux

Instalar Metasploit-Framework En Android Con Termux

Termux Instalar Ngrok

Hackear contraseñas WiFi con Python fácilmente con este sencillo script

WhatScriptApp: Automatización de Mensajería y Su Impacto

Seguridad Informática

Bienvenido a nuestra sección de Seguridad

Comparte el enlace con tus amigos y ayúdanos a crecer

Seguir Blog