Saltearse al contenido

Tu Primer Módulo Move

La blockchain de Aptos permite a los desarrolladores escribir smart contracts Turing complete (llamados “módulos”) con el lenguaje Move, que es seguro por diseño. Los smart contracts permiten a los usuarios enviar dinero a través de la blockchain, pero también escribir código arbitrario, ¡incluso juegos! Todo comienza con la CLI de Aptos creando una cuenta que almacenará el módulo Move al que se le hizo deploy (“publicado”).

Este tutorial te ayudará a entender los Módulos Move guiándote a través de la configuración de un entorno mínimo de Aptos, y luego cómo compilar, testear, publicar e interactuar con módulos Move en la Blockchain de Aptos. Aprenderás a:

  1. Configurar tu entorno e instalar la CLI
  2. Crear una cuenta en devnet y fondearla
  3. Compilar y testear un módulo Move
  4. Publicar (o “hacer deploy”) un módulo Move en la blockchain de Aptos
  5. Interactuar con el módulo
  6. Seguir construyendo con Aptos (siguientes pasos)

Los cambios en la blockchain se llaman “transacciones”, y requieren una cuenta para pagar el network fee (“gas fee”). Necesitaremos crear una cuenta con algo de APT para pagar ese fee y ser dueños del contrato publicado. Para hacer esto, necesitaremos usar la CLI de Aptos.

  1. Instalar la CLI de Aptos

    Instala la CLI de Aptos (si aún no lo has hecho).

  2. Abrir una nueva terminal

    Abre una nueva ventana o pestaña de terminal.

  3. Verificar la instalación

    Ejecuta aptos --version para verificar que la tienes instalada.

    Ventana de terminal
    aptos --version

    Deberías ver una respuesta como aptos 4.6.1.

  4. Crear una carpeta para el proyecto

    Crea una nueva carpeta para este tutorial corriendo:

    Ventana de terminal
    mkdir my-first-module
  5. Navegar a la carpeta del proyecto

    Corre cd my-first-module para entrar en tu nueva carpeta.

  6. Inicializar tu cuenta

    Corre aptos init y presiona ‘enter’ en cada paso de la configuración para crear una cuenta de prueba en devnet.

    Deberías ver un mensaje de éxito como este:

    Ventana de terminal
    ---
    Aptos CLI is now set up for account 0x9ec1cfa30b885a5c9d595f32f3381ec16d208734913b587be9e210f60be9f9ba as profile default!
    {
    "Result": "Success"
    }

2. (Opcional) Explora lo que acabas de hacer On-Chain

Sección titulada «2. (Opcional) Explora lo que acabas de hacer On-Chain»
  1. Copia la address de tu cuenta

    Copia la dirección (address) de la línea de comando de tu nueva cuenta.

    La address se ve así 0x9ec1cfa30b885a5c9d595f32f3381ec16d208734913b587be9e210f60be9f9ba y puedes encontrarla en la línea:

    Ventana de terminal
    Aptos CLI is now set up for account 0x9ec1cfa30b885a5c9d595f32f3381ec16d208734913b587be9e210f60be9f9ba as profile default!
  2. Abre el Aptos Explorer

    Ve al Aptos Explorer.

    Esta es la forma principal de chequear rápidamente qué está pasando en devnet, testnet o mainnet. Lo usaremos más adelante para ver nuestros contratos deployados.

  3. Asegúrate de estar en la red Devnet.

    Busca “Devnet” en la esquina superior derecha, o cambia de red haciendo clic en el menú desplegable “Mainnet” y seleccionando Devnet.

    Switching to Devnet network in Aptos Explorer

  4. Busca tu cuenta

    Pega tu address recién creada en la barra de búsqueda.

  5. Ver los resultados de búsqueda

    Espera a que aparezcan los resultados, luego haz clic en el primer resultado.

  6. Chequear la transacción

    Deberías ver tu cuenta recién creada y una transacción con la función faucet, fondeándola con tokens de devnet.

    Viewing Account in Aptos Explorer

  7. Verificar tu balance

    Haz clic en la pestaña “Coins” para ver que tienes 1 APT de Aptos Coin. Esto te permitirá publicar e interactuar con smart contracts en la devnet de Aptos.

3. Escribiendo y Compilando Tu Primer Módulo

Sección titulada «3. Escribiendo y Compilando Tu Primer Módulo»

