@meddleware/token-deployer-ui 0.0.10 → 0.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -5
- package/package.json +19 -8
- package/src/App.vue +1 -1
- package/src/component-styles.css +39 -57
- package/src/components/GithubPush.vue +2 -2
- package/src/components/IconPicker.vue +44 -75
- package/src/components/LicensePicker.vue +2 -2
- package/src/components/ResultPanel.vue +2 -2
- package/src/components/ReviewPanel.vue +11 -3
- package/src/components/TokenDeployerView.vue +52 -48
- package/src/components/WalletBar.vue +12 -1
- package/src/components/WalrusBlobBrowser.vue +4 -4
- package/src/composables/useWalrusRelay.ts +1 -2
- package/src/config.ts +19 -17
- package/src/lib/buildPublishTx.ts +0 -10
- package/src/lib/deploy.ts +9 -3
- package/src/lib/deployExecutor.ts +18 -45
- package/src/lib/template.ts +3 -0
- package/src/lib/walrus-constants.ts +2 -2
- package/src/main.ts +4 -6
- package/src/styles.css +22 -0
- package/.claude/move-language-reference/SKILL.md +0 -445
- package/.claude/skills/move-language-reference/SKILL.md +0 -445
- package/.claude/skills/sui-move-bootcamp/SKILL.md +0 -128
- package/.claude/sui-move-bootcamp/SKILL.md +0 -128
- package/.editorconfig +0 -8
- package/.env.example +0 -72
- package/.gitattributes +0 -1
- package/.github/workflows/docker-publish.yml +0 -348
- package/.github/workflows/e2e-realchain.yml +0 -64
- package/.github/workflows/node-ci.yml +0 -43
- package/.github/workflows/npm-publish.yml +0 -83
- package/.htmlvalidate.mjs +0 -30
- package/.oxfmtrc.json +0 -5
- package/.oxlintrc.json +0 -10
- package/.vscode/extensions.json +0 -9
- package/AGENTS.md +0 -39
- package/CLAUDE.md +0 -166
- package/Dockerfile +0 -96
- package/eslint.config.ts +0 -63
- package/index.html +0 -22
- package/playwright.config.ts +0 -30
- package/postcss.config.js +0 -8
- package/public/CNAME +0 -1
- package/public/_headers +0 -12
- package/public/_redirects +0 -1
- package/public/favicon.ico +0 -0
- package/public/favicon.svg +0 -5
- package/public/og-image.png +0 -0
- package/public/robots.txt +0 -3
- package/public/sitemap.xml +0 -8
- package/scripts/e2e-browser.mjs +0 -15
- package/scripts/e2e-deploy.mjs +0 -227
- package/scripts/e2e-localnet.mjs +0 -67
- package/scripts/e2e-walrus-browser.mjs +0 -112
- package/scripts/gen-og-image.mjs +0 -31
- package/scripts/publish-localnet.mjs +0 -56
- package/scripts/regen-template.sh +0 -45
- package/scripts/sync-template-src.sh +0 -36
- package/scripts/verify-bytecode.mjs +0 -49
- package/src/__tests__/App.spec.js +0 -11
- package/src/composables/useAccessGate.ts +0 -127
- package/src/lib/accessGate.ts +0 -155
- package/src/lib/walrus.ts +0 -155
- package/stylelint.config.js +0 -33
- package/test-results/.last-run.json +0 -4
- package/tests/accessGate.test.ts +0 -113
- package/tests/buildPublishTx.test.ts +0 -243
- package/tests/deploy.test.ts +0 -149
- package/tests/errors.test.ts +0 -32
- package/tests/generatePackage.test.ts +0 -193
- package/tests/github.test.ts +0 -61
- package/tests/licenses.test.ts +0 -81
- package/tests/listMyTokens.test.ts +0 -30
- package/tests/template.test.ts +0 -93
- package/tests/templateArtifact.test.ts +0 -61
- package/tests/templateParity.test.ts +0 -55
- package/tests/useAccessGate.test.ts +0 -97
- package/tests/useWallet.test.ts +0 -74
- package/tests/useWalrusRelayGating.test.ts +0 -30
- package/tests/validation.test.ts +0 -117
- package/tests/walrusUpload.test.ts +0 -93
- package/tests/walrus_url_patch.test.ts +0 -26
- package/tsconfig.json +0 -19
- package/typedoc.json +0 -34
- package/vite.config.ts +0 -73
- package/vitest.config.ts +0 -10
|
@@ -1,445 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: move-language-reference
|
|
3
|
-
description: Deep Move language reference covering type system, control flow, generics, abilities, Move 2024 features, and advanced Sui programmability patterns. Companion to sui-stack-dev:sui-move-development — covers depth not in that skill.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Move Language Reference
|
|
7
|
-
|
|
8
|
-
A deep reference for the Move language, based on the [Move Book](https://move-book.com). This complements `sui-stack-dev:sui-move-development` (which covers practical patterns like object transfer, capabilities, and basic test scenarios) by providing language semantics, type system rules, and advanced programmability patterns.
|
|
9
|
-
|
|
10
|
-
## Primitive Types and Operations
|
|
11
|
-
|
|
12
|
-
### Integers and Math
|
|
13
|
-
|
|
14
|
-
- **Types**: `u8`, `u16`, `u32`, `u64`, `u128`, `u256`
|
|
15
|
-
- **Casts**: `(val as u64)` — cast to different integer type
|
|
16
|
-
- **Overflow**: Arithmetic is checked (panics on overflow); tests can use wrapping arithmetic modules
|
|
17
|
-
- **Literals**: `123u8`, `456u64`, `0x1A2B` (hex)
|
|
18
|
-
|
|
19
|
-
### Boolean and Address
|
|
20
|
-
|
|
21
|
-
- **`bool`**: `true`, `false`; used in conditionals; cannot be cast to/from integers
|
|
22
|
-
- **`address`**: 32-byte identifier; literal form `@0x1234567890abcdef...` (64 hex chars); cast between `u256` via `sui::address::parse_and_verify`
|
|
23
|
-
|
|
24
|
-
### Vector
|
|
25
|
-
|
|
26
|
-
```move
|
|
27
|
-
let mut v = vector[1, 2, 3];
|
|
28
|
-
vector::push_back(&mut v, 4);
|
|
29
|
-
vector::pop_back(&mut v);
|
|
30
|
-
let len = vector::length(&v);
|
|
31
|
-
let ref_elem = vector::borrow(&v, 0);
|
|
32
|
-
let mut_ref = vector::borrow_mut(&mut v, 1);
|
|
33
|
-
vector::remove(&mut v, 0);
|
|
34
|
-
vector::destroy_empty(v);
|
|
35
|
-
let is_empty = vector::is_empty(&v);
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
### References
|
|
39
|
-
|
|
40
|
-
- **Immutable reference** `&T`: read-only borrow; multiple immutable refs allowed
|
|
41
|
-
- **Mutable reference** `&mut T`: exclusive write access; only one active at a time
|
|
42
|
-
- **Dereference**: `*ref` gives the value (if `T: copy`)
|
|
43
|
-
- **Borrow checker**: prevents use-after-move and aliased mutable refs
|
|
44
|
-
|
|
45
|
-
```move
|
|
46
|
-
let x = 10;
|
|
47
|
-
let r1 = &x;
|
|
48
|
-
let r2 = &x; // OK: multiple immutable refs
|
|
49
|
-
let y = &mut x; // ERROR: cannot have mutable while immutable borrows exist
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
## Control Flow
|
|
53
|
-
|
|
54
|
-
### Conditionals
|
|
55
|
-
|
|
56
|
-
```move
|
|
57
|
-
if (condition) {
|
|
58
|
-
// ...
|
|
59
|
-
} else if (other) {
|
|
60
|
-
// ...
|
|
61
|
-
} else {
|
|
62
|
-
// ...
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// Expression form (returns a value)
|
|
66
|
-
let result = if (flag) 1 else 2;
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
### Loops
|
|
70
|
-
|
|
71
|
-
```move
|
|
72
|
-
loop {
|
|
73
|
-
if (done) break;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
while (condition) {
|
|
77
|
-
// ...
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// Labeled loops (break/continue to specific label)
|
|
81
|
-
'outer: loop {
|
|
82
|
-
loop {
|
|
83
|
-
break 'outer; // breaks the outer loop
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
### Pattern Matching (Move 2024)
|
|
89
|
-
|
|
90
|
-
```move
|
|
91
|
-
match (value) {
|
|
92
|
-
Some(x) => x * 2,
|
|
93
|
-
None => 0,
|
|
94
|
-
_ => 99, // catch-all
|
|
95
|
-
}
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
## Error Handling
|
|
99
|
-
|
|
100
|
-
### Abort and Assert
|
|
101
|
-
|
|
102
|
-
```move
|
|
103
|
-
const E_INVALID_AMOUNT: u64 = 1;
|
|
104
|
-
const E_INSUFFICIENT_BALANCE: u64 = 2;
|
|
105
|
-
|
|
106
|
-
assert!(balance >= amount, E_INSUFFICIENT_BALANCE);
|
|
107
|
-
if (!is_valid) abort E_INVALID_AMOUNT;
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
**Convention**: Error constants prefixed with `E_`, uppercase snake_case.
|
|
111
|
-
|
|
112
|
-
**Behavior**: `abort` terminates the transaction immediately; no recovery. Errors are visible in transaction effects.
|
|
113
|
-
|
|
114
|
-
## Generics and Type Parameters
|
|
115
|
-
|
|
116
|
-
### Basic Generics
|
|
117
|
-
|
|
118
|
-
```move
|
|
119
|
-
fun get_first<T>(vec: &vector<T>): &T {
|
|
120
|
-
vector::borrow(vec, 0)
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// Unconstrained: T can be any type (but still movable by default)
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
### Constraints
|
|
127
|
-
|
|
128
|
-
```move
|
|
129
|
-
fun destroy_all<T: drop>(vec: vector<T>) {
|
|
130
|
-
while (vector::length(&vec) > 0) {
|
|
131
|
-
vector::pop_back(&mut vec); // T must have drop
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
struct Container<T: store> has store {
|
|
136
|
-
items: vector<T>
|
|
137
|
-
}
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
**Common constraints**:
|
|
141
|
-
- `T: copy` — can be duplicated
|
|
142
|
-
- `T: drop` — can be discarded
|
|
143
|
-
- `T: store` — can be stored in other objects
|
|
144
|
-
- `T: key` — can be a top-level object (rare)
|
|
145
|
-
- `T: copy + drop + store` — most permissive for data containers
|
|
146
|
-
|
|
147
|
-
### Phantom Types
|
|
148
|
-
|
|
149
|
-
Type parameter not stored as a field; used for type safety without holding a value:
|
|
150
|
-
|
|
151
|
-
```move
|
|
152
|
-
struct Coin<phantom T> has store { amount: u64 }
|
|
153
|
-
|
|
154
|
-
// Coin<SUI> and Coin<USDC> are different types, even though storage is identical
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
## Abilities — Rules in Depth
|
|
158
|
-
|
|
159
|
-
Every struct declares its own abilities; they are not inherited.
|
|
160
|
-
|
|
161
|
-
### `copy`
|
|
162
|
-
|
|
163
|
-
- **Means**: values of this type can be duplicated/copied
|
|
164
|
-
- **Requires**: ALL fields must also have `copy`
|
|
165
|
-
- **Examples**: integers, bools, addresses
|
|
166
|
-
- **Caveat**: `copy` types are automatically copied in function calls; consuming logic must carefully handle this
|
|
167
|
-
|
|
168
|
-
```move
|
|
169
|
-
struct Point has copy { x: u64, y: u64 } // OK: both u64 have copy
|
|
170
|
-
let p1 = Point { x: 1, y: 2 };
|
|
171
|
-
let p2 = p1; // p1 is copied; both exist
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
### `drop`
|
|
175
|
-
|
|
176
|
-
- **Means**: values can be discarded without explicit logic
|
|
177
|
-
- **Requires**: ALL fields must also have `drop`
|
|
178
|
-
- **Examples**: integers, bools
|
|
179
|
-
- **Without `drop`**: must be explicitly consumed (moved into another struct, returned, etc.)
|
|
180
|
-
|
|
181
|
-
```move
|
|
182
|
-
struct Resource has key { id: UID, data: u64 }
|
|
183
|
-
// Resource does NOT have drop (id: UID does not)
|
|
184
|
-
// Must be explicitly destroyed: object::delete(obj)
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
### `store`
|
|
188
|
-
|
|
189
|
-
- **Means**: values can be stored inside other objects (as fields in a `key` struct)
|
|
190
|
-
- **Requires**: ALL fields must also have `store`
|
|
191
|
-
- **Caveat**: only top-level objects need `key`; inner objects need `store`
|
|
192
|
-
|
|
193
|
-
```move
|
|
194
|
-
struct Inventory<T: store> has key {
|
|
195
|
-
id: UID,
|
|
196
|
-
items: vector<T> // T must have store
|
|
197
|
-
}
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
### `key`
|
|
201
|
-
|
|
202
|
-
- **Means**: can be stored as a top-level object at the global level
|
|
203
|
-
- **Requires**: first field MUST be `id: UID`; ALL other fields must have `store`
|
|
204
|
-
- **Caveat**: only one type in a module can be the main object type
|
|
205
|
-
|
|
206
|
-
```move
|
|
207
|
-
struct Account has key {
|
|
208
|
-
id: UID,
|
|
209
|
-
balance: u64, // u64 has store ✓
|
|
210
|
-
items: Bag, // Bag has store ✓
|
|
211
|
-
}
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
## Visibility and Generics
|
|
215
|
-
|
|
216
|
-
### Function Visibility
|
|
217
|
-
|
|
218
|
-
```move
|
|
219
|
-
public fun public_func() { } // callable from any module
|
|
220
|
-
public(package) fun friend() { } // callable from same package only
|
|
221
|
-
fun private_func() { } // private to this module
|
|
222
|
-
entry fun can_be_called() { } // can be called as a PTB move_call
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
### `public(package)` (Move 2024)
|
|
226
|
-
|
|
227
|
-
Like old `friend` declarations; allows inter-module calls within the same package:
|
|
228
|
-
|
|
229
|
-
```move
|
|
230
|
-
// In module utils
|
|
231
|
-
public(package) fun helper() { }
|
|
232
|
-
|
|
233
|
-
// In module main (same package)
|
|
234
|
-
fun caller() {
|
|
235
|
-
utils::helper(); // OK
|
|
236
|
-
}
|
|
237
|
-
```
|
|
238
|
-
|
|
239
|
-
## Move 2024 Edition Features
|
|
240
|
-
|
|
241
|
-
### Method Syntax
|
|
242
|
-
|
|
243
|
-
```move
|
|
244
|
-
// Old style
|
|
245
|
-
object::transfer(obj, addr);
|
|
246
|
-
vector::push_back(&mut v, 99);
|
|
247
|
-
|
|
248
|
-
// New style (method calls)
|
|
249
|
-
obj.transfer(addr);
|
|
250
|
-
v.push_back(99);
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
### Index Syntax
|
|
254
|
-
|
|
255
|
-
```move
|
|
256
|
-
let elem = v[0]; // sugar for *vector::borrow(&v, 0)
|
|
257
|
-
v[1] = new_val; // sugar for *vector::borrow_mut(&mut v, 1) = new_val
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
### Macros
|
|
261
|
-
|
|
262
|
-
```move
|
|
263
|
-
macro fun repeat<T>($val: T, $times: u64): vector<T> {
|
|
264
|
-
let mut result = vector[];
|
|
265
|
-
let mut i = 0;
|
|
266
|
-
while (i < $times) {
|
|
267
|
-
vector::push_back(&mut result, $val);
|
|
268
|
-
i = i + 1;
|
|
269
|
-
}
|
|
270
|
-
result
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
// Called at compile time
|
|
274
|
-
let v = repeat!(42, 5); // expands before runtime
|
|
275
|
-
```
|
|
276
|
-
|
|
277
|
-
### `let ... else` (Move 2024)
|
|
278
|
-
|
|
279
|
-
Early exit pattern:
|
|
280
|
-
|
|
281
|
-
```move
|
|
282
|
-
let Some(x) = opt else { return };
|
|
283
|
-
let Some(y) = other else { abort E_NOT_FOUND };
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
## Advanced Sui Programmability Patterns
|
|
287
|
-
|
|
288
|
-
### Hot Potato
|
|
289
|
-
|
|
290
|
-
Struct with no abilities — forces atomic consumption within a single PTB:
|
|
291
|
-
|
|
292
|
-
```move
|
|
293
|
-
struct Request has drop { // ONLY drop, no copy/store/key
|
|
294
|
-
id: UID,
|
|
295
|
-
value: u64,
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
public fun create_request(value: u64, ctx: &mut TxContext): Request {
|
|
299
|
-
Request { id: object::new(ctx), value }
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
public fun approve_request(req: Request) { // takes ownership
|
|
303
|
-
// Must be called same TX; cannot be stored or copied
|
|
304
|
-
}
|
|
305
|
-
```
|
|
306
|
-
|
|
307
|
-
### Flashloan
|
|
308
|
-
|
|
309
|
-
Borrow and return within one transaction:
|
|
310
|
-
|
|
311
|
-
```move
|
|
312
|
-
public fun borrow<T: store>(vault: &mut Vault<T>, amount: u64): (T, Receipt<T>) {
|
|
313
|
-
let asset = // ... extract amount
|
|
314
|
-
let receipt = Receipt { vault_id: object::uid_to_inner(&vault.id), amount };
|
|
315
|
-
(asset, receipt)
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
public fun repay<T: store>(vault: &mut Vault<T>, asset: T, receipt: Receipt<T>) {
|
|
319
|
-
assert!(receipt.vault_id == object::uid_to_inner(&vault.id), E_WRONG_VAULT);
|
|
320
|
-
// ... return asset to vault
|
|
321
|
-
}
|
|
322
|
-
// If Receipt is not consumed, transaction aborts
|
|
323
|
-
```
|
|
324
|
-
|
|
325
|
-
### Coin Standard
|
|
326
|
-
|
|
327
|
-
```move
|
|
328
|
-
use sui::coin::{Coin, Balance};
|
|
329
|
-
|
|
330
|
-
// Coin<T> is a wrapper around Balance<T>
|
|
331
|
-
struct Coin<T> has store, key {
|
|
332
|
-
id: UID,
|
|
333
|
-
balance: Balance<T>
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
// Combine coins
|
|
337
|
-
public fun join<T>(coin1: &mut Coin<T>, coin2: Coin<T>) {
|
|
338
|
-
let Coin { id, balance } = coin2;
|
|
339
|
-
object::delete(id);
|
|
340
|
-
balance::join(&mut coin1.balance, balance);
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
// Split coin
|
|
344
|
-
public fun split<T>(coin: &mut Coin<T>, amount: u64, ctx: &mut TxContext): Coin<T> {
|
|
345
|
-
let balance = balance::split(&mut coin.balance, amount);
|
|
346
|
-
Coin { id: object::new(ctx), balance }
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
// Minting and burning require TreasuryCap
|
|
350
|
-
public fun mint<T>(cap: &mut TreasuryCap<T>, amount: u64, ctx: &mut TxContext): Coin<T> {
|
|
351
|
-
Coin {
|
|
352
|
-
id: object::new(ctx),
|
|
353
|
-
balance: balance::increase_supply(&mut cap.supply, amount),
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
public fun burn<T>(cap: &mut TreasuryCap<T>, coin: Coin<T>) {
|
|
358
|
-
let Coin { id, balance } = coin;
|
|
359
|
-
object::delete(id);
|
|
360
|
-
balance::decrease_supply(&mut cap.supply, balance);
|
|
361
|
-
}
|
|
362
|
-
```
|
|
363
|
-
|
|
364
|
-
### Display Objects
|
|
365
|
-
|
|
366
|
-
Metadata templates for UI rendering:
|
|
367
|
-
|
|
368
|
-
```move
|
|
369
|
-
use sui::display::Display;
|
|
370
|
-
|
|
371
|
-
public fun new<T: key>(pub: &Publisher, ctx: &mut TxContext): Display<T> {
|
|
372
|
-
let mut display = display::new<T>(pub, ctx);
|
|
373
|
-
display.add(b"name", b"{name}");
|
|
374
|
-
display.add(b"description", b"{description}");
|
|
375
|
-
display.add(b"image_url", b"{image_url}");
|
|
376
|
-
display.update_version(); // must call after changes
|
|
377
|
-
display
|
|
378
|
-
}
|
|
379
|
-
```
|
|
380
|
-
|
|
381
|
-
### Kiosk and Transfer Policies
|
|
382
|
-
|
|
383
|
-
Personal marketplaces with enforced transfer rules:
|
|
384
|
-
|
|
385
|
-
```move
|
|
386
|
-
public fun create_kiosk(ctx: &mut TxContext): (Kiosk, KioskOwnerCap) {
|
|
387
|
-
kiosk::new(ctx)
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
public fun place<T: key + store>(kiosk: &mut Kiosk, item: T, cap: &KioskOwnerCap) {
|
|
391
|
-
kiosk::place(kiosk, cap, item)
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
public fun list<T: key + store>(
|
|
395
|
-
kiosk: &mut Kiosk,
|
|
396
|
-
cap: &KioskOwnerCap,
|
|
397
|
-
item_id: ID,
|
|
398
|
-
price: u64,
|
|
399
|
-
) {
|
|
400
|
-
kiosk::list(kiosk, cap, item_id, price)
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
// TransferPolicy enforces rules on all transfers of type T
|
|
404
|
-
public fun create_policy<T: key + store>(pub: &Publisher, ctx: &mut TxContext): TransferPolicy<T> {
|
|
405
|
-
transfer_policy::new(pub, ctx)
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
public fun add_rule<T: key + store>(policy: &mut TransferPolicy<T>, rule_data: u64) {
|
|
409
|
-
// e.g., add royalty, allowlist, burn-on-transfer rules
|
|
410
|
-
}
|
|
411
|
-
```
|
|
412
|
-
|
|
413
|
-
### Data Structure Choices
|
|
414
|
-
|
|
415
|
-
- **`Table<K, V>`** where `K: copy+drop+store`: large homogeneous KV; efficient random access
|
|
416
|
-
- **`Bag`**: heterogeneous values (any `T`); keys must have `copy+drop+store`
|
|
417
|
-
- **`ObjectTable<K, V>`** where `V: key+store`: values are objects; enables object field access
|
|
418
|
-
- **`LinkedTable<K, V>`**: ordered traversal with `prev`/`next` links; supports range iteration
|
|
419
|
-
|
|
420
|
-
### Package Upgrades
|
|
421
|
-
|
|
422
|
-
```move
|
|
423
|
-
// At init:
|
|
424
|
-
public fun init(ctx: &mut TxContext) {
|
|
425
|
-
transfer::transfer(UpgradeCap { id: object::new(ctx) }, ctx.sender());
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
// To upgrade:
|
|
429
|
-
// 1. Modify package code
|
|
430
|
-
// 2. Run: sui client upgrade --package-id 0x... --upgrade-cap 0x... --gas-budget 100000000
|
|
431
|
-
// 3. By default, additive-only: cannot remove/change existing public functions
|
|
432
|
-
|
|
433
|
-
// To make immutable (no future upgrades):
|
|
434
|
-
public fun make_immutable(cap: UpgradeCap) {
|
|
435
|
-
package::make_immutable(cap);
|
|
436
|
-
}
|
|
437
|
-
```
|
|
438
|
-
|
|
439
|
-
---
|
|
440
|
-
|
|
441
|
-
## Reference
|
|
442
|
-
|
|
443
|
-
For the complete Move Book, see [https://move-book.com](https://move-book.com)
|
|
444
|
-
|
|
445
|
-
For Sui-specific APIs and patterns, refer to the Sui framework docs.
|