@btc-vision/btc-runtime 1.5.6 → 1.5.8
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/package.json +44 -44
- package/runtime/buffer/BytesReader.ts +2 -0
- package/runtime/contracts/DeployableOP_20.ts +1 -1
- package/runtime/contracts/OP_20.ts +1 -1
- package/runtime/env/BlockchainEnvironment.ts +13 -20
- package/runtime/env/global.ts +1 -1
- package/runtime/storage/arrays/StoredPackedArray.ts +105 -9
- package/runtime/storage/arrays/StoredU128Array.ts +1 -1
- package/runtime/storage/arrays/StoredU16Array.ts +1 -1
- package/runtime/storage/arrays/StoredU256Array.ts +1 -1
- package/runtime/storage/arrays/StoredU32Array.ts +1 -1
- package/runtime/storage/arrays/StoredU64Array.ts +1 -1
- package/runtime/storage/arrays/StoredU8Array.ts +1 -1
package/package.json
CHANGED
|
@@ -1,46 +1,46 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
2
|
+
"name": "@btc-vision/btc-runtime",
|
|
3
|
+
"version": "1.5.8",
|
|
4
|
+
"description": "Bitcoin Smart Contract Runtime",
|
|
5
|
+
"main": "btc/index.ts",
|
|
6
|
+
"scripts": {},
|
|
7
|
+
"types": "btc/index.ts",
|
|
8
|
+
"keywords": [
|
|
9
|
+
"bitcoin",
|
|
10
|
+
"smart",
|
|
11
|
+
"contract",
|
|
12
|
+
"runtime",
|
|
13
|
+
"opnet",
|
|
14
|
+
"OP_NET"
|
|
15
|
+
],
|
|
16
|
+
"homepage": "https://opnet.org",
|
|
17
|
+
"author": "BlobMaster41",
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"@types/node": "^22.14.0",
|
|
21
|
+
"assemblyscript": "^0.27.35"
|
|
22
|
+
},
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "https://github.com/btc-vision/btc-runtime"
|
|
26
|
+
},
|
|
27
|
+
"type": "module",
|
|
28
|
+
"files": [
|
|
29
|
+
"package.json",
|
|
30
|
+
"runtime",
|
|
31
|
+
"runtime/*.ts",
|
|
32
|
+
"runtime/**/*.ts",
|
|
33
|
+
"!**/*.js.map",
|
|
34
|
+
"!**/*.tsbuildinfo",
|
|
35
|
+
"test/*.ts"
|
|
36
|
+
],
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@assemblyscript/loader": "^0.27.35",
|
|
39
|
+
"@btc-vision/as-bignum": "^0.0.5",
|
|
40
|
+
"@eslint/js": "^9.24.0",
|
|
41
|
+
"gulplog": "^2.2.0",
|
|
42
|
+
"ts-node": "^10.9.2",
|
|
43
|
+
"typescript": "^5.8.3",
|
|
44
|
+
"typescript-eslint": "^8.29.1"
|
|
45
|
+
}
|
|
46
46
|
}
|
|
@@ -233,6 +233,8 @@ export class BytesReader {
|
|
|
233
233
|
* Reads an Address (32 bytes).
|
|
234
234
|
*/
|
|
235
235
|
public readAddress(): Address {
|
|
236
|
+
this.verifyEnd(this.currentOffset + ADDRESS_BYTE_LENGTH);
|
|
237
|
+
|
|
236
238
|
const addr = new Address();
|
|
237
239
|
for (let i: i32 = 0; i < ADDRESS_BYTE_LENGTH; i++) {
|
|
238
240
|
addr[i] = this.readU8();
|
|
@@ -39,7 +39,7 @@ export abstract class DeployableOP_20 extends OP_NET implements IOP_20 {
|
|
|
39
39
|
|
|
40
40
|
protected readonly _nonceMap: AddressMemoryMap;
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
public constructor(params: OP20InitParameters | null = null) {
|
|
43
43
|
super();
|
|
44
44
|
|
|
45
45
|
// Initialize main storage structures
|
|
@@ -3,7 +3,7 @@ import { u256 } from '@btc-vision/as-bignum/assembly';
|
|
|
3
3
|
import { OP20InitParameters } from './interfaces/OP20InitParameters';
|
|
4
4
|
|
|
5
5
|
export abstract class OP_20 extends DeployableOP_20 {
|
|
6
|
-
|
|
6
|
+
public constructor(maxSupply: u256, decimals: u8, name: string, symbol: string) {
|
|
7
7
|
super(new OP20InitParameters(maxSupply, decimals, name, symbol));
|
|
8
8
|
}
|
|
9
9
|
}
|
|
@@ -25,13 +25,10 @@ import { eqUint, MapUint8Array } from '../generic/MapUint8Array';
|
|
|
25
25
|
import { EMPTY_BUFFER } from '../math/bytes';
|
|
26
26
|
import { Plugin } from '../plugins/Plugin';
|
|
27
27
|
import { Calldata } from '../types';
|
|
28
|
+
import { Revert } from '../types/Revert';
|
|
28
29
|
|
|
29
30
|
export * from '../env/global';
|
|
30
31
|
|
|
31
|
-
export function runtimeError(msg: string): Error {
|
|
32
|
-
return new Error(`RuntimeException: ${msg}`);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
32
|
@final
|
|
36
33
|
export class BlockchainEnvironment {
|
|
37
34
|
private static readonly MAX_U16: u16 = 65535;
|
|
@@ -47,7 +44,7 @@ export class BlockchainEnvironment {
|
|
|
47
44
|
@inline
|
|
48
45
|
public get block(): Block {
|
|
49
46
|
if (!this._block) {
|
|
50
|
-
throw
|
|
47
|
+
throw new Revert('Block is required');
|
|
51
48
|
}
|
|
52
49
|
|
|
53
50
|
return this._block as Block;
|
|
@@ -58,7 +55,7 @@ export class BlockchainEnvironment {
|
|
|
58
55
|
@inline
|
|
59
56
|
public get tx(): Transaction {
|
|
60
57
|
if (!this._tx) {
|
|
61
|
-
throw
|
|
58
|
+
throw new Revert('Transaction is required');
|
|
62
59
|
}
|
|
63
60
|
|
|
64
61
|
return this._tx as Transaction;
|
|
@@ -80,7 +77,7 @@ export class BlockchainEnvironment {
|
|
|
80
77
|
|
|
81
78
|
public get nextPointer(): u16 {
|
|
82
79
|
if (this._nextPointer === BlockchainEnvironment.MAX_U16) {
|
|
83
|
-
throw
|
|
80
|
+
throw new Revert(`Out of storage pointer.`);
|
|
84
81
|
}
|
|
85
82
|
|
|
86
83
|
this._nextPointer += 1;
|
|
@@ -92,7 +89,7 @@ export class BlockchainEnvironment {
|
|
|
92
89
|
|
|
93
90
|
public get contractDeployer(): Address {
|
|
94
91
|
if (!this._contractDeployer) {
|
|
95
|
-
throw
|
|
92
|
+
throw new Revert('Deployer is required');
|
|
96
93
|
}
|
|
97
94
|
|
|
98
95
|
return this._contractDeployer as Address;
|
|
@@ -102,7 +99,7 @@ export class BlockchainEnvironment {
|
|
|
102
99
|
|
|
103
100
|
public get contractAddress(): Address {
|
|
104
101
|
if (!this._contractAddress) {
|
|
105
|
-
throw
|
|
102
|
+
throw new Revert('Contract address is required');
|
|
106
103
|
}
|
|
107
104
|
|
|
108
105
|
return this._contractAddress as Address;
|
|
@@ -171,12 +168,8 @@ export class BlockchainEnvironment {
|
|
|
171
168
|
}
|
|
172
169
|
|
|
173
170
|
public call(destinationContract: Address, calldata: BytesWriter): BytesReader {
|
|
174
|
-
if (destinationContract === this.contractAddress) {
|
|
175
|
-
throw this.error('Cannot call self');
|
|
176
|
-
}
|
|
177
|
-
|
|
178
171
|
if (!destinationContract) {
|
|
179
|
-
throw
|
|
172
|
+
throw new Revert('Destination contract is required');
|
|
180
173
|
}
|
|
181
174
|
|
|
182
175
|
const resultLengthBuffer = new ArrayBuffer(32);
|
|
@@ -224,17 +217,21 @@ export class BlockchainEnvironment {
|
|
|
224
217
|
public deployContractFromExisting(
|
|
225
218
|
existingAddress: Address,
|
|
226
219
|
salt: u256,
|
|
220
|
+
calldata: BytesWriter,
|
|
227
221
|
): Address {
|
|
228
222
|
const resultAddressBuffer = new ArrayBuffer(ADDRESS_BYTE_LENGTH);
|
|
223
|
+
const callDataBuffer = calldata.getBuffer().buffer;
|
|
229
224
|
|
|
230
225
|
const status = deployFromAddress(
|
|
231
226
|
existingAddress.buffer,
|
|
232
227
|
salt.toUint8Array(true).buffer,
|
|
228
|
+
callDataBuffer,
|
|
229
|
+
callDataBuffer.byteLength,
|
|
233
230
|
resultAddressBuffer,
|
|
234
231
|
);
|
|
235
232
|
|
|
236
233
|
if (status !== 0) {
|
|
237
|
-
throw
|
|
234
|
+
throw new Revert('Failed to deploy contract');
|
|
238
235
|
}
|
|
239
236
|
|
|
240
237
|
const contractAddressReader = new BytesReader(Uint8Array.wrap(resultAddressBuffer));
|
|
@@ -283,7 +280,7 @@ export class BlockchainEnvironment {
|
|
|
283
280
|
|
|
284
281
|
private createContractIfNotExists(): void {
|
|
285
282
|
if (!this._contract) {
|
|
286
|
-
throw
|
|
283
|
+
throw new Revert('Contract is required');
|
|
287
284
|
}
|
|
288
285
|
|
|
289
286
|
if (!this._selfContract) {
|
|
@@ -291,10 +288,6 @@ export class BlockchainEnvironment {
|
|
|
291
288
|
}
|
|
292
289
|
}
|
|
293
290
|
|
|
294
|
-
private error(msg: string): Error {
|
|
295
|
-
return runtimeError(msg);
|
|
296
|
-
}
|
|
297
|
-
|
|
298
291
|
private _internalSetStorageAt(pointerHash: Uint8Array, value: Uint8Array): void {
|
|
299
292
|
this.storage.set(pointerHash, value);
|
|
300
293
|
|
package/runtime/env/global.ts
CHANGED
|
@@ -20,7 +20,7 @@ export declare function storePointer(key: ArrayBuffer, value: ArrayBuffer): void
|
|
|
20
20
|
|
|
21
21
|
// @ts-ignore
|
|
22
22
|
@external('env', 'deployFromAddress')
|
|
23
|
-
export declare function deployFromAddress(originAddress: ArrayBuffer, salt: ArrayBuffer, resultAddress: ArrayBuffer): u32;
|
|
23
|
+
export declare function deployFromAddress(originAddress: ArrayBuffer, salt: ArrayBuffer, calldata: ArrayBuffer, calldataLength: u32, resultAddress: ArrayBuffer): u32;
|
|
24
24
|
|
|
25
25
|
// @ts-ignore
|
|
26
26
|
@external('env', 'call')
|
|
@@ -49,7 +49,7 @@ export abstract class StoredPackedArray<T> {
|
|
|
49
49
|
*/
|
|
50
50
|
protected readonly MAX_LENGTH: u64 = <u64>(u32.MAX_VALUE - 1);
|
|
51
51
|
|
|
52
|
-
protected constructor(public pointer: u16, public subPointer: Uint8Array) {
|
|
52
|
+
protected constructor(public pointer: u16, public subPointer: Uint8Array, protected defaultValue: T) {
|
|
53
53
|
assert(subPointer.length <= 30, `You must pass a 30 bytes sub-pointer. (Array, got ${subPointer.length})`);
|
|
54
54
|
|
|
55
55
|
const basePointer = encodeBasePointer(pointer, subPointer);
|
|
@@ -66,6 +66,24 @@ export abstract class StoredPackedArray<T> {
|
|
|
66
66
|
@inline
|
|
67
67
|
@operator('[]')
|
|
68
68
|
public get(index: u64): T {
|
|
69
|
+
// max length used on purpose to prevent unbounded usage
|
|
70
|
+
if (index > this.MAX_LENGTH) {
|
|
71
|
+
throw new Revert('get: out of range');
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const realIndex = (this._startIndex + index) % this.MAX_LENGTH;
|
|
75
|
+
const cap = this.getSlotCapacity();
|
|
76
|
+
const slotIndex = realIndex / cap;
|
|
77
|
+
const subIndex = <u32>(realIndex % cap);
|
|
78
|
+
|
|
79
|
+
const slotData = this.ensureSlot(slotIndex);
|
|
80
|
+
const arr = this.unpackSlot(slotData);
|
|
81
|
+
|
|
82
|
+
return arr[subIndex];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
@inline
|
|
86
|
+
public get_physical(index: u64): T {
|
|
69
87
|
if (index > this.MAX_LENGTH) {
|
|
70
88
|
throw new Revert('get: index exceeds MAX_LENGTH (packed array)');
|
|
71
89
|
}
|
|
@@ -74,11 +92,9 @@ export abstract class StoredPackedArray<T> {
|
|
|
74
92
|
const slotIndex = index / cap;
|
|
75
93
|
const subIndex = <u32>(index % cap);
|
|
76
94
|
|
|
77
|
-
// Load the slot if not cached
|
|
78
95
|
const slotData = this.ensureSlot(slotIndex);
|
|
79
|
-
|
|
80
|
-
// Unpack and return the subIndex
|
|
81
96
|
const arr = this.unpackSlot(slotData);
|
|
97
|
+
|
|
82
98
|
return arr[subIndex];
|
|
83
99
|
}
|
|
84
100
|
|
|
@@ -89,6 +105,28 @@ export abstract class StoredPackedArray<T> {
|
|
|
89
105
|
throw new Revert('set: index exceeds MAX_LENGTH (packed array)');
|
|
90
106
|
}
|
|
91
107
|
|
|
108
|
+
const realIndex = (this._startIndex + index) % this.MAX_LENGTH;
|
|
109
|
+
const cap = this.getSlotCapacity();
|
|
110
|
+
const slotIndex = realIndex / cap;
|
|
111
|
+
const subIndex = <u32>(realIndex % cap);
|
|
112
|
+
|
|
113
|
+
let slotData = this.ensureSlot(slotIndex);
|
|
114
|
+
const arr = this.unpackSlot(slotData);
|
|
115
|
+
|
|
116
|
+
if (!this.eq(arr[subIndex], value)) {
|
|
117
|
+
arr[subIndex] = value;
|
|
118
|
+
slotData = this.packSlot(arr);
|
|
119
|
+
this._slots.set(slotIndex, slotData);
|
|
120
|
+
this._isChanged.add(slotIndex);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
@inline
|
|
125
|
+
public set_physical(index: u64, value: T): void {
|
|
126
|
+
if (index > this.MAX_LENGTH) {
|
|
127
|
+
throw new Revert('set: index exceeds MAX_LENGTH (packed array)');
|
|
128
|
+
}
|
|
129
|
+
|
|
92
130
|
const cap = this.getSlotCapacity();
|
|
93
131
|
const slotIndex = index / cap;
|
|
94
132
|
const subIndex = <u32>(index % cap);
|
|
@@ -105,15 +143,15 @@ export abstract class StoredPackedArray<T> {
|
|
|
105
143
|
}
|
|
106
144
|
|
|
107
145
|
@inline
|
|
108
|
-
public push(value: T): void {
|
|
146
|
+
public push(value: T, isPhysical: bool = false): void {
|
|
109
147
|
if (this._length >= this.MAX_LENGTH) {
|
|
110
|
-
throw new Revert('push: array has reached MAX_LENGTH
|
|
148
|
+
throw new Revert('push: array has reached MAX_LENGTH');
|
|
111
149
|
}
|
|
112
150
|
|
|
113
|
-
const
|
|
151
|
+
const realIndex = ((isPhysical ? 0 : this._startIndex) + this._length) % this.MAX_LENGTH;
|
|
114
152
|
const cap = this.getSlotCapacity();
|
|
115
|
-
const slotIndex =
|
|
116
|
-
const subIndex = <u32>(
|
|
153
|
+
const slotIndex = realIndex / cap;
|
|
154
|
+
const subIndex = <u32>(realIndex % cap);
|
|
117
155
|
|
|
118
156
|
let slotData = this.ensureSlot(slotIndex);
|
|
119
157
|
const arr = this.unpackSlot(slotData);
|
|
@@ -129,12 +167,70 @@ export abstract class StoredPackedArray<T> {
|
|
|
129
167
|
this._isChangedLength = true;
|
|
130
168
|
}
|
|
131
169
|
|
|
170
|
+
/**
|
|
171
|
+
* Remove the first element by zeroing it and shifting all other elements.
|
|
172
|
+
*/
|
|
173
|
+
@inline
|
|
174
|
+
public shift(): T {
|
|
175
|
+
if (this._length == 0) {
|
|
176
|
+
throw new Revert('shift: array is empty (packed array)');
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const newIndex = this._startIndex;
|
|
180
|
+
const cap = this.getSlotCapacity();
|
|
181
|
+
const slotIndex = newIndex / cap;
|
|
182
|
+
const subIndex = <u32>(newIndex % cap);
|
|
183
|
+
|
|
184
|
+
let slotData = this.ensureSlot(slotIndex);
|
|
185
|
+
|
|
186
|
+
const arr = this.unpackSlot(slotData);
|
|
187
|
+
const currentData = arr[subIndex];
|
|
188
|
+
|
|
189
|
+
if (!this.eq(currentData, this.defaultValue)) {
|
|
190
|
+
arr[subIndex] = this.defaultValue;
|
|
191
|
+
slotData = this.packSlot(arr);
|
|
192
|
+
|
|
193
|
+
this._slots.set(slotIndex, slotData);
|
|
194
|
+
this._isChanged.add(slotIndex);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
this._length -= 1;
|
|
198
|
+
this._startIndex += 1;
|
|
199
|
+
this._isChangedLength = true;
|
|
200
|
+
this._isChangedStartIndex = true;
|
|
201
|
+
|
|
202
|
+
return currentData;
|
|
203
|
+
}
|
|
204
|
+
|
|
132
205
|
/**
|
|
133
206
|
* "Delete" by zeroing out the element at `index`,
|
|
134
207
|
* but does not reduce the length.
|
|
135
208
|
*/
|
|
136
209
|
@inline
|
|
137
210
|
public delete(index: u64): void {
|
|
211
|
+
const realIndex = (this._startIndex + index) % this.MAX_LENGTH;
|
|
212
|
+
const cap = this.getSlotCapacity();
|
|
213
|
+
const slotIndex = realIndex / cap;
|
|
214
|
+
const subIndex = <u32>(realIndex % cap);
|
|
215
|
+
|
|
216
|
+
let slotData = this.ensureSlot(slotIndex);
|
|
217
|
+
const arr = this.unpackSlot(slotData);
|
|
218
|
+
|
|
219
|
+
const zeroVal = this.zeroValue();
|
|
220
|
+
if (!this.eq(arr[subIndex], zeroVal)) {
|
|
221
|
+
arr[subIndex] = zeroVal;
|
|
222
|
+
slotData = this.packSlot(arr);
|
|
223
|
+
this._slots.set(slotIndex, slotData);
|
|
224
|
+
this._isChanged.add(slotIndex);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* "Delete" by zeroing out the element at `index`,
|
|
230
|
+
* but does not reduce the length.
|
|
231
|
+
*/
|
|
232
|
+
@inline
|
|
233
|
+
public delete_physical(index: u64): void {
|
|
138
234
|
const cap = this.getSlotCapacity();
|
|
139
235
|
const slotIndex = index / cap;
|
|
140
236
|
const subIndex = <u32>(index % cap);
|
|
@@ -10,7 +10,7 @@ import { bigEndianAdd } from '../../math/bytes';
|
|
|
10
10
|
@final
|
|
11
11
|
export class StoredU128Array extends StoredPackedArray<u128> {
|
|
12
12
|
public constructor(pointer: u16, subPointer: Uint8Array) {
|
|
13
|
-
super(pointer, subPointer);
|
|
13
|
+
super(pointer, subPointer, u128.Zero);
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
protected getSlotCapacity(): u64 {
|
|
@@ -7,7 +7,7 @@ import { bigEndianAdd } from '../../math/bytes';
|
|
|
7
7
|
@final
|
|
8
8
|
export class StoredU16Array extends StoredPackedArray<u16> {
|
|
9
9
|
public constructor(pointer: u16, subPointer: Uint8Array) {
|
|
10
|
-
super(pointer, subPointer);
|
|
10
|
+
super(pointer, subPointer, 0);
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
protected getSlotCapacity(): u64 {
|
|
@@ -9,7 +9,7 @@ import { bigEndianAdd } from '../../math/bytes';
|
|
|
9
9
|
@final
|
|
10
10
|
export class StoredU256Array extends StoredPackedArray<u256> {
|
|
11
11
|
public constructor(pointer: u16, subPointer: Uint8Array) {
|
|
12
|
-
super(pointer, subPointer);
|
|
12
|
+
super(pointer, subPointer, u256.Zero);
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
protected getSlotCapacity(): u64 {
|
|
@@ -8,7 +8,7 @@ import { bigEndianAdd } from '../../math/bytes';
|
|
|
8
8
|
@final
|
|
9
9
|
export class StoredU32Array extends StoredPackedArray<u32> {
|
|
10
10
|
public constructor(pointer: u16, subPointer: Uint8Array) {
|
|
11
|
-
super(pointer, subPointer);
|
|
11
|
+
super(pointer, subPointer, 0);
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
protected getSlotCapacity(): u64 {
|
|
@@ -8,7 +8,7 @@ import { bigEndianAdd } from '../../math/bytes';
|
|
|
8
8
|
@final
|
|
9
9
|
export class StoredU64Array extends StoredPackedArray<u64> {
|
|
10
10
|
public constructor(pointer: u16, subPointer: Uint8Array) {
|
|
11
|
-
super(pointer, subPointer);
|
|
11
|
+
super(pointer, subPointer, 0);
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
protected getSlotCapacity(): u64 {
|
|
@@ -8,7 +8,7 @@ import { bigEndianAdd } from '../../math/bytes';
|
|
|
8
8
|
@final
|
|
9
9
|
export class StoredU8Array extends StoredPackedArray<u8> {
|
|
10
10
|
public constructor(pointer: u16, subPointer: Uint8Array) {
|
|
11
|
-
super(pointer, subPointer);
|
|
11
|
+
super(pointer, subPointer, 0);
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
protected getSlotCapacity(): u64 {
|