Ahora que tenemos nuestro entorno configurado y una cuenta creada, escribamos y compilemos nuestro primer módulo Move. A diferencia de Ethereum, donde los contratos existen de forma independiente, Move ata todo a las cuentas: tanto los módulos como sus recursos. Empecemos con un ejemplo simple para entender los conceptos clave.

Move Blockchain Diagram

Este diagrama ilustra la relación entre la propiedad del módulo, la propiedad del token y el estado de la blockchain de Move. Ayuda a visualizar cómo los módulos y recursos están atados a las cuentas, enfatizando los aspectos únicos del diseño de Move en comparación con otras plataformas blockchain.

Los módulos Move son similares a los smart contracts en otras blockchains, con algunas diferencias clave:

  • Recursos: A diferencia de Solidity, donde el estado se almacena en variables del contrato, Move usa “recursos” (resources): tipos de datos especiales que solo pueden existir en un lugar a la vez y siempre están atados a una cuenta.
  • Basado en Módulos: En lugar de deployar contratos enteros como unidades independientes como en Solidity, el código Move se organiza en módulos reutilizables que pueden compartir y manejar recursos a través de límites. Los módulos son más como paquetes de una librería estándar que pueden publicarse juntos o por separado, ofreciendo un control más granular sobre la organización del código.
  • Seguridad por diseño: El sistema de tipos de Move y la semántica de recursos ayudan a prevenir vulnerabilidades comunes de los smart contracts.

Antes de empezar, ve a tu VSCode (o Cursor) e instala la extensión de VSCode Move On Aptos.

  1. Abre VSCode (o Cursor) y navega a la pestaña de Extensiones.
  2. Busca Move On Aptos publicada por aptoslabs e instala la extensión.

Esta extensión nos ayudará con el resaltado de sintaxis, autocompletado y otras características que harán nuestra experiencia de desarrollo más fácil.

Nuestro primer módulo será un sistema simple de almacenamiento de mensajes que permite a las cuentas guardar y recuperar mensajes. Creemos un nuevo proyecto Move dentro de nuestra carpeta my-first-module:

  1. Inicializar el proyecto

    Inicializa un nuevo proyecto Move con aptos move init --name my_first_module

    Esto crea una estructura de proyecto con un directorio sources y un archivo Move.toml.

  2. Crear el archivo del módulo

    Crea un nuevo archivo sources/message.move con el código de nuestro módulo:

    module my_first_module::message {
    use std::string;
    use std::signer;
    struct MessageHolder has key, store, drop {
    message: string::String,
    }
    public entry fun set_message(account: &signer, message: string::String) acquires MessageHolder {
    let account_addr = signer::address_of(account);
    if (exists<MessageHolder>(account_addr)) {
    move_from<MessageHolder>(account_addr);
    };
    move_to(account, MessageHolder { message });
    }
    public fun get_message(account_addr: address): string::String acquires MessageHolder {
    assert!(exists<MessageHolder>(account_addr), 0);
    let message_holder = borrow_global<MessageHolder>(account_addr);
    message_holder.message
    }
    }

    Desglosemos este módulo:

    • Definimos un tipo de recurso MessageHolder que puede almacenar un mensaje de tipo string.
    • set_message permite a una cuenta almacenar un mensaje.
    • get_message permite a cualquiera recuperar un mensaje almacenado.
    • La palabra clave acquires indica a qué recursos necesitan acceso las funciones (MessageHolder, en este caso).
    • move_to y move_from manejan el almacenamiento de recursos bajo las cuentas.
  3. Compilar el módulo

    Compila el módulo Move que acabamos de crear con aptos move compile --named-addresses my_first_module=default

    Deberías ver un mensaje como este si tuvo éxito:

    Ventana de terminal
    aptos move compile --named-addresses my_first_module=default
    Compiling, may take a little while to download git dependencies...
    UPDATING GIT DEPENDENCY https://github.com/aptos-labs/aptos-framework.git
    INCLUDING DEPENDENCY AptosFramework
    INCLUDING DEPENDENCY AptosStdlib
    INCLUDING DEPENDENCY MoveStdlib
    BUILDING my_first_module
    {
    "Result": [
    "9ec1cfa30b885a5c9d595f32f3381ec16d208734913b587be9e210f60be9f9ba::message"
    ]
    }

¡Buen trabajo! Ahora estamos listos para testear y debuggear.

