Paquetes
Los paquetes permiten a los programadores de Move reutilizar código más fácilmente y compartirlo entre proyectos. El sistema de paquetes de Move permite a los programadores hacer fácilmente lo siguiente:
- Definir un paquete que contenga código Move;
- Parametrizar un paquete por direcciones nombradas;
- Importar y usar paquetes en otro código Move e instanciar direcciones nombradas;
- Construir paquetes y generar artefactos de compilación asociados de los paquetes; y
- Trabajar con una interfaz común alrededor de artefactos Move compilados.
Estructura del Paquete y Sintaxis del Manifiesto
Sección titulada «Estructura del Paquete y Sintaxis del Manifiesto»Un directorio fuente de paquete Move contiene un archivo de manifiesto de paquete Move.toml
junto con un conjunto de subdirectorios:
Directoryun_paquete_move/
- Move.toml
Directorysources (requerido)/
- module.move
- *.move
- examples (opcional, modo test & dev)/
- scripts (opcional, también se puede poner en sources)/
- doc_templates (opcional)/
- tests (opcional, modo test)/
Los directorios marcados como requerido
deben estar presentes para que el directorio se considere un paquete Move y pueda ser compilado. Los directorios opcionales pueden estar presentes, y si es así serán incluidos en el proceso de compilación. Dependiendo del modo con el que se construye el paquete (test
o dev
), los directorios tests
y examples
también serán incluidos.
El directorio sources
puede contener tanto módulos Move como scripts Move (tanto scripts Move como módulos que contienen funciones de script). El directorio examples
puede contener código adicional para ser usado solo para propósitos de desarrollo y/o tutorial que no será incluido cuando se compile fuera del modo test
o dev
.
Se soporta un directorio scripts
para que los scripts Move puedan separarse de los módulos si eso es deseado por el autor del paquete. El directorio scripts
siempre será incluido para compilación si está presente. La documentación será construida usando cualquier plantilla de documentación presente en el directorio doc_templates
.
Move.toml
Sección titulada «Move.toml»El manifiesto del paquete Move se define dentro del archivo Move.toml
y tiene la siguiente sintaxis. Los campos opcionales están marcados con *
, +
denota uno o más elementos:
[package]name = <string> # ej., "MoveStdlib"version = "<uint>.<uint>.<uint>" # ej., "0.1.1"license* = <string> # ej., "MIT", "GPL", "Apache 2.0"authors* = [<string>] # ej., ["Joe Smith (joesmith@noemail.com)", "Jane Smith (janesmith@noemail.com)"]
[addresses] # (Sección opcional) Declara direcciones nombradas en este paquete e instancia direcciones nombradas en el grafo del paquete# Una o más líneas declarando direcciones nombradas en el siguiente formato<addr_name> = "_" | "<hex_address>" # ej., std = "_" o my_addr = "0xC0FFEECAFE"
[dependencies] # (Sección opcional) Rutas a dependencias e instanciaciones o renombramientos de direcciones nombradas de cada dependencia# Una o más líneas declarando dependencias en el siguiente formato<string> = { local = <string>, addr_subst* = { (<string> = (<string> | "<hex_address>"))+ } } # dependencias locales<string> = { git = <URL terminando en .git>, subdir=<ruta al dir que contiene Move.toml dentro del repo git>, rev=<hash de commit git o nombre de rama>, addr_subst* = { (<string> = (<string> | "<hex_address>"))+ } } # dependencias git
[dev-addresses] # (Sección opcional) Igual que la sección [addresses], pero solo incluida en modos "dev" y "test"# Una o más líneas declarando direcciones nombradas dev en el siguiente formato<addr_name> = "_" | "<hex_address>" # ej., std = "_" o my_addr = "0xC0FFEECAFE"
[dev-dependencies] # (Sección opcional) Igual que la sección [dependencies], pero solo incluida en modos "dev" y "test"# Una o más líneas declarando dependencias dev en el siguiente formato<string> = { local = <string>, addr_subst* = { (<string> = (<string> | <address>))+ } }
Un ejemplo de un manifiesto de paquete mínimo con una dependencia local y una dependencia git:
[package]name = "UnNombre"version = "0.0.0"
Un ejemplo de un manifiesto de paquete más estándar que también incluye la biblioteca estándar de Move e instancia la dirección nombrada Std
de ella con el valor de dirección 0x1
:
[package]name = "UnNombre"version = "0.0.0"license = "Apache 2.0"
[addresses]std = "0x1"
[dependencies]MoveStdlib = { local = "../move-stdlib", addr_subst = { "std" = "0x1" } }
Direcciones Nombradas Durante la Compilación
Sección titulada «Direcciones Nombradas Durante la Compilación»Las direcciones nombradas pueden dejarse sin asignar en el manifiesto del paquete, y se pueden asignar instanciaciones de estas direcciones mediante el comando aptos move compile
:
[package]name = "Ejemplo"version = "0.0.0"
[addresses]A = "_"B = "0x42"
Que luego se compila con:
aptos move compile --named-addresses A=0x42,B=0x43
Esto resultado en una compilación donde A
se establece a 0x42
y B
se establece a 0x43
. Nota que B
fue reasignado de su valor en el manifiesto (0x42
) a 0x43
.
Herencia de Direcciones Nombradas
Sección titulada «Herencia de Direcciones Nombradas»Si tienes un paquete P
que depende de un paquete Q
, entonces P
puede usar direcciones nombradas que se definen en Q
sustituyéndolas en la sección [dependencies]
. Por ejemplo:
Paquete P
:
[package]name = "P"version = "0.0.0"
[addresses]P_addr = "0x100"
[dependencies]Q = { local = "../Q", addr_subst = { "Q_addr" = "0x200" } }
Paquete Q
:
[package]name = "Q"version = "0.0.0"
[addresses]Q_addr = "_"
Esto permite que P
use Q_addr
en su código, y será resuelto a 0x200
cuando se compile P
.
Proceso de Construcción
Sección titulada «Proceso de Construcción»Estructura de Compilación
Sección titulada «Estructura de Compilación»El directorio de salida para un paquete compilado incluye:
Directorybuild/
Directorynombre-del-paquete/
- BuildInfo.yaml
Directorybytecode_modules/
Directorydependencies/
Directorynombre-dependencia/
Directorybytecode/
- *.mv
- *.mv
Directorysource_maps/
Directorydependencies/
Directorynombre-dependencia/
Directorysource_maps/
- *.mvsm
- *.mvsm
Directorysources/
Directorydependencies/
Directorynombre-dependencia/
- *.move
- *.move
Directorydocs/
- *.md
Comandos de Construcción
Sección titulada «Comandos de Construcción»Compilación Básica
Sección titulada «Compilación Básica»aptos move compile
Esto compila el paquete en el directorio actual.
Compilación con Direcciones Nombradas
Sección titulada «Compilación con Direcciones Nombradas»aptos move compile --named-addresses addr1=0x123,addr2=0x456
Compilación para Testing
Sección titulada «Compilación para Testing»aptos move test
Esto incluye directorios tests
y examples
en la compilación.
Compilación con Documentación
Sección titulada «Compilación con Documentación»aptos move compile --generate-docs
Modos de Compilación
Sección titulada «Modos de Compilación»Modo Producción (por defecto)
Sección titulada «Modo Producción (por defecto)»- Solo incluye directorio
sources
- Solo incluye directorio
scripts
si está presente - Excluye
tests
,examples
,dev-dependencies
, ydev-addresses
Modo Test
Sección titulada «Modo Test»aptos move test
- Incluye todo de modo producción
- Incluye directorio
tests
- Incluye
dev-dependencies
ydev-addresses
Modo Dev
Sección titulada «Modo Dev»aptos move compile --dev
- Incluye todo de modo test
- Incluye directorio
examples
Dependencias
Sección titulada «Dependencias»Dependencias Locales
Sección titulada «Dependencias Locales»Para depender de un paquete en el sistema de archivos local:
[dependencies]MiLibreria = { local = "../mi-libreria" }
Con Sustitución de Direcciones
Sección titulada «Con Sustitución de Direcciones»[dependencies]MiLibreria = { local = "../mi-libreria", addr_subst = { "lib_addr" = "0x42" }}
Dependencias Git
Sección titulada «Dependencias Git»Para depender de un paquete en un repositorio git:
[dependencies]AptosFramework = { git = "https://github.com/aptos-labs/aptos-core.git", rev = "main", subdir = "aptos-move/framework/aptos-framework"}
Con Subdirectorio y Sustitución
Sección titulada «Con Subdirectorio y Sustitución»[dependencies]AptosStdlib = { git = "https://github.com/aptos-labs/aptos-core.git", rev = "framework/releases/v1.3.0", subdir = "aptos-move/framework/aptos-stdlib", addr_subst = { "std" = "0x1" }}
Dependencias de Desarrollo
Sección titulada «Dependencias de Desarrollo»Para dependencias que solo se necesitan durante desarrollo o testing:
[dev-dependencies]TestHelpers = { local = "../test-helpers" }MockFramework = { git = "https://github.com/example/mock-framework.git", rev = "v1.0.0"}
Resolución de Dependencias
Sección titulada «Resolución de Dependencias»Move resuelve dependencias de la siguiente manera:
- Resolución de Nombres: Los nombres de paquetes deben ser únicos en el grafo de dependencias
- Resolución de Versiones: Si múltiples versiones del mismo paquete son requeridas, Move falla la compilación
- Resolución de Direcciones: Las direcciones nombradas se resuelven según la jerarquía del paquete
Casos de Uso Avanzados
Sección titulada «Casos de Uso Avanzados»Desarrollo de Bibliotecas
Sección titulada «Desarrollo de Bibliotecas»Para crear una biblioteca reutilizable:
[package]name = "MiLibreria"version = "1.0.0"license = "MIT"authors = ["Tu Nombre <tu@email.com>"]
[addresses]lib = "_" # Permite a los usuarios asignar esta dirección
En el código:
module lib::utilities { // Funciones de utilidad aquí}
Los usuarios pueden entonces usar tu biblioteca:
[dependencies]MiLibreria = { git = "https://github.com/tu-usuario/mi-libreria.git", rev = "v1.0.0", addr_subst = { "lib" = "0x123" }}
Plantillas de Proyecto
Sección titulada «Plantillas de Proyecto»Para crear una plantilla de proyecto:
Directoryplantilla-proyecto/
- Move.toml
Directorysources/
- main.move
Directoryscripts/
- deploy.move
Directorytests/
- main_tests.move
Directoryexamples/
- ejemplo_uso.move
Directorydoc_templates/
- README.md
Monorepo con Múltiples Paquetes
Sección titulada «Monorepo con Múltiples Paquetes»mi-proyecto/├── contratos/│ ├── core/│ │ └── Move.toml│ └── periphery/│ └── Move.toml├── scripts/│ └── Move.toml└── tests/ └── Move.toml
Cada Move.toml
puede referenciar otros paquetes en el monorepo:
[dependencies]Core = { local = "../core" }
Versionado y Releases
Sección titulada «Versionado y Releases»Para manejar versiones:
[package]name = "MiContrato"version = "2.1.0" # formato semver
[dependencies]AptosFramework = { git = "https://github.com/aptos-labs/aptos-core.git", rev = "aptos-release-v1.8" # versión específica}
Mejores Prácticas
Sección titulada «Mejores Prácticas»1. Estructura de Proyecto
Sección titulada «1. Estructura de Proyecto»mi-dapp/├── Move.toml├── sources/│ ├── main.move # Lógica principal│ ├── events.move # Definiciones de eventos│ └── errors.move # Códigos de error├── scripts/│ ├── deploy.move # Scripts de despliegue│ └── upgrade.move # Scripts de actualización├── tests/│ ├── unit_tests.move # Tests unitarios│ └── integration_tests.move└── doc_templates/ └── overview.md
2. Manifiesto Completo
Sección titulada «2. Manifiesto Completo»[package]name = "MiDApp"version = "1.0.0"license = "Apache-2.0"authors = ["Equipo Dev <dev@ejemplo.com>"]
[addresses]my_app = "_"admin = "0x1234567890abcdef"
[dependencies]AptosFramework = { git = "https://github.com/aptos-labs/aptos-core.git", rev = "main", subdir = "aptos-move/framework/aptos-framework"}AptosStdlib = { git = "https://github.com/aptos-labs/aptos-core.git", rev = "main", subdir = "aptos-move/framework/aptos-stdlib"}
[dev-addresses]test_account = "0xCAFE"
[dev-dependencies]TestUtils = { local = "../test-utils" }
3. Separación de Responsabilidades
Sección titulada «3. Separación de Responsabilidades»// sources/main.move - Lógica principalmodule my_app::main { use my_app::events; use my_app::errors; // Lógica principal aquí}
// sources/events.move - Eventosmodule my_app::events { struct TransferEvent has copy, drop { from: address, to: address, amount: u64, }}
// sources/errors.move - Manejo de erroresmodule my_app::errors { const EINVALID_AMOUNT: u64 = 1; const EUNAUTHORIZED: u64 = 2;}
4. Testing Comprehensivo
Sección titulada «4. Testing Comprehensivo»#[test_only]module my_app::unit_tests { use my_app::main;
#[test] fun test_basic_functionality() { // Tests aquí }}
// tests/integration_tests.move#[test_only]module my_app::integration_tests { use aptos_framework::account; use my_app::main;
#[test(admin = @my_app)] fun test_end_to_end_flow(admin: &signer) { // Tests de integración aquí }}
5. Documentación
Sección titulada «5. Documentación»[package]name = "MiDApp"# ... otros campos
# Generar documentación automáticamente
aptos move compile --generate-docs
Solución de Problemas
Sección titulada «Solución de Problemas»Errores Comunes
Sección titulada «Errores Comunes»Error: Dependencia no encontrada
Sección titulada «Error: Dependencia no encontrada»Error: Package dependency 'MiLibreria' not found
Solución: Verificar la ruta en Move.toml
:
[dependencies]MiLibreria = { local = "../mi-libreria" } # Verificar ruta correcta
Error: Conflicto de direcciones nombradas
Sección titulada «Error: Conflicto de direcciones nombradas»Error: Named address 'std' is assigned different values
Solución: Asegurar consistencia en addr_subst
:
[dependencies]Lib1 = { local = "../lib1", addr_subst = { "std" = "0x1" } }Lib2 = { local = "../lib2", addr_subst = { "std" = "0x1" } } # Mismo valor
Error: Versión de Move incompatible
Sección titulada «Error: Versión de Move incompatible»Error: Package compiled with different version of Move
Solución: Recompilar todas las dependencias o usar versiones compatibles.
Comandos de Depuración
Sección titulada «Comandos de Depuración»Verificar Dependencias
Sección titulada «Verificar Dependencias»aptos move compile --dump-all
Limpiar Cache de Construcción
Sección titulada «Limpiar Cache de Construcción»rm -rf build/aptos move compile
Verificar Direcciones Resueltas
Sección titulada «Verificar Direcciones Resueltas»aptos move compile --explain
Integración con Aptos CLI
Sección titulada «Integración con Aptos CLI»Comandos Útiles
Sección titulada «Comandos Útiles»Crear Nuevo Paquete
Sección titulada «Crear Nuevo Paquete»aptos move init --name mi-proyecto
Publicar Paquete
Sección titulada «Publicar Paquete»aptos move publish --named-addresses my_app=0x123
Ejecutar Tests
Sección titulada «Ejecutar Tests»aptos move test --named-addresses my_app=0x123
Verificar Compilación
Sección titulada «Verificar Compilación»aptos move compile --check
Configuración de Perfiles
Sección titulada «Configuración de Perfiles»profiles: default: private_key: "0x..." public_key: "0x..." account: "0x123..." rest_url: "https://fullnode.mainnet.aptoslabs.com" faucet_url: "https://faucet.mainnet.aptoslabs.com"
testnet: private_key: "0x..." public_key: "0x..." account: "0x456..." rest_url: "https://fullnode.testnet.aptoslabs.com" faucet_url: "https://faucet.testnet.aptoslabs.com"
Conclusión
Sección titulada «Conclusión»El sistema de paquetes de Move proporciona una base robusta para organizar, distribuir y reutilizar código Move. Las características clave incluyen:
- Gestión de dependencias flexible con soporte local y git
- Direcciones nombradas parametrizables para máxima reutilización
- Modos de construcción para diferentes fases de desarrollo
- Herramientas integradas para testing, documentación y despliegue
Seguir las mejores prácticas de estructura de paquetes, versionado y testing asegura que tus proyectos Move sean mantenibles, testeable y fáciles de compartir con la comunidad.
Puntos clave para recordar:
- Usa estructura de directorio estándar para consistencia
- Parametriza direcciones para máxima reutilización
- Separa dependencias de desarrollo de las de producción
- Versiona apropiadamente y especifica dependencias exactas
- Incluye tests comprehensivos y documentación
- Aprovecha las herramientas del CLI de Aptos para flujos de trabajo eficientes