Saltearse al contenido

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.

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:

Ventana de terminal
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.

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.

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
Ventana de terminal
aptos move compile

Esto compila el paquete en el directorio actual.

Ventana de terminal
aptos move compile --named-addresses addr1=0x123,addr2=0x456
Ventana de terminal
aptos move test

Esto incluye directorios tests y examples en la compilación.

Ventana de terminal
aptos move compile --generate-docs
  • Solo incluye directorio sources
  • Solo incluye directorio scripts si está presente
  • Excluye tests, examples, dev-dependencies, y dev-addresses
Ventana de terminal
aptos move test
  • Incluye todo de modo producción
  • Incluye directorio tests
  • Incluye dev-dependencies y dev-addresses
Ventana de terminal
aptos move compile --dev
  • Incluye todo de modo test
  • Incluye directorio examples

Para depender de un paquete en el sistema de archivos local:

[dependencies]
MiLibreria = { local = "../mi-libreria" }
[dependencies]
MiLibreria = {
local = "../mi-libreria",
addr_subst = {
"lib_addr" = "0x42"
}
}

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"
}
[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"
}
}

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"
}

Move resuelve dependencias de la siguiente manera:

  1. Resolución de Nombres: Los nombres de paquetes deben ser únicos en el grafo de dependencias
  2. Resolución de Versiones: Si múltiples versiones del mismo paquete son requeridas, Move falla la compilación
  3. Resolución de Direcciones: Las direcciones nombradas se resuelven según la jerarquía del paquete

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" }
}

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
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:

periphery/Move.toml
[dependencies]
Core = { local = "../core" }

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
}
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
[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" }
// sources/main.move - Lógica principal
module my_app::main {
use my_app::events;
use my_app::errors;
// Lógica principal aquí
}
// sources/events.move - Eventos
module my_app::events {
struct TransferEvent has copy, drop {
from: address,
to: address,
amount: u64,
}
}
// sources/errors.move - Manejo de errores
module my_app::errors {
const EINVALID_AMOUNT: u64 = 1;
const EUNAUTHORIZED: u64 = 2;
}
tests/unit_tests.move
#[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í
}
}
Move.toml
[package]
name = "MiDApp"
# ... otros campos
# Generar documentación automáticamente
Ventana de terminal
aptos move compile --generate-docs
Error: Package dependency 'MiLibreria' not found

Solución: Verificar la ruta en Move.toml:

[dependencies]
MiLibreria = { local = "../mi-libreria" } # Verificar ruta correcta
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: Package compiled with different version of Move

Solución: Recompilar todas las dependencias o usar versiones compatibles.

Ventana de terminal
aptos move compile --dump-all
Ventana de terminal
rm -rf build/
aptos move compile
Ventana de terminal
aptos move compile --explain
Ventana de terminal
aptos move init --name mi-proyecto
Ventana de terminal
aptos move publish --named-addresses my_app=0x123
Ventana de terminal
aptos move test --named-addresses my_app=0x123
Ventana de terminal
aptos move compile --check
.aptos/config.yaml
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"

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