Testing y debugging son partes cruciales del desarrollo de módulos Move. Move tiene soporte nativo para unit testing e impresión de debug (debug printing).

  1. Agregar debug prints

    Primero, modifiquemos nuestro módulo de mensajes para agregar algunos debug prints. Actualiza tu sources/message.move:

    module my_first_module::message {
    use std::string;
    use std::signer;
    use std::debug; // Agrega esto para los debug prints
    struct MessageHolder has key, store, drop {
    message: string::String,
    }
    public entry fun set_message(account: &signer, message: string::String) acquires MessageHolder {
    let account_addr = signer::address_of(account);
    debug::print(&message); // Imprimir el mensaje que se está guardando
    if (exists<MessageHolder>(account_addr)) {
    debug::print(&string::utf8(b"Updating existing message")); // Imprimir info de debug
    move_from<MessageHolder>(account_addr);
    } else {
    debug::print(&string::utf8(b"Creating new message")); // Imprimir al crear nuevo
    };
    move_to(account, MessageHolder { message });
    }
    public fun get_message(account_addr: address): string::String acquires MessageHolder {
    assert!(exists<MessageHolder>(account_addr), 0);
    let message_holder = borrow_global<MessageHolder>(account_addr);
    debug::print(&message_holder.message); // Imprimir el mensaje recuperado
    message_holder.message
    }
    }
  2. Crear archivo de test

    Crea nuestros tests: un nuevo archivo sources/message_tests.move con:

    #[test_only]
    module my_first_module::message_tests {
    use std::string;
    use std::signer;
    use my_first_module::message;
    #[test(sender= @my_first_module)]
    fun test_set_and_get_message(sender: &signer) {
    // Test setting a message
    message::set_message(sender, string::utf8(b"Hello World"));
    // Verify the message was set correctly
    let stored_message = message::get_message(signer::address_of(sender));
    assert!(stored_message == string::utf8(b"Hello World"), 0)
    }
    #[test(sender=@my_first_module)]
    fun test_update_message(sender: &signer) {
    // Test setting a message
    message::set_message(sender, string::utf8(b"Hello World"));
    // Test updating the message
    message::set_message(sender, string::utf8(b"Hello Aptos"));
    // Verify the message was updated correctly
    let stored_message = message::get_message(signer::address_of(sender));
    assert!(stored_message == string::utf8(b"Hello Aptos"), 0)
    }
    }
  3. Correr los tests

    Ahora corre los tests con aptos move test --named-addresses my_first_module=default

    Deberías ver el output si los tests pasan: (Mira abajo para ver cómo manejar errores)

    Ventana de terminal
    INCLUDING DEPENDENCY AptosFramework
    INCLUDING DEPENDENCY AptosStdlib
    INCLUDING DEPENDENCY MoveStdlib
    BUILDING my_first_module
    Running Move unit tests
    [debug] "Hello World"
    [debug] "Creating new message"
    [debug] "Hello World"
    [ PASS ] 0x852a264419a80b27771f072b5cae8c8b358d4450e135e134e065247376a4357a::message_tests::test_set_and_get_message
    [debug] "Hello World"
    [debug] "Creating new message"
    [debug] "Hello Aptos"
    [debug] "Updating existing message"
    [debug] "Hello Aptos"
    [ PASS ] 0x852a264419a80b27771f072b5cae8c8b358d4450e135e134e065247376a4357a::message_tests::test_update_message
    Test result: OK. Total tests: 2; passed: 2; failed: 0
    {
    "Result": "Success"
    }

Si encuentras errores al testear, aquí hay algunos problemas y soluciones comunes:

  • Asegúrate de que todas las dependencias del módulo estén importadas correctamente.
  • Chequea que la address de tu cuenta coincida en el parámetro -named-addresses.
  • Verifica que las funciones de test tengan el atributo #[test].
  • Asegúrate de que los string literals estén codificados correctamente.

