@btc-vision/btc-runtime 1.4.7 → 1.5.0

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.
Files changed (59) hide show
  1. package/package.json +44 -53
  2. package/runtime/abort/abort.ts +25 -0
  3. package/runtime/buffer/BytesReader.ts +171 -140
  4. package/runtime/buffer/BytesWriter.ts +120 -152
  5. package/runtime/contracts/DeployableOP_20.ts +29 -15
  6. package/runtime/contracts/OP_NET.ts +1 -1
  7. package/runtime/env/BlockchainEnvironment.ts +79 -137
  8. package/runtime/env/classes/Block.ts +4 -8
  9. package/runtime/env/classes/Transaction.ts +14 -7
  10. package/runtime/env/classes/UTXO.ts +4 -2
  11. package/runtime/env/global.ts +49 -20
  12. package/runtime/events/predefined/MintEvent.ts +1 -1
  13. package/runtime/exports/index.ts +29 -8
  14. package/runtime/generic/AddressMap.ts +7 -5
  15. package/runtime/generic/Map.ts +32 -2
  16. package/runtime/generic/MapU256.ts +7 -5
  17. package/runtime/generic/MapUint8Array.ts +93 -0
  18. package/runtime/index.ts +4 -12
  19. package/runtime/math/abi.ts +71 -11
  20. package/runtime/math/bytes.ts +177 -41
  21. package/runtime/memory/AddressMemoryMap.ts +22 -19
  22. package/runtime/memory/FastUint8Array.ts +122 -0
  23. package/runtime/memory/KeyMerger.ts +25 -23
  24. package/runtime/memory/MultiAddressMemoryMap.ts +11 -8
  25. package/runtime/memory/MultiStringMemoryMap.ts +8 -5
  26. package/runtime/memory/StringMemoryMap.ts +15 -15
  27. package/runtime/memory/Uint8ArrayMerger.ts +22 -15
  28. package/runtime/storage/Serializable.ts +19 -20
  29. package/runtime/storage/StoredAddress.ts +16 -15
  30. package/runtime/storage/StoredBoolean.ts +26 -21
  31. package/runtime/storage/StoredString.ts +158 -102
  32. package/runtime/storage/StoredU256.ts +25 -28
  33. package/runtime/storage/StoredU64.ts +23 -35
  34. package/runtime/storage/arrays/StoredAddressArray.ts +83 -175
  35. package/runtime/storage/arrays/StoredBooleanArray.ts +146 -271
  36. package/runtime/storage/arrays/StoredPackedArray.ts +313 -0
  37. package/runtime/storage/arrays/StoredU128Array.ts +38 -374
  38. package/runtime/storage/arrays/StoredU16Array.ts +34 -420
  39. package/runtime/storage/arrays/StoredU256Array.ts +21 -347
  40. package/runtime/storage/arrays/StoredU32Array.ts +37 -440
  41. package/runtime/storage/arrays/StoredU64Array.ts +66 -0
  42. package/runtime/storage/arrays/StoredU8Array.ts +29 -453
  43. package/runtime/types/Address.ts +72 -5
  44. package/runtime/types/index.ts +1 -4
  45. package/runtime/utils/encodings.ts +5 -6
  46. package/runtime/utils/hex.ts +1 -1
  47. package/runtime/interfaces/DeployContractResponse.ts +0 -12
  48. package/runtime/math/cyrb53.ts +0 -48
  49. package/runtime/math/sha256.ts +0 -12
  50. package/runtime/memory/MemorySlot.ts +0 -1
  51. package/runtime/memory/MemorySlotPointer.ts +0 -3
  52. package/runtime/storage/utils/StorageBacked.ts +0 -5
  53. package/runtime/storage/utils/StorageLayout.ts +0 -7
  54. package/runtime/storage/utils/StorageSlot.ts +0 -106
  55. package/runtime/storage/utils/StorageStruct.ts +0 -23
  56. package/runtime/storage/utils/StorageValue.ts +0 -36
  57. package/runtime/tests/assert.ts +0 -11
  58. package/runtime/tests/env.ts +0 -7
  59. package/runtime/tests/tests.ts +0 -28
@@ -1,460 +1,57 @@
1
- import { u256 } from '@btc-vision/as-bignum/assembly';
2
- import { Blockchain } from '../../env';
3
- import { BytesWriter } from '../../buffer/BytesWriter';
4
- import { SafeMath } from '../../types/SafeMath';
5
- import { Revert } from '../../types/Revert';
1
+ import { StoredPackedArray } from './StoredPackedArray';
2
+ import { bigEndianAdd } from '../../math/bytes';
6
3
 
