|
1 | | ---- |
2 | | -title: "Bytecode Version History" |
3 | | -description: "Reference for what changed in each Move bytecode format version, from v5 through v10, including new instructions, table types, and signature tokens." |
4 | | -sidebar: |
5 | | - label: "Version History" |
6 | | ---- |
7 | | - |
8 | | -The Move bytecode format carries a version number in every compiled module. The VM uses this |
9 | | -version to decide which features are available during verification and execution. This page |
10 | | -documents the changes introduced in each version from v5 (the minimum the VM accepts) through |
11 | | -v10 (the latest). |
12 | | - |
13 | | -## Quick Reference |
14 | | - |
15 | | -| Version | Default For | Key Additions | |
16 | | -| ------- | ---------------------- | ------------------------------------------------- | |
17 | | -| v5 | -- (minimum supported) | Baseline instruction set | |
18 | | -| v6 | -- | Internal refactoring; no new user-facing features | |
19 | | -| v7 | -- | Enum types and variant instructions | |
20 | | -| v8 | -- | First-class closures | |
21 | | -| v9 | Language v1 (default) | Signed integer types (`i8`..`i256`) | |
22 | | -| v10 | Language v2.4, v2.5 | `AbortMsg` instruction (abort with message) | |
23 | | - |
24 | | -## Version 5 |
25 | | - |
26 | | -Version 5 is the **minimum bytecode version** the Aptos Move VM accepts. It defines the baseline |
27 | | -instruction set, the module binary layout, and the core type system. All instructions present |
28 | | -before v7 belong to this baseline. |
29 | | - |
30 | | -Modules compiled at v5 can use the full set of unsigned integer types (`u8`, `u16`, `u32`, `u64`, |
31 | | -`u128`, `u256`), structs with abilities, generics, global storage operations, and vector |
32 | | -instructions. See the [Instruction Set Reference](/build/smart-contracts/bytecode/instructions) |
33 | | -for the complete baseline instruction list. |
34 | | - |
35 | | -## Version 6 |
36 | | - |
37 | | -Version 6 introduced internal changes to the binary format but did not add any new instructions, |
38 | | -table types, or signature tokens visible to Move authors. Modules compiled at v6 are functionally |
39 | | -equivalent to v5 modules from a developer perspective. |
40 | | - |
41 | | -## Version 7 |
42 | | - |
43 | | -Version 7 added **enum types** (also called variants) to the Move bytecode. Enums allow a single |
44 | | -type to hold one of several named variants, each with its own fields -- similar to Rust enums or |
45 | | -algebraic data types in functional languages. |
46 | | - |
47 | | -### New Instructions |
48 | | - |
49 | | -| Instruction | Opcode | Description | |
50 | | -| ------------------------------ | ------ | --------------------------------------------------------- | |
51 | | -| `PackVariant` | `0x52` | Create a variant value with the given fields | |
52 | | -| `PackVariantGeneric` | `0x53` | Generic version of `PackVariant` | |
53 | | -| `UnpackVariant` | `0x54` | Destructure a variant, pushing its fields onto the stack | |
54 | | -| `UnpackVariantGeneric` | `0x55` | Generic version of `UnpackVariant` | |
55 | | -| `TestVariant` | `0x56` | Test whether a value is a specific variant; pushes `bool` | |
56 | | -| `TestVariantGeneric` | `0x57` | Generic version of `TestVariant` | |
57 | | -| `ImmBorrowVariantField` | `0x4E` | Borrow a variant field immutably | |
58 | | -| `MutBorrowVariantField` | `0x4F` | Borrow a variant field mutably | |
59 | | -| `ImmBorrowVariantFieldGeneric` | `0x50` | Generic version of `ImmBorrowVariantField` | |
60 | | -| `MutBorrowVariantFieldGeneric` | `0x51` | Generic version of `MutBorrowVariantField` | |
61 | | - |
62 | | -### New Table Types |
63 | | - |
64 | | -These table types store metadata about enum variants and their fields: |
65 | | - |
66 | | -| Table Type | Code | Purpose | |
67 | | -| ------------------------ | ------ | --------------------------------------------------------------------------- | |
68 | | -| `VARIANT_FIELD_HANDLES` | `0x11` | Maps variant field references to their parent variant and field index | |
69 | | -| `VARIANT_FIELD_INST` | `0x12` | Instantiations of generic variant field handles | |
70 | | -| `STRUCT_VARIANT_HANDLES` | `0x13` | Maps variant references to their parent struct definition and variant index | |
71 | | -| `STRUCT_VARIANT_INST` | `0x14` | Instantiations of generic struct variant handles | |
72 | | - |
73 | | -### What This Enables |
74 | | - |
75 | | -With v7, Move developers can define types like: |
76 | | - |
77 | | -```move |
78 | | -enum Color { |
79 | | - Red, |
80 | | - Green, |
81 | | - Blue, |
82 | | - Custom { r: u8, g: u8, b: u8 }, |
83 | | -} |
84 | | -``` |
85 | | - |
86 | | -The compiler emits `PackVariant` / `UnpackVariant` instructions to construct and destructure these |
87 | | -values, and `TestVariant` to implement pattern matching. See the |
88 | | -[Move Book -- Enums](/build/smart-contracts/book/enums) for the source-level reference. |
89 | | - |
90 | | -## Version 8 |
91 | | - |
92 | | -Version 8 added **first-class closures** to Move bytecode. Closures capture values from their |
93 | | -environment and can be passed as function arguments, enabling higher-order programming patterns. |
94 | | - |
95 | | -### New Instructions |
96 | | - |
97 | | -| Instruction | Opcode | Description | |
98 | | -| -------------------- | ------ | ---------------------------------------------------------------------------------- | |
99 | | -| `PackClosure` | `0x58` | Create a closure that captures specified stack values and binds them to a function | |
100 | | -| `PackClosureGeneric` | `0x59` | Generic version of `PackClosure` | |
101 | | -| `CallClosure` | `0x5A` | Invoke a closure, pushing its return values onto the stack | |
102 | | - |
103 | | -### New Signature Token |
104 | | - |
105 | | -Version 8 introduced the **`Function`** signature token, which represents the type of a closure |
106 | | -or function reference. A `Function` token carries: |
107 | | - |
108 | | -- A list of parameter types |
109 | | -- A list of return types |
110 | | -- An ability set that constrains how the closure can be used |
111 | | - |
112 | | -This token appears in signatures wherever a closure type is expected, such as function parameters |
113 | | -that accept callbacks. |
114 | | - |
115 | | -### What This Enables |
116 | | - |
117 | | -Closures allow patterns like passing a comparison function to a sorting routine or creating |
118 | | -callbacks that carry captured state. The `Function` signature token gives the type system full |
119 | | -visibility into closure types, so the bytecode verifier can enforce type safety and ability |
120 | | -constraints on closures just as it does on structs. |
121 | | - |
122 | | -## Version 9 |
123 | | - |
124 | | -Version 9 added **signed integer types** to Move. Previously, Move supported only unsigned |
125 | | -integers (`u8` through `u256`). Version 9 introduced six signed counterparts along with |
126 | | -arithmetic negation. |
127 | | - |
128 | | -### New Load Instructions |
129 | | - |
130 | | -| Instruction | Opcode | Description | |
131 | | -| ----------- | ------ | -------------------------------------- | |
132 | | -| `LdI8` | `0x5B` | Load a signed 8-bit integer constant | |
133 | | -| `LdI16` | `0x5C` | Load a signed 16-bit integer constant | |
134 | | -| `LdI32` | `0x5D` | Load a signed 32-bit integer constant | |
135 | | -| `LdI64` | `0x5E` | Load a signed 64-bit integer constant | |
136 | | -| `LdI128` | `0x5F` | Load a signed 128-bit integer constant | |
137 | | -| `LdI256` | `0x60` | Load a signed 256-bit integer constant | |
138 | | - |
139 | | -### New Cast Instructions |
140 | | - |
141 | | -| Instruction | Opcode | Description | |
142 | | -| ----------- | ------ | ------------------------------- | |
143 | | -| `CastI8` | `0x61` | Cast the top of stack to `i8` | |
144 | | -| `CastI16` | `0x62` | Cast the top of stack to `i16` | |
145 | | -| `CastI32` | `0x63` | Cast the top of stack to `i32` | |
146 | | -| `CastI64` | `0x64` | Cast the top of stack to `i64` | |
147 | | -| `CastI128` | `0x65` | Cast the top of stack to `i128` | |
148 | | -| `CastI256` | `0x66` | Cast the top of stack to `i256` | |
149 | | - |
150 | | -### New Arithmetic Instruction |
151 | | - |
152 | | -| Instruction | Opcode | Description | |
153 | | -| ----------- | ------ | ------------------------------------------------------------------ | |
154 | | -| `Negate` | `0x67` | Arithmetic negation; pops a signed integer and pushes its negation | |
155 | | - |
156 | | -### New Signature Tokens |
157 | | - |
158 | | -Six new signature tokens represent signed integer types in the type system: |
159 | | - |
160 | | -- `I8` -- signed 8-bit integer |
161 | | -- `I16` -- signed 16-bit integer |
162 | | -- `I32` -- signed 32-bit integer |
163 | | -- `I64` -- signed 64-bit integer |
164 | | -- `I128` -- signed 128-bit integer |
165 | | -- `I256` -- signed 256-bit integer |
166 | | - |
167 | | -These tokens appear in function signatures, struct field definitions, and local variable types |
168 | | -wherever signed integers are used. |
169 | | - |
170 | | -### What This Enables |
171 | | - |
172 | | -Signed integers support negative values and two's complement arithmetic, which simplifies |
173 | | -financial calculations, coordinate math, and any domain where negative numbers are natural. |
174 | | -Version 9 is the default bytecode version for the standard Move language configuration. |
175 | | - |
176 | | -## Version 10 |
177 | | - |
178 | | -Version 10 added the **abort-with-message** instruction, which allows a transaction to abort |
179 | | -with a human-readable error string in addition to the numeric abort code. |
180 | | - |
181 | | -### New Instruction |
182 | | - |
183 | | -| Instruction | Opcode | Description | |
184 | | -| ----------- | ------ | ---------------------------------------------------------------------------- | |
185 | | -| `AbortMsg` | `0x68` | Abort execution with a `u64` error code and an optional UTF-8 message string | |
186 | | - |
187 | | -### What This Enables |
188 | | - |
189 | | -Before v10, `abort` only accepted a numeric code, making it difficult to diagnose failures |
190 | | -without consulting the module source. With `AbortMsg`, modules can include descriptive error |
191 | | -messages that appear in transaction output, greatly improving debuggability. Version 10 is the |
192 | | -default bytecode version for Move language v2.4 and v2.5. |
193 | | - |
194 | | -## Compatibility Notes |
195 | | - |
196 | | -- The VM accepts bytecode from **v5 through the current maximum version** (v10 at the time of |
197 | | - writing). Modules compiled at any supported version can coexist on-chain and call each other. |
198 | | -- When a module declares an older bytecode version, the verifier **rejects instructions and types |
199 | | - introduced in later versions**. For example, a module at v6 cannot use `PackVariant` (a v7 |
200 | | - instruction). |
201 | | -- The bytecode version is encoded as a **little-endian `u32`** in bytes 4 through 7 of the module |
202 | | - binary header, immediately after the magic bytes. See the |
203 | | - [Module Binary Format](/build/smart-contracts/bytecode/module-format) page for a full |
204 | | - description of the header layout. |
205 | | -- Publishing a module with a version newer than the VM supports causes the transaction to fail |
206 | | - during verification. |
0 commit comments