Después de compilar y testear exitosamente tu módulo, puedes publicarlo en la blockchain de Aptos. Este proceso hace el deploy de tu código para que sea accesible on-chain.

  1. Publicar el módulo

    Publica tu módulo con aptos move publish --named-addresses my_first_module=default

    Verás un output mostrando el proceso de compilación y luego un prompt preguntando sobre los gas fees:

    Ventana de terminal
    Compiling, may take a little while to download git dependencies...
    UPDATING GIT DEPENDENCY https://github.com/aptos-labs/aptos-framework.git
    INCLUDING DEPENDENCY AptosFramework
    INCLUDING DEPENDENCY AptosStdlib
    INCLUDING DEPENDENCY MoveStdlib
    BUILDING my_first_module
    package size 1271 bytes
    Do you want to submit a transaction for a range of [141300 - 211900] Octas at a gas unit price of 100 Octas? [yes/no] >
  2. Confirmar la transacción

    Escribe y y presiona Enter para confirmar la transacción.

    Después de la confirmación, recibirás una respuesta mostrando los detalles de la transacción:

    Ventana de terminal
    {
    "Result": {
    "transaction_hash": "0x95fce7344b066abda10c07dbf1ffa83e0d9c7bd400e2b143682a6c8a5f179dc2",
    "gas_used": 1413,
    "gas_unit_price": 100,
    "sender": "9ec1cfa30b885a5c9d595f32f3381ec16d208734913b587be9e210f60be9f9ba",
    "sequence_number": 0,
    "success": true,
    "timestamp_us": 1735351260227638,
    "version": 273029731,
    "vm_status": "Executed successfully"
    }
    }

Después de una publicación exitosa, puedes verificar que tu módulo está on-chain siguiendo estos pasos:

  1. Abre el Explorer

    Ve al Aptos Explorer

  2. Chequear la transacción

    Busca la address de tu cuenta. Deberías notar que hay una nueva transacción en tu cuenta, la función code::publish_package_txn.

  3. Ver tu balance

    Haz clic en la pestaña “Coins” para ver que ahora tienes menos de 1 APT de Aptos Coin.

    Explorer Coins View

    Has gastado una pequeña cantidad en gas para deployar el contrato, así que deberías tener alrededor de 0.99855 APT restantes.

  4. Encontrar tu módulo

    Busca bajo la pestaña “Modules”

    Exporer Modules View

  5. Verificar el módulo

    Deberías ver tu módulo “message” listado.

Ahora que tu módulo está publicado, puedes interactuar con él a través de la CLI de Aptos:

  1. Configurar un mensaje

    Configura un mensaje usando la CLI:

    Ventana de terminal
    aptos move run --function-id 'default::message::set_message' --args 'string:Hello, Aptos!'

    Verás un prompt de gas fee similar al que viste durante la publicación.

  2. Confirmar la transacción

    Después de confirmar con y, deberías obtener una respuesta de éxito como:

    Ventana de terminal
    Transaction submitted: https://explorer.aptoslabs.com/txn/0x0c0b1e56a31d037280278327eb8fdfcc469a20213e5e65accf6e7c56af574449?network=devnet
    {
    "Result": {
    "transaction_hash": "0x0c0b1e56a31d037280278327eb8fdfcc469a20213e5e65accf6e7c56af574449",
    "gas_used": 445,
    "gas_unit_price": 100,
    "sender": "9ec1cfa30b885a5c9d595f32f3381ec16d208734913b587be9e210f60be9f9ba",
    "sequence_number": 1,
    "success": true,
    "timestamp_us": 1735351754495208,
    "version": 273137362,
    "vm_status": "Executed successfully"
    }
    }
  3. Ver tu mensaje

    Mira tu mensaje almacenado revisando bajo Resources en el Explorer.

  4. ¡Celebra!

    ¡Lo logramos!

¡Felicitaciones! Has logrado exitosamente:

  1. Compilar tu primer módulo Move
  2. Agregar tests para ayudar a debuggear
  3. Publicar tu módulo on-chain
  4. Usar tu contrato a través de la CLI

¡Ahora tu módulo Move publicado puede ser conectado justo como una API a través de uno de nuestros muchos SDKs Oficiales!

Aquí hay algunos siguientes pasos sugeridos para obtener un entendimiento más profundo de los módulos Move:

  1. Intenta modificar el módulo para agregar una nueva funcionalidad. Puedes usar el Move Book para construir tu conocimiento sobre cómo escribir módulos Move.
  2. Para entender cómo funciona Move on-chain, puedes aprender sobre el sistema de recursos de Move.
  3. Si estás construyendo una aplicación para interactuar con contratos o buscar datos on-chain, aprende cómo usar los SDKs aquí.
  4. Únete al Discord de Aptos para conectar con otros desarrolladores.