Ir al contenido

Historial de Versiones del Bytecode

El formato de bytecode de Move lleva un número de versión en cada módulo compilado. La VM usa esta versión para decidir qué características están disponibles durante la verificación y ejecución. Esta página documenta los cambios introducidos en cada versión desde v5 (la mínima que la VM acepta) hasta v10 (la más reciente).

VersiónPredeterminada ParaAdiciones Clave
v5— (mínima soportada)Conjunto de instrucciones base
v6Refactorización interna; sin nuevas características visibles para el usuario
v7Tipos enum e instrucciones de variante
v8Closures de primera clase
v9Language v1 (predeterminada)Tipos de enteros con signo (i8..i256)
v10Language v2.4, v2.5Instrucción AbortMsg (abortar con mensaje)

La versión 5 es la versión mínima de bytecode que acepta el Move VM de Aptos. Define el conjunto de instrucciones base, el diseño binario del módulo y el sistema de tipos central. Todas las instrucciones presentes antes de la v7 pertenecen a esta línea base.

Los módulos compilados en v5 pueden usar el conjunto completo de tipos de enteros sin signo (u8, u16, u32, u64, u128, u256), structs con abilities, genéricos, operaciones de almacenamiento global e instrucciones de vector. Consulta la Referencia del Conjunto de Instrucciones para la lista completa de instrucciones base.

La versión 6 introdujo cambios internos al formato binario pero no agregó nuevas instrucciones, tipos de tabla ni signature tokens visibles para los desarrolladores de Move. Los módulos compilados en v6 son funcionalmente equivalentes a los módulos v5 desde la perspectiva del desarrollador.

La versión 7 agregó tipos enum (también llamados variantes) al bytecode de Move. Los enums permiten que un solo tipo contenga una de varias variantes nombradas, cada una con sus propios campos — similar a los enums de Rust o los tipos de datos algebraicos en lenguajes funcionales.

InstrucciónOpcodeDescripción
PackVariant0x52Crear un valor de variante con los campos dados
PackVariantGeneric0x53Versión genérica de PackVariant
UnpackVariant0x54Desestructurar una variante, apilando sus campos en el stack
UnpackVariantGeneric0x55Versión genérica de UnpackVariant
TestVariant0x56Probar si un valor es una variante específica; apila bool
TestVariantGeneric0x57Versión genérica de TestVariant
ImmBorrowVariantField0x4ETomar prestado un campo de variante de forma inmutable
MutBorrowVariantField0x4FTomar prestado un campo de variante de forma mutable
ImmBorrowVariantFieldGeneric0x50Versión genérica de ImmBorrowVariantField
MutBorrowVariantFieldGeneric0x51Versión genérica de MutBorrowVariantField

Estos tipos de tabla almacenan metadatos sobre variantes de enum y sus campos:

Tipo de TablaCódigoPropósito
VARIANT_FIELD_HANDLES0x11Mapea referencias de campos de variante a su variante padre e índice de campo
VARIANT_FIELD_INST0x12Instanciaciones de handles genéricos de campos de variante
STRUCT_VARIANT_HANDLES0x13Mapea referencias de variante a su definición de struct padre e índice de variante
STRUCT_VARIANT_INST0x14Instanciaciones de handles genéricos de variantes de struct

Con v7, los desarrolladores de Move pueden definir tipos como:

enum Color {
Red,
Green,
Blue,
Custom { r: u8, g: u8, b: u8 },
}

El compilador emite instrucciones PackVariant / UnpackVariant para construir y desestructurar estos valores, y TestVariant para implementar la coincidencia de patrones. Consulta el Libro de Move — Enums para la referencia a nivel de código fuente.

La versión 8 agregó closures de primera clase al bytecode de Move. Los closures capturan valores de su entorno y pueden pasarse como argumentos de función, habilitando patrones de programación de orden superior.

InstrucciónOpcodeDescripción
PackClosure0x58Crear un closure que captura valores del stack especificados y los vincula a una función
PackClosureGeneric0x59Versión genérica de PackClosure
CallClosure0x5AInvocar un closure, apilando sus valores de retorno en el stack

La versión 8 introdujo el signature token Function, que representa el tipo de un closure o referencia de función. Un token Function lleva:

  • Una lista de tipos de parámetro
  • Una lista de tipos de retorno
  • Un conjunto de abilities que restringe cómo puede usarse el closure

Este token aparece en signatures donde se espera un tipo closure, como parámetros de función que aceptan callbacks.

Los closures permiten patrones como pasar una función de comparación a una rutina de ordenamiento o crear callbacks que llevan estado capturado. El signature token Function da al sistema de tipos visibilidad completa sobre los tipos de closure, para que el verificador de bytecode pueda imponer seguridad de tipos y restricciones de abilities sobre los closures de la misma manera que lo hace con los structs.

La versión 9 agregó tipos de enteros con signo a Move. Anteriormente, Move solo soportaba enteros sin signo (u8 a u256). La versión 9 introdujo seis contrapartes con signo junto con la negación aritmética.

InstrucciónOpcodeDescripción
LdI80x5BCargar una constante entera con signo de 8 bits
LdI160x5CCargar una constante entera con signo de 16 bits
LdI320x5DCargar una constante entera con signo de 32 bits
LdI640x5ECargar una constante entera con signo de 64 bits
LdI1280x5FCargar una constante entera con signo de 128 bits
LdI2560x60Cargar una constante entera con signo de 256 bits
InstrucciónOpcodeDescripción
CastI80x61Convertir el tope del stack a i8
CastI160x62Convertir el tope del stack a i16
CastI320x63Convertir el tope del stack a i32
CastI640x64Convertir el tope del stack a i64
CastI1280x65Convertir el tope del stack a i128
CastI2560x66Convertir el tope del stack a i256
InstrucciónOpcodeDescripción
Negate0x67Negación aritmética; desapila un entero con signo y apila su negación

Seis nuevos signature tokens representan tipos de enteros con signo en el sistema de tipos:

  • I8 — entero con signo de 8 bits
  • I16 — entero con signo de 16 bits
  • I32 — entero con signo de 32 bits
  • I64 — entero con signo de 64 bits
  • I128 — entero con signo de 128 bits
  • I256 — entero con signo de 256 bits

Estos tokens aparecen en firmas de funciones, definiciones de campos de struct y tipos de variables locales donde se usen enteros con signo.

Los enteros con signo soportan valores negativos y aritmética en complemento a dos, lo que simplifica cálculos financieros, matemáticas de coordenadas y cualquier dominio donde los números negativos son naturales. La versión 9 es la versión predeterminada de bytecode para la configuración estándar del lenguaje Move.

La versión 10 agregó la instrucción abort-with-message, que permite que una transacción aborte con una cadena de error legible por humanos además del código numérico de aborto.

InstrucciónOpcodeDescripción
AbortMsg0x68Abortar la ejecución con un código de error u64 y una cadena de mensaje UTF-8 opcional

Antes de v10, abort solo aceptaba un código numérico, lo que dificultaba diagnosticar fallos sin consultar el código fuente del módulo. Con AbortMsg, los módulos pueden incluir mensajes de error descriptivos que aparecen en la salida de la transacción, mejorando enormemente la capacidad de depuración. La versión 10 es la versión predeterminada de bytecode para Move language v2.4 y v2.5.

  • La VM acepta bytecode desde v5 hasta la versión máxima actual (v10 al momento de escribir esto). Los módulos compilados en cualquier versión soportada pueden coexistir en la cadena y llamarse entre sí.
  • Cuando un módulo declara una versión de bytecode más antigua, el verificador rechaza instrucciones y tipos introducidos en versiones posteriores. Por ejemplo, un módulo en v6 no puede usar PackVariant (una instrucción de v7).
  • La versión de bytecode se codifica como un u32 little-endian en los bytes 4 al 7 del encabezado binario del módulo, inmediatamente después de los bytes mágicos. Consulta la página del Formato Binario de Módulo para una descripción completa del diseño del encabezado.
  • Publicar un módulo con una versión más nueva que la que soporta la VM causa que la transacción falle durante la verificación.