7
4
  /**
8
- * @class StoredU32Array
9
- * @description Manages an array of u32 values across multiple storage slots.
10
- * Each slot holds **eight** u32 values packed into a single u256.
5
+ * StoredU32Array
6
+ * - 8 items of type `u32` fit in one 32-byte slot.
11
7
  */
12
8
  @final
13
- export class StoredU32Array {
14
- private readonly baseU256Pointer: u256;
15
- private readonly lengthPointer: u256;
16
-
17
- // Internal cache for storage slots
18
- private _values: Map<u64, u32[]> = new Map(); // Map from slotIndex to array of eight u32s
19
- private _isLoaded: Set<u64> = new Set(); // Set of slotIndexes that are loaded
20
- private _isChanged: Set<u64> = new Set(); // Set of slotIndexes that are modified
21
-
22
- // Internal variables for length and startIndex management
23
- private _length: u64 = 0; // Current length of the array
24
- private _startIndex: u64 = 0; // Starting index of the array
25
- private _isChangedLength: bool = false; // Indicates if the length has been modified
26
- private _isChangedStartIndex: bool = false; // Indicates if the startIndex has been modified
27
-
28
- // Define a maximum allowed length to prevent excessive storage usage
29
- private readonly MAX_LENGTH: u64 = u64(u32.MAX_VALUE - 1);
30
-
31
- /**
32
- * @constructor
33
- * @param {u16} pointer - The primary pointer identifier.
34
- * @param {Uint8Array} subPointer - The sub-pointer for memory slot addressing.
35
- * @param {u256} defaultValue - The default u256 value if storage is uninitialized.
36
- */
37
- constructor(
38
- public pointer: u16,
39
- public subPointer: Uint8Array,
40
- private defaultValue: u256,
41
- ) {
42
- // Initialize the base pointer using the primary pointer and subPointer
43
- const writer = new BytesWriter(32);
44
- writer.writeU16(pointer);
45
- writer.writeBytes(subPointer);
46
-
47
- const baseU256Pointer = u256.fromBytes(writer.getBuffer(), true);
48
- this.baseU256Pointer = baseU256Pointer;
49
-
50
- // We’ll reuse the same pointer for length & startIndex
51
- const lengthPointer = baseU256Pointer.clone();
52
- this.lengthPointer = lengthPointer;
53
-
54
- // Load current length + startIndex from storage
55
- const storedLengthAndStartIndex: u256 = Blockchain.getStorageAt(lengthPointer, u256.Zero);
56
- this._length = storedLengthAndStartIndex.lo1; // Bytes 0-7: length (u64)
57
- this._startIndex = storedLengthAndStartIndex.lo2; // Bytes 8-15: startIndex (u64)
9
+ export class StoredU32Array extends StoredPackedArray<u32> {
10
+ public constructor(pointer: u16, subPointer: Uint8Array) {
11
+ super(pointer, subPointer);
58
12
  }
59
13
 
60
- /**
61
- * @method get
62
- * @description Retrieves the u32 value at the specified global index.
63
- * @param {u64} index - The global index (0 to ∞) of the u32 value to retrieve.
64
- * @returns {u32} - The u32 value at the specified index.
65
- */
66
- @inline
67
- public get(index: u64): u32 {
68
- if (index > this.MAX_LENGTH) {
69
- throw new Revert('Operation failed: Index exceeds maximum allowed value.');
70
- }
71
-
72
- const slotIndex: u64 = index / 8; // Each slot holds 8 u32s
73
- const subIndex: u8 = <u8>(index % 8); // 0..7
74
-
75
- this.ensureValues(slotIndex);
76
-
77
- const slotValues = this._values.get(slotIndex);
78
- return slotValues ? slotValues[subIndex] : 0;
14
+ protected getSlotCapacity(): u64 {
15
+ return 8; // 8 x u32 => 32 bytes
79
16
  }
80
17
 
81
- /**
82
- * @method set
83
- * @description Sets the u32 value at the specified global index.
84
- * @param {u64} index - The global index (0 to ∞) of the u32 value to set.
85
- * @param {u32} value - The u32 value to assign.
86
- */
87
- @inline
88
- public set(index: u64, value: u32): void {
89
- if (index > this.MAX_LENGTH) {
90
- throw new Revert('Set operation failed: Index exceeds maximum allowed value.');
91
- }
92
-
93
- const slotIndex: u64 = index / 8;
94
- const subIndex: u8 = <u8>(index % 8);
95
-
96
- this.ensureValues(slotIndex);
97
- const slotValues = this._values.get(slotIndex);
98
- if (slotValues && slotValues[subIndex] !== value) {
99
- slotValues[subIndex] = value;
100
- this._isChanged.add(slotIndex);
101
- }
18
+ protected zeroValue(): u32 {
19
+ return 0;
102
20
  }
103
21
 
104
- /**
105
- * @method push
106
- * @description Appends a new u32 value to the end of the array.
107
- * @param {u32} value - The u32 value to append.
108
- */
109
- public push(value: u32): void {
110
- if (this._length > this.MAX_LENGTH) {
111
- throw new Revert(
112
- 'Push operation failed: Array has reached its maximum allowed length.',
113
- );
114
- }
115
-
116
- const newIndex: u64 = this._length;
117
- const wrappedIndex: u64 =
118
- newIndex < this.MAX_LENGTH ? newIndex : newIndex % this.MAX_LENGTH;
119
-
120
- const slotIndex: u64 = wrappedIndex / 8;
121
- const subIndex: u8 = <u8>(wrappedIndex % 8);
122
-
123
- // Ensure the slot is loaded
124
- this.ensureValues(slotIndex);
125
-
126
- // Set the new value
127
- const slotValues = this._values.get(slotIndex);
128
- if (slotValues) {
129
- slotValues[subIndex] = value;
130
- this._isChanged.add(slotIndex);
131
- }
132
-
133
- // Increment the length
134
- this._length += 1;
135
- this._isChangedLength = true;
22
+ protected eq(a: u32, b: u32): bool {
23
+ return a == b;
136
24
  }
137
25
 
138
- /**
139
- * @method delete
140
- * @description Deletes the u32 value at the specified index by setting it to zero (does not reorder).
141
- * @param {u64} index - The global index of the u32 value to delete.
142
- */
143
- public delete(index: u64): void {
144
- if (index > this.MAX_LENGTH) {
145
- throw new Revert('Operation failed: Index exceeds maximum allowed value.');
26
+ protected packSlot(values: u32[]): Uint8Array {
27
+ const out = new Uint8Array(32);
28
+ let offset = 0;
29
+ for (let i = 0; i < 8; i++) {
30
+ const v = values[i];
31
+ out[offset] = <u8>((v >> 24) & 0xff);
32
+ out[offset + 1] = <u8>((v >> 16) & 0xff);
33
+ out[offset + 2] = <u8>((v >> 8) & 0xff);
34
+ out[offset + 3] = <u8>(v & 0xff);
35
+ offset += 4;
146
36
  }
147
-
148
- const slotIndex: u64 = index / 8;
149
- const subIndex: u8 = <u8>(index % 8);
150
- this.ensureValues(slotIndex);
151
-
152
- const slotValues = this._values.get(slotIndex);
153
- if (slotValues && slotValues[subIndex] !== 0) {
154
- slotValues[subIndex] = 0;
155
- this._isChanged.add(slotIndex);
156
- }
157
- }
158
-
159
- /**
160
- * @method shift
161
- * @description Removes the first element of the array by zeroing it out, decrementing length,
162
- * and incrementing the startIndex (with wrap-around).
163
- */
164
- public shift(): void {
165
- if (this._length === 0) {
166
- throw new Revert('Shift operation failed: Array is empty.');
167
- }
168
-
169
- const currentStartIndex: u64 = this._startIndex;
170
- const slotIndex: u64 = currentStartIndex / 8;
171
- const subIndex: u8 = <u8>(currentStartIndex % 8);
172
-
173
- this.ensureValues(slotIndex);
174
- const slotValues = this._values.get(slotIndex);
175
- if (slotValues && slotValues[subIndex] !== 0) {
176
- slotValues[subIndex] = 0;
177
- this._isChanged.add(slotIndex);
178
- }
179
-
180
- // Decrement length
181
- this._length -= 1;
182
- this._isChangedLength = true;
183
-
184
- // Increment startIndex with wrap-around
185
- if (this._startIndex < this.MAX_LENGTH - 1) {
186
- this._startIndex += 1;
187
- } else {
188
- this._startIndex = 0;
189
- }
190
- this._isChangedStartIndex = true;
191
- }
192
-
193
- /**
194
- * @method save
195
- * @description Persists all modified slots and the current length/startIndex into storage.
196
- */
197
- public save(): void {
198
- // Save changed slots
199
- const changedSlots = this._isChanged.values();
200
- for (let i = 0; i < changedSlots.length; i++) {
201
- const slotIndex = changedSlots[i];
202
- const packed = this.packValues(slotIndex);
203
- const storagePointer = this.calculateStoragePointer(slotIndex);
204
- Blockchain.setStorageAt(storagePointer, packed);
205
- }
206
- this._isChanged.clear();
207
-
208
- // Save length + startIndex if changed
209
- if (this._isChangedLength || this._isChangedStartIndex) {
210
- const packedLengthAndStartIndex = new u256();
211
- packedLengthAndStartIndex.lo1 = this._length;
212
- packedLengthAndStartIndex.lo2 = this._startIndex;
213
-
214
- Blockchain.setStorageAt(this.lengthPointer, packedLengthAndStartIndex);
215
- this._isChangedLength = false;
216
- this._isChangedStartIndex = false;
217
- }
218
- }
219
-
220
- /**
221
- * @method deleteAll
222
- * @description Deletes all storage slots and resets length/startIndex to zero.
223
- */
224
- public deleteAll(): void {
225
- // Clear loaded slots from storage
226
- const keys = this._values.keys();
227
- for (let i = 0; i < keys.length; i++) {
228
- const slotIndex = keys[i];
229
- const storagePointer = this.calculateStoragePointer(slotIndex);
230
- Blockchain.setStorageAt(storagePointer, u256.Zero);
231
- }
232
-
233
- // Reset length + startIndex
234
- Blockchain.setStorageAt(this.lengthPointer, u256.Zero);
235
- this._length = 0;
236
- this._startIndex = 0;
237
- this._isChangedLength = false;
238
- this._isChangedStartIndex = false;
239
-
240
- // Clear caches
241
- this._values.clear();
242
- this._isLoaded.clear();
243
- this._isChanged.clear();
37
+ return out;
244
38
  }
245
39
 
246
- /**
247
- * @method setMultiple
248
- * @description Sets multiple u32 values starting at a given global index.
249
- * @param {u64} startIndex - The starting global index.
250
- * @param {u32[]} values - The array of u32 values to set.
251
- */
252
- @inline
253
- public setMultiple(startIndex: u64, values: u32[]): void {
254
- for (let i: u64 = 0; i < values.length; i++) {
255
- this.set(startIndex + i, values[i]);
40
+ protected unpackSlot(slotData: Uint8Array): u32[] {
41
+ const out = new Array<u32>(8);
42
+ let offset = 0;
43
+ for (let i = 0; i < 8; i++) {
44
+ const b0 = slotData[offset];
45
+ const b1 = slotData[offset + 1];
46
+ const b2 = slotData[offset + 2];
47
+ const b3 = slotData[offset + 3];
48
+ out[i] = ((<u32>b0 << 24) | (<u32>b1 << 16) | (<u32>b2 << 8) | b3) as u32;
49
+ offset += 4;
256
50
  }
51
+ return out;
257
52
  }
258
53
 
259
- /**
260
- * @method getAll
261
- * @description Retrieves a consecutive range of u32 values starting at a given global index.
262
- * @param {u64} startIndex - The starting global index.
263
- * @param {u64} count - The number of u32 values to retrieve.
264
- * @returns {u32[]} - The requested slice of the array.
265
- */
266
- @inline
267
- public getAll(startIndex: u64, count: u64): u32[] {
268
- if ((startIndex + count) > this._length) {
269
- throw new Revert('Requested range exceeds array length');
270
- }
271
-
272
- if (u32.MAX_VALUE < count) {
273
- throw new Revert('Requested range exceeds maximum allowed value.');
274
- }
275
-
276
- const result: u32[] = new Array<u32>(count as u32);
277
- for (let i: u64 = 0; i < count; i++) {
278
- result[i as u32] = this.get(startIndex + i);
279
- }
280
- return result;
281
- }
282
-
283
- /**
284
- * @method toString
285
- * @description Returns a string representation of all cached u32 values.
286
- * @returns {string} - A string in the format "[val0, val1, ..., valN]".
287
- */
288
- @inline
289
- public toString(): string {
290
- let str = '[';
291
- for (let i: u64 = 0; i < this._length; i++) {
292
- const value = this.get(i);
293
- str += value.toString();
294
- if (i !== this._length - 1) {
295
- str += ', ';
296
- }
297
- }
298
- str += ']';
299
- return str;
300
- }
301
-
302
- /**
303
- * @method toBytes
304
- * @description Packs all cached slots into u256 and returns them as a byte array.
305
- * @returns {u8[]} - The packed u256 values in byte form.
306
- */
307
- @inline
308
- public toBytes(): u8[] {
309
- const bytes: u8[] = new Array<u8>();
310
- const slotCount: u64 = (this._length + 7) / 8; // each slot has 8 values
311
-
312
- for (let slotIndex: u64 = 0; slotIndex < slotCount; slotIndex++) {
313
- this.ensureValues(slotIndex);
314
- const packed = this.packValues(slotIndex);
315
- const slotBytes = packed.toBytes();
316
- for (let i: u32 = 0; i < slotBytes.length; i++) {
317
- bytes.push(slotBytes[i]);
318
- }
319
- }
320
- return bytes;
321
- }
322
-
323
- /**
324
- * @method reset
325
- * @description Zeros out the entire array and resets length/startIndex to zero, persisting changes immediately.
326
- */
327
- @inline
328
- public reset(): void {
329
- this._length = 0;
330
- this._startIndex = 0;
331
- this._isChangedLength = true;
332
- this._isChangedStartIndex = true;
333
- this.save();
334
- }
335
-
336
- /**
337
- * @method getLength
338
- * @description Returns the current length of the array.
339
- * @returns {u64} - The length.
340
- */
341
- @inline
342
- public getLength(): u64 {
343
- return this._length;
344
- }
345
-
346
- /**
347
- * @method startingIndex
348
- * @description Returns the current starting index of the array.
349
- * @returns {u64} - The startIndex.
350
- */
351
- @inline
352
- public startingIndex(): u64 {
353
- return this._startIndex;
354
- }
355
-
356
- /**
357
- * @method deleteLast
358
- * @description Deletes the last element of the array by setting it to zero and decrementing the length.
359
- */
360
- public deleteLast(): void {
361
- if (this._length === 0) {
362
- throw new Revert('DeleteLast operation failed: Array is empty.');
363
- }
364
-
365
- const index = this._length - 1;
366
- this.delete(index);
367
-
368
- this._length -= 1;
369
- this._isChangedLength = true;
370
- }
371
-
372
- /**
373
- * @private
374
- * @method ensureValues
375
- * @description Loads the slot data from storage if not already in cache.
376
- * @param {u64} slotIndex - The slot index.
377
- */
378
- private ensureValues(slotIndex: u64): void {
379
- if (!this._isLoaded.has(slotIndex)) {
380
- const storagePointer = this.calculateStoragePointer(slotIndex);
381
- const storedU256: u256 = Blockchain.getStorageAt(storagePointer, this.defaultValue);
382
- const slotValues = this.unpackU256(storedU256);
383
- this._values.set(slotIndex, slotValues);
384
- this._isLoaded.add(slotIndex);
385
- }
386
- }
387
-
388
- /**
389
- * @private
390
- * @method packValues
391
- * @description Packs eight u32 values into a single u256 (lo1, lo2, hi1, hi2).
392
- * @param {u64} slotIndex - The slot index.
393
- * @returns {u256} - The packed u256.
394
- */
395
- private packValues(slotIndex: u64): u256 {
396
- const values = this._values.get(slotIndex);
397
- if (!values) {
398
- return u256.Zero;
399
- }
400
- const packed = new u256();
401
-
402
- // Each 64 bits can store two u32:
403
- // lo1 = (values[0], values[1])
404
- // lo2 = (values[2], values[3])
405
- // hi1 = (values[4], values[5])
406
- // hi2 = (values[6], values[7])
407
-
408
- // Pack into lo1
409
- packed.lo1 = (u64(values[0]) << 32) | (u64(values[1]) & 0xffffffff);
410
-
411
- // Pack into lo2
412
- packed.lo2 = (u64(values[2]) << 32) | (u64(values[3]) & 0xffffffff);
413
-
414
- // Pack into hi1
415
- packed.hi1 = (u64(values[4]) << 32) | (u64(values[5]) & 0xffffffff);
416
-
417
- // Pack into hi2
418
- packed.hi2 = (u64(values[6]) << 32) | (u64(values[7]) & 0xffffffff);
419
-
420
- return packed;
421
- }
422
-
423
- /**
424
- * @private
425
- * @method unpackU256
426
- * @description Unpacks a u256 into an array of eight u32 values.
427
- * @param {u256} storedU256 - The stored u256 data.
428
- * @returns {u32[]} - The array of eight u32s.
429
- */
430
- private unpackU256(storedU256: u256): u32[] {
431
- const values: u32[] = new Array<u32>(8);
432
-
433
- // Extract each pair of u32 from lo1, lo2, hi1, hi2
434
- values[0] = u32(storedU256.lo1 >> 32);
435
- values[1] = u32(storedU256.lo1 & 0xffffffff);
436
-
437
- values[2] = u32(storedU256.lo2 >> 32);
438
- values[3] = u32(storedU256.lo2 & 0xffffffff);
439
-
440
- values[4] = u32(storedU256.hi1 >> 32);
441
- values[5] = u32(storedU256.hi1 & 0xffffffff);
442
-
443
- values[6] = u32(storedU256.hi2 >> 32);
444
- values[7] = u32(storedU256.hi2 & 0xffffffff);
445
-
446
- return values;
447
- }
448
-
449
- /**
450
- * @private
451
- * @method calculateStoragePointer
452
- * @description Derives the storage pointer for a slot index by adding (slotIndex + 1) to the base pointer.
453
- * @param {u64} slotIndex - The slot index.
454
- * @returns {u256} - The resulting storage pointer.
455
- */
456
- private calculateStoragePointer(slotIndex: u64): u256 {
457
- // We offset by +1 so we don't collide with the length pointer (stored at basePointer itself).
458
- return SafeMath.add(this.baseU256Pointer, u256.fromU64(slotIndex + 1));
54
+ protected calculateStoragePointer(slotIndex: u64): Uint8Array {
55
+ return bigEndianAdd(this.basePointer, slotIndex + 1);
459
56
  }
460
57
  }
@@ -0,0 +1,66 @@
1
+ import { StoredPackedArray } from './StoredPackedArray';
2
+ import { bigEndianAdd } from '../../math/bytes';
3
+
4
+ /**
5
+ * StoredU64Array
6
+ * - 4 items of type `u64` fit in one 32-byte slot.
7
+ */
8
+ @final
9
+ export class StoredU64Array extends StoredPackedArray<u64> {
10
+ public constructor(pointer: u16, subPointer: Uint8Array) {
11
+ super(pointer, subPointer);
12
+ }
13
+
14
+ protected getSlotCapacity(): u64 {
15
+ return 4; // 4 x u64 => 32 bytes
16
+ }
17
+
18
+ protected zeroValue(): u64 {
19
+ return 0;
20
+ }
21
+
22
+ protected eq(a: u64, b: u64): bool {
23
+ return a == b;
24
+ }
25
+
26
+ protected packSlot(values: u64[]): Uint8Array {
27
+ const out = new Uint8Array(32);
28
+ let offset = 0;
29
+ for (let i = 0; i < 4; i++) {
30
+ const v = values[i];
31
+ out[offset] = <u8>((v >> 56) & 0xff);
32
+ out[offset + 1] = <u8>((v >> 48) & 0xff);
33
+ out[offset + 2] = <u8>((v >> 40) & 0xff);
34
+ out[offset + 3] = <u8>((v >> 32) & 0xff);
35
+ out[offset + 4] = <u8>((v >> 24) & 0xff);
36
+ out[offset + 5] = <u8>((v >> 16) & 0xff);
37
+ out[offset + 6] = <u8>((v >> 8) & 0xff);
38
+ out[offset + 7] = <u8>(v & 0xff);
39
+ offset += 8;
40
+ }
41
+ return out;
42
+ }
43
+
44
+ protected unpackSlot(slotData: Uint8Array): u64[] {
45
+ const out = new Array<u64>(4);
46
+ let offset = 0;
47
+ for (let i = 0; i < 4; i++) {
48
+ const b0 = <u64>slotData[offset];
49
+ const b1 = <u64>slotData[offset + 1];
50
+ const b2 = <u64>slotData[offset + 2];
51
+ const b3 = <u64>slotData[offset + 3];
52
+ const b4 = <u64>slotData[offset + 4];
53
+ const b5 = <u64>slotData[offset + 5];
54
+ const b6 = <u64>slotData[offset + 6];
55
+ const b7 = <u64>slotData[offset + 7];
56
+ out[i] = (b0 << 56) | (b1 << 48) | (b2 << 40) | (b3 << 32) |
57
+ (b4 << 24) | (b5 << 16) | (b6 << 8) | b7;
58
+ offset += 8;
59
+ }
60
+ return out;
61
+ }
62
+
63
+ protected calculateStoragePointer(slotIndex: u64): Uint8Array {
64
+ return bigEndianAdd(this.basePointer, slotIndex + 1);
65
+ }
66
+ }