@btc-vision/btc-runtime 1.5.4 → 1.5.7
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/contracts/DeployableOP_20.ts +1 -1
- package/runtime/contracts/OP_20.ts +1 -1
- package/runtime/env/BlockchainEnvironment.ts +11 -20
- package/runtime/env/classes/Transaction.ts +1 -0
- package/runtime/exports/index.ts +1 -1
- package/runtime/math/bytes.ts +2 -18
- package/runtime/storage/arrays/StoredAddressArray.ts +48 -42
- package/runtime/storage/arrays/StoredBooleanArray.ts +58 -26
- package/runtime/storage/arrays/StoredPackedArray.ts +130 -14
- package/runtime/storage/arrays/StoredU128Array.ts +2 -2
- package/runtime/storage/arrays/StoredU16Array.ts +2 -2
- package/runtime/storage/arrays/StoredU256Array.ts +2 -2
- package/runtime/storage/arrays/StoredU32Array.ts +2 -2
- package/runtime/storage/arrays/StoredU64Array.ts +2 -2
- package/runtime/storage/arrays/StoredU8Array.ts +2 -2
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.7",
|
|
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.13.10",
|
|
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.22.0",
|
|
41
|
+
"gulplog": "^2.2.0",
|
|
42
|
+
"ts-node": "^10.9.2",
|
|
43
|
+
"typescript": "^5.8.2",
|
|
44
|
+
"typescript-eslint": "^8.26.1"
|
|
45
|
+
}
|
|
46
46
|
}
|
|
@@ -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;
|
|
@@ -148,6 +145,7 @@ export class BlockchainEnvironment {
|
|
|
148
145
|
const blockHash = reader.readBytes(32);
|
|
149
146
|
const blockNumber = reader.readU64();
|
|
150
147
|
const blockMedianTime = reader.readU64();
|
|
148
|
+
const txId = reader.readBytes(32);
|
|
151
149
|
const txHash = reader.readBytes(32);
|
|
152
150
|
const contractAddress = reader.readAddress();
|
|
153
151
|
const contractDeployer = reader.readAddress();
|
|
@@ -157,6 +155,7 @@ export class BlockchainEnvironment {
|
|
|
157
155
|
this._tx = new Transaction(
|
|
158
156
|
caller,
|
|
159
157
|
origin,
|
|
158
|
+
txId,
|
|
160
159
|
txHash,
|
|
161
160
|
);
|
|
162
161
|
|
|
@@ -169,12 +168,8 @@ export class BlockchainEnvironment {
|
|
|
169
168
|
}
|
|
170
169
|
|
|
171
170
|
public call(destinationContract: Address, calldata: BytesWriter): BytesReader {
|
|
172
|
-
if (destinationContract === this.contractAddress) {
|
|
173
|
-
throw this.error('Cannot call self');
|
|
174
|
-
}
|
|
175
|
-
|
|
176
171
|
if (!destinationContract) {
|
|
177
|
-
throw
|
|
172
|
+
throw new Revert('Destination contract is required');
|
|
178
173
|
}
|
|
179
174
|
|
|
180
175
|
const resultLengthBuffer = new ArrayBuffer(32);
|
|
@@ -232,7 +227,7 @@ export class BlockchainEnvironment {
|
|
|
232
227
|
);
|
|
233
228
|
|
|
234
229
|
if (status !== 0) {
|
|
235
|
-
throw
|
|
230
|
+
throw new Revert('Failed to deploy contract');
|
|
236
231
|
}
|
|
237
232
|
|
|
238
233
|
const contractAddressReader = new BytesReader(Uint8Array.wrap(resultAddressBuffer));
|
|
@@ -281,7 +276,7 @@ export class BlockchainEnvironment {
|
|
|
281
276
|
|
|
282
277
|
private createContractIfNotExists(): void {
|
|
283
278
|
if (!this._contract) {
|
|
284
|
-
throw
|
|
279
|
+
throw new Revert('Contract is required');
|
|
285
280
|
}
|
|
286
281
|
|
|
287
282
|
if (!this._selfContract) {
|
|
@@ -289,10 +284,6 @@ export class BlockchainEnvironment {
|
|
|
289
284
|
}
|
|
290
285
|
}
|
|
291
286
|
|
|
292
|
-
private error(msg: string): Error {
|
|
293
|
-
return runtimeError(msg);
|
|
294
|
-
}
|
|
295
|
-
|
|
296
287
|
private _internalSetStorageAt(pointerHash: Uint8Array, value: Uint8Array): void {
|
|
297
288
|
this.storage.set(pointerHash, value);
|
|
298
289
|
|
|
@@ -9,6 +9,7 @@ export class Transaction {
|
|
|
9
9
|
public constructor(
|
|
10
10
|
public readonly sender: Address, // "immediate caller"
|
|
11
11
|
public readonly origin: Address, // "leftmost thing in the call chain"
|
|
12
|
+
public readonly txId: Uint8Array,
|
|
12
13
|
public readonly hash: Uint8Array,
|
|
13
14
|
) {
|
|
14
15
|
}
|
package/runtime/exports/index.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { Selector } from '../math/abi';
|
|
|
5
5
|
import { Calldata } from '../types';
|
|
6
6
|
import { env_exit, getCalldata, getEnvironmentVariables } from '../env/global';
|
|
7
7
|
|
|
8
|
-
const ENVIRONMENT_VARIABLES_BYTE_LENGTH: u32 =
|
|
8
|
+
const ENVIRONMENT_VARIABLES_BYTE_LENGTH: u32 = 240;
|
|
9
9
|
|
|
10
10
|
export function execute(calldataLength: u32): u32 {
|
|
11
11
|
const environmentVariablesBuffer = new ArrayBuffer(ENVIRONMENT_VARIABLES_BYTE_LENGTH);
|
package/runtime/math/bytes.ts
CHANGED
|
@@ -171,23 +171,7 @@ export function encodeBasePointer(pointer: u16, subPointer: Uint8Array): Uint8Ar
|
|
|
171
171
|
|
|
172
172
|
@inline
|
|
173
173
|
export function bigEndianAdd(base: Uint8Array, increment: u64): Uint8Array {
|
|
174
|
-
const
|
|
174
|
+
const add = u64ToBE32Bytes(increment);
|
|
175
175
|
|
|
176
|
-
|
|
177
|
-
for (let i = 0; i < 32; i++) {
|
|
178
|
-
out[i] = base[i];
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
// If this is truly big-endian, out[0] is the MSB, out[31] is the LSB.
|
|
182
|
-
// So to add `increment`, we start from out[31] backward.
|
|
183
|
-
let carry: u64 = increment;
|
|
184
|
-
for (let i = 31; i >= 0; i--) {
|
|
185
|
-
const sum = <u64>out[i] + (carry & 0xFF);
|
|
186
|
-
out[i] = <u8>(sum & 0xFF);
|
|
187
|
-
carry = sum >> 8;
|
|
188
|
-
if (carry == 0 || i == 0) {
|
|
189
|
-
break;
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
return out;
|
|
176
|
+
return addUint8ArraysBE(base, add);
|
|
193
177
|
}
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { BytesWriter } from '../../buffer/BytesWriter';
|
|
2
2
|
import { Blockchain } from '../../env';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
addUint8ArraysBE,
|
|
5
|
+
bigEndianAdd,
|
|
6
|
+
encodeBasePointer,
|
|
7
|
+
readLengthAndStartIndex,
|
|
8
|
+
u64ToBE32Bytes,
|
|
9
|
+
} from '../../math/bytes';
|
|
4
10
|
import { Address } from '../../types/Address';
|
|
5
11
|
import { Revert } from '../../types/Revert';
|
|
6
12
|
|
|
@@ -39,7 +45,7 @@ export class StoredAddressArray {
|
|
|
39
45
|
|
|
40
46
|
const basePointer = encodeBasePointer(pointer, subPointer);
|
|
41
47
|
this.lengthPointer = Uint8Array.wrap(basePointer.buffer);
|
|
42
|
-
this.baseU256Pointer = basePointer;
|
|
48
|
+
this.baseU256Pointer = bigEndianAdd(basePointer, 1);
|
|
43
49
|
|
|
44
50
|
const storedLenStart = Blockchain.getStorageAt(basePointer);
|
|
45
51
|
const data = readLengthAndStartIndex(storedLenStart);
|
|
@@ -48,13 +54,21 @@ export class StoredAddressArray {
|
|
|
48
54
|
this._startIndex = data[1];
|
|
49
55
|
}
|
|
50
56
|
|
|
57
|
+
@inline
|
|
58
|
+
public has(index: u64): bool {
|
|
59
|
+
return index < this._length;
|
|
60
|
+
}
|
|
61
|
+
|
|
51
62
|
/** Get an element by its global index. */
|
|
52
63
|
@inline
|
|
64
|
+
@operator('[]')
|
|
53
65
|
public get(index: u64): Address {
|
|
54
|
-
if (index
|
|
55
|
-
throw new Revert('
|
|
66
|
+
if (index >= this._length) {
|
|
67
|
+
throw new Revert('get: index out of range (address array)');
|
|
56
68
|
}
|
|
57
|
-
|
|
69
|
+
|
|
70
|
+
const physicalIndex = (this._startIndex + index) % this.MAX_LENGTH;
|
|
71
|
+
const slotIndex: u32 = <u32>physicalIndex;
|
|
58
72
|
this.ensureValues(slotIndex);
|
|
59
73
|
|
|
60
74
|
return this._values.get(slotIndex);
|
|
@@ -62,11 +76,14 @@ export class StoredAddressArray {
|
|
|
62
76
|
|
|
63
77
|
/** Set an element by its global index. */
|
|
64
78
|
@inline
|
|
79
|
+
@operator('[]=')
|
|
65
80
|
public set(index: u64, value: Address): void {
|
|
66
|
-
if (index
|
|
67
|
-
throw new Revert('
|
|
81
|
+
if (index >= this._length) {
|
|
82
|
+
throw new Revert('set: index out of range (address array)');
|
|
68
83
|
}
|
|
69
|
-
|
|
84
|
+
|
|
85
|
+
const physicalIndex = (this._startIndex + index) % this.MAX_LENGTH;
|
|
86
|
+
const slotIndex: u32 = <u32>physicalIndex;
|
|
70
87
|
this.ensureValues(slotIndex);
|
|
71
88
|
|
|
72
89
|
const currentValue = this._values.get(slotIndex);
|
|
@@ -76,33 +93,16 @@ export class StoredAddressArray {
|
|
|
76
93
|
}
|
|
77
94
|
}
|
|
78
95
|
|
|
79
|
-
/** Find the first index containing `value`. Returns -1 if not found. */
|
|
80
|
-
@inline
|
|
81
|
-
public indexOf(value: Address): i64 {
|
|
82
|
-
for (let i: u64 = 0; i < this._length; i++) {
|
|
83
|
-
if (this.get(i) == value) {
|
|
84
|
-
return i64(i);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
return -1;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/** Check if the array contains `value`. */
|
|
91
|
-
@inline
|
|
92
|
-
public contains(value: Address): boolean {
|
|
93
|
-
return this.indexOf(value) !== -1;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
96
|
/** Append an address at the end of the array. */
|
|
97
|
+
@inline
|
|
97
98
|
public push(value: Address): void {
|
|
98
99
|
if (this._length >= this.MAX_LENGTH) {
|
|
99
|
-
throw new Revert('
|
|
100
|
+
throw new Revert('push: array reached maximum length (address array)');
|
|
100
101
|
}
|
|
101
102
|
|
|
102
|
-
const
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
const slotIndex: u32 = <u32>wrappedIndex;
|
|
103
|
+
const newLogicalIndex: u64 = this._length;
|
|
104
|
+
const physicalIndex: u64 = (this._startIndex + newLogicalIndex) % this.MAX_LENGTH;
|
|
105
|
+
const slotIndex: u32 = <u32>physicalIndex;
|
|
106
106
|
|
|
107
107
|
this.ensureValues(slotIndex);
|
|
108
108
|
this._values.set(slotIndex, value);
|
|
@@ -115,11 +115,12 @@ export class StoredAddressArray {
|
|
|
115
115
|
/** Delete the last element. */
|
|
116
116
|
public deleteLast(): void {
|
|
117
117
|
if (this._length === 0) {
|
|
118
|
-
throw new Revert('
|
|
118
|
+
throw new Revert('deleteLast: array is empty (address array)');
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
-
const
|
|
122
|
-
const
|
|
121
|
+
const lastLogicalIndex: u64 = this._length - 1;
|
|
122
|
+
const physicalIndex: u64 = (this._startIndex + lastLogicalIndex) % this.MAX_LENGTH;
|
|
123
|
+
const slotIndex: u32 = <u32>physicalIndex;
|
|
123
124
|
this.ensureValues(slotIndex);
|
|
124
125
|
|
|
125
126
|
const currentValue = this._values.get(slotIndex);
|
|
@@ -139,12 +140,14 @@ export class StoredAddressArray {
|
|
|
139
140
|
}
|
|
140
141
|
|
|
141
142
|
/** Delete a specific element by setting it to `defaultValue`. */
|
|
143
|
+
@inline
|
|
142
144
|
public delete(index: u64): void {
|
|
143
145
|
if (index > this.MAX_LENGTH) {
|
|
144
|
-
throw new Revert('
|
|
146
|
+
throw new Revert('delete: index out of range (address array)');
|
|
145
147
|
}
|
|
146
148
|
|
|
147
|
-
const
|
|
149
|
+
const physicalIndex: u64 = (this._startIndex + index) % this.MAX_LENGTH;
|
|
150
|
+
const slotIndex: u32 = <u32>physicalIndex;
|
|
148
151
|
this.ensureValues(slotIndex);
|
|
149
152
|
|
|
150
153
|
const currentValue = this._values.get(slotIndex);
|
|
@@ -159,6 +162,7 @@ export class StoredAddressArray {
|
|
|
159
162
|
* - Store any changed slotIndex -> Address
|
|
160
163
|
* - Store updated length and startIndex if changed
|
|
161
164
|
*/
|
|
165
|
+
@inline
|
|
162
166
|
public save(): void {
|
|
163
167
|
// 1) Save changed slots
|
|
164
168
|
const changed = this._isChanged.values();
|
|
@@ -185,7 +189,6 @@ export class StoredAddressArray {
|
|
|
185
189
|
|
|
186
190
|
/** Clear entire array content from storage, reset length and startIndex. */
|
|
187
191
|
public deleteAll(): void {
|
|
188
|
-
// Clear all loaded slots
|
|
189
192
|
const keys = this._values.keys();
|
|
190
193
|
for (let i = 0; i < keys.length; i++) {
|
|
191
194
|
const slotIndex = keys[i];
|
|
@@ -193,14 +196,13 @@ export class StoredAddressArray {
|
|
|
193
196
|
Blockchain.setStorageAt(storagePointer, this.defaultValue);
|
|
194
197
|
}
|
|
195
198
|
|
|
196
|
-
|
|
197
|
-
|
|
199
|
+
Blockchain.setStorageAt(this.lengthPointer, new Uint8Array(32));
|
|
200
|
+
|
|
198
201
|
this._length = 0;
|
|
199
202
|
this._startIndex = 0;
|
|
200
203
|
this._isChangedLength = false;
|
|
201
204
|
this._isChangedStartIndex = false;
|
|
202
205
|
|
|
203
|
-
// Clear internal caches
|
|
204
206
|
this._values.clear();
|
|
205
207
|
this._isChanged.clear();
|
|
206
208
|
}
|
|
@@ -217,7 +219,7 @@ export class StoredAddressArray {
|
|
|
217
219
|
@inline
|
|
218
220
|
public getAll(startIndex: u32, count: u32): Address[] {
|
|
219
221
|
if (startIndex + count > this._length) {
|
|
220
|
-
throw new Revert('
|
|
222
|
+
throw new Revert('getAll: index out of range (address array)');
|
|
221
223
|
}
|
|
222
224
|
|
|
223
225
|
const result = new Array<Address>(count);
|
|
@@ -249,6 +251,10 @@ export class StoredAddressArray {
|
|
|
249
251
|
this._startIndex = 0;
|
|
250
252
|
this._isChangedLength = true;
|
|
251
253
|
this._isChangedStartIndex = true;
|
|
254
|
+
|
|
255
|
+
this._values.clear();
|
|
256
|
+
this._isChanged.clear();
|
|
257
|
+
|
|
252
258
|
this.save();
|
|
253
259
|
}
|
|
254
260
|
|
|
@@ -284,8 +290,8 @@ export class StoredAddressArray {
|
|
|
284
290
|
* Compute a 32-byte storage pointer = basePointer + (slotIndex + 1) big-endian.
|
|
285
291
|
*/
|
|
286
292
|
private calculateStoragePointer(slotIndex: u64): Uint8Array {
|
|
287
|
-
// Convert (slotIndex
|
|
288
|
-
const offset = u64ToBE32Bytes(slotIndex
|
|
293
|
+
// Convert (slotIndex) to a 32-byte big-endian offset
|
|
294
|
+
const offset = u64ToBE32Bytes(slotIndex);
|
|
289
295
|
|
|
290
296
|
return addUint8ArraysBE(this.baseU256Pointer, offset);
|
|
291
297
|
}
|
|
@@ -3,6 +3,7 @@ import { Blockchain } from '../../env';
|
|
|
3
3
|
import { Revert } from '../../types/Revert';
|
|
4
4
|
import {
|
|
5
5
|
addUint8ArraysBE,
|
|
6
|
+
bigEndianAdd,
|
|
6
7
|
encodeBasePointer,
|
|
7
8
|
GET_EMPTY_BUFFER,
|
|
8
9
|
getBit,
|
|
@@ -51,7 +52,7 @@ export class StoredBooleanArray {
|
|
|
51
52
|
|
|
52
53
|
const basePointer = encodeBasePointer(pointer, subPtr);
|
|
53
54
|
this.lengthPointer = Uint8Array.wrap(basePointer.buffer);
|
|
54
|
-
this.basePointer = basePointer;
|
|
55
|
+
this.basePointer = bigEndianAdd(basePointer, 1);
|
|
55
56
|
|
|
56
57
|
const storedLenStart = Blockchain.getStorageAt(basePointer);
|
|
57
58
|
const data = readLengthAndStartIndex(storedLenStart);
|
|
@@ -62,16 +63,28 @@ export class StoredBooleanArray {
|
|
|
62
63
|
|
|
63
64
|
// -------------- Public Accessors -------------- //
|
|
64
65
|
|
|
66
|
+
@inline
|
|
67
|
+
public has(index: u64): bool {
|
|
68
|
+
return index < this._length;
|
|
69
|
+
}
|
|
70
|
+
|
|
65
71
|
/**
|
|
66
72
|
* Retrieve boolean at `index`.
|
|
67
73
|
*/
|
|
74
|
+
@operator('[]')
|
|
68
75
|
@inline
|
|
69
76
|
public get(index: u64): bool {
|
|
70
|
-
if (index
|
|
71
|
-
throw new Revert(
|
|
77
|
+
if (index >= this._length) {
|
|
78
|
+
throw new Revert(`get: index out of range (${index} >= ${this._length}, boolean array)`);
|
|
72
79
|
}
|
|
73
|
-
|
|
74
|
-
const
|
|
80
|
+
|
|
81
|
+
const effectiveIndex = this._startIndex + index;
|
|
82
|
+
const wrappedIndex = effectiveIndex < this.MAX_LENGTH
|
|
83
|
+
? effectiveIndex
|
|
84
|
+
: effectiveIndex % this.MAX_LENGTH;
|
|
85
|
+
|
|
86
|
+
const slotIndex = wrappedIndex / 256;
|
|
87
|
+
const bitIndex = <u16>(wrappedIndex % 256);
|
|
75
88
|
|
|
76
89
|
this.ensureSlotLoaded(slotIndex);
|
|
77
90
|
|
|
@@ -82,13 +95,20 @@ export class StoredBooleanArray {
|
|
|
82
95
|
/**
|
|
83
96
|
* Set boolean at `index`.
|
|
84
97
|
*/
|
|
98
|
+
@operator('[]=')
|
|
85
99
|
@inline
|
|
86
100
|
public set(index: u64, value: bool): void {
|
|
87
|
-
if (index
|
|
88
|
-
throw new Revert(
|
|
101
|
+
if (index >= this._length) {
|
|
102
|
+
throw new Revert(`set: index out of range (${index} >= ${this._length}, boolean array)`);
|
|
89
103
|
}
|
|
90
|
-
|
|
91
|
-
const
|
|
104
|
+
|
|
105
|
+
const effectiveIndex = this._startIndex + index;
|
|
106
|
+
const wrappedIndex = effectiveIndex < this.MAX_LENGTH
|
|
107
|
+
? effectiveIndex
|
|
108
|
+
: effectiveIndex % this.MAX_LENGTH;
|
|
109
|
+
|
|
110
|
+
const slotIndex = wrappedIndex / 256;
|
|
111
|
+
const bitIndex = <u16>(wrappedIndex % 256);
|
|
92
112
|
|
|
93
113
|
this.ensureSlotLoaded(slotIndex);
|
|
94
114
|
|
|
@@ -108,7 +128,7 @@ export class StoredBooleanArray {
|
|
|
108
128
|
@inline
|
|
109
129
|
public push(value: bool): void {
|
|
110
130
|
if (this._length >= this.MAX_LENGTH) {
|
|
111
|
-
throw new Revert('push:
|
|
131
|
+
throw new Revert('push: reached max allowed length (boolean array)');
|
|
112
132
|
}
|
|
113
133
|
|
|
114
134
|
const newIndex = this._length;
|
|
@@ -137,11 +157,17 @@ export class StoredBooleanArray {
|
|
|
137
157
|
*/
|
|
138
158
|
@inline
|
|
139
159
|
public delete(index: u64): void {
|
|
140
|
-
if (index
|
|
141
|
-
throw new Revert('delete:
|
|
160
|
+
if (index >= this._length) {
|
|
161
|
+
throw new Revert('delete: index out of range (boolean array)');
|
|
142
162
|
}
|
|
143
|
-
|
|
144
|
-
const
|
|
163
|
+
|
|
164
|
+
const effectiveIndex = this._startIndex + index;
|
|
165
|
+
const wrappedIndex = effectiveIndex < this.MAX_LENGTH
|
|
166
|
+
? effectiveIndex
|
|
167
|
+
: effectiveIndex % this.MAX_LENGTH;
|
|
168
|
+
|
|
169
|
+
const slotIndex = wrappedIndex / 256;
|
|
170
|
+
const bitIndex = <u16>(wrappedIndex % 256);
|
|
145
171
|
|
|
146
172
|
this.ensureSlotLoaded(slotIndex);
|
|
147
173
|
|
|
@@ -161,8 +187,9 @@ export class StoredBooleanArray {
|
|
|
161
187
|
@inline
|
|
162
188
|
public deleteLast(): void {
|
|
163
189
|
if (this._length === 0) {
|
|
164
|
-
throw new Revert('deleteLast:
|
|
190
|
+
throw new Revert('deleteLast: array is empty');
|
|
165
191
|
}
|
|
192
|
+
|
|
166
193
|
const lastIndex = this._length - 1;
|
|
167
194
|
this.delete(lastIndex);
|
|
168
195
|
|
|
@@ -200,11 +227,10 @@ export class StoredBooleanArray {
|
|
|
200
227
|
}
|
|
201
228
|
|
|
202
229
|
/**
|
|
203
|
-
* Delete all slots in storage (that are loaded) + reset length +
|
|
230
|
+
* Delete all slots in storage (that are loaded) + reset length + _startIndex.
|
|
204
231
|
*/
|
|
205
232
|
@inline
|
|
206
233
|
public deleteAll(): void {
|
|
207
|
-
// clear all loaded slots
|
|
208
234
|
const keys = this._values.keys();
|
|
209
235
|
const zeroArr = GET_EMPTY_BUFFER();
|
|
210
236
|
for (let i = 0; i < keys.length; i++) {
|
|
@@ -213,15 +239,14 @@ export class StoredBooleanArray {
|
|
|
213
239
|
Blockchain.setStorageAt(storagePointer, zeroArr);
|
|
214
240
|
}
|
|
215
241
|
|
|
216
|
-
// also reset length + startIndex in storage
|
|
217
242
|
const writer = new BytesWriter(32);
|
|
218
243
|
Blockchain.setStorageAt(this.lengthPointer, writer.getBuffer());
|
|
219
244
|
|
|
220
|
-
// reset in memory
|
|
221
245
|
this._length = 0;
|
|
222
246
|
this._startIndex = 0;
|
|
223
247
|
this._isChangedLength = false;
|
|
224
248
|
this._isChangedStartIndex = false;
|
|
249
|
+
|
|
225
250
|
this._values.clear();
|
|
226
251
|
this._isChanged.clear();
|
|
227
252
|
}
|
|
@@ -240,18 +265,20 @@ export class StoredBooleanArray {
|
|
|
240
265
|
* Retrieve a batch of bools.
|
|
241
266
|
*/
|
|
242
267
|
@inline
|
|
243
|
-
public getAll(
|
|
244
|
-
if (
|
|
245
|
-
throw new Revert('getAll: range exceeds array length');
|
|
268
|
+
public getAll(start: u64, count: u64): bool[] {
|
|
269
|
+
if (start + count > this._length) {
|
|
270
|
+
throw new Revert('getAll: range exceeds array length (boolean array)');
|
|
246
271
|
}
|
|
272
|
+
|
|
247
273
|
if (count > u64(u32.MAX_VALUE)) {
|
|
248
|
-
throw new Revert('getAll: range exceeds max allowed');
|
|
274
|
+
throw new Revert('getAll: range exceeds max allowed (boolean array)');
|
|
249
275
|
}
|
|
250
276
|
|
|
251
277
|
const result = new Array<bool>(<i32>count);
|
|
252
278
|
for (let i: u64 = 0; i < count; i++) {
|
|
253
|
-
result[<i32>i] = this.get(
|
|
279
|
+
result[<i32>i] = this.get(start + i);
|
|
254
280
|
}
|
|
281
|
+
|
|
255
282
|
return result;
|
|
256
283
|
}
|
|
257
284
|
|
|
@@ -295,6 +322,12 @@ export class StoredBooleanArray {
|
|
|
295
322
|
return this._length;
|
|
296
323
|
}
|
|
297
324
|
|
|
325
|
+
@inline
|
|
326
|
+
public setStartingIndex(index: u64): void {
|
|
327
|
+
this._startIndex = index;
|
|
328
|
+
this._isChangedStartIndex = true;
|
|
329
|
+
}
|
|
330
|
+
|
|
298
331
|
/**
|
|
299
332
|
* Current starting index for the array.
|
|
300
333
|
*/
|
|
@@ -303,7 +336,6 @@ export class StoredBooleanArray {
|
|
|
303
336
|
return this._startIndex;
|
|
304
337
|
}
|
|
305
338
|
|
|
306
|
-
|
|
307
339
|
/**
|
|
308
340
|
* Ensure the 32-byte slot for `slotIndex` is loaded into _values.
|
|
309
341
|
*/
|
|
@@ -319,7 +351,7 @@ export class StoredBooleanArray {
|
|
|
319
351
|
* Convert `slotIndex` -> pointer = basePointer + (slotIndex + 1), as big-endian addition.
|
|
320
352
|
*/
|
|
321
353
|
private calculateStoragePointer(slotIndex: u64): Uint8Array {
|
|
322
|
-
const offset = u64ToBE32Bytes(slotIndex
|
|
354
|
+
const offset = u64ToBE32Bytes(slotIndex);
|
|
323
355
|
return addUint8ArraysBE(this.basePointer, offset);
|
|
324
356
|
}
|
|
325
357
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
bigEndianAdd,
|
|
2
3
|
encodeBasePointer,
|
|
3
4
|
GET_EMPTY_BUFFER,
|
|
4
5
|
readLengthAndStartIndex,
|
|
@@ -48,12 +49,12 @@ export abstract class StoredPackedArray<T> {
|
|
|
48
49
|
*/
|
|
49
50
|
protected readonly MAX_LENGTH: u64 = <u64>(u32.MAX_VALUE - 1);
|
|
50
51
|
|
|
51
|
-
protected constructor(public pointer: u16, public subPointer: Uint8Array) {
|
|
52
|
+
protected constructor(public pointer: u16, public subPointer: Uint8Array, protected defaultValue: T) {
|
|
52
53
|
assert(subPointer.length <= 30, `You must pass a 30 bytes sub-pointer. (Array, got ${subPointer.length})`);
|
|
53
54
|
|
|
54
55
|
const basePointer = encodeBasePointer(pointer, subPointer);
|
|
55
56
|
this.lengthPointer = Uint8Array.wrap(basePointer.buffer);
|
|
56
|
-
this.basePointer = basePointer;
|
|
57
|
+
this.basePointer = bigEndianAdd(basePointer, 1);
|
|
57
58
|
|
|
58
59
|
const storedLenStart = Blockchain.getStorageAt(basePointer);
|
|
59
60
|
const data = readLengthAndStartIndex(storedLenStart);
|
|
@@ -62,24 +63,70 @@ export abstract class StoredPackedArray<T> {
|
|
|
62
63
|
this._startIndex = data[1];
|
|
63
64
|
}
|
|
64
65
|
|
|
66
|
+
@inline
|
|
67
|
+
@operator('[]')
|
|
65
68
|
public get(index: u64): T {
|
|
69
|
+
// max length used on purpose to prevent unbounded usage
|
|
66
70
|
if (index > this.MAX_LENGTH) {
|
|
67
|
-
throw new Revert('get:
|
|
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 {
|
|
87
|
+
if (index > this.MAX_LENGTH) {
|
|
88
|
+
throw new Revert('get: index exceeds MAX_LENGTH (packed array)');
|
|
68
89
|
}
|
|
69
90
|
|
|
70
91
|
const cap = this.getSlotCapacity();
|
|
71
92
|
const slotIndex = index / cap;
|
|
72
93
|
const subIndex = <u32>(index % cap);
|
|
73
94
|
|
|
74
|
-
// Load the slot if not cached
|
|
75
95
|
const slotData = this.ensureSlot(slotIndex);
|
|
76
|
-
|
|
77
|
-
// Unpack and return the subIndex
|
|
78
96
|
const arr = this.unpackSlot(slotData);
|
|
97
|
+
|
|
79
98
|
return arr[subIndex];
|
|
80
99
|
}
|
|
81
100
|
|
|
101
|
+
@inline
|
|
102
|
+
@operator('[]=')
|
|
82
103
|
public set(index: u64, value: T): void {
|
|
104
|
+
if (index > this.MAX_LENGTH) {
|
|
105
|
+
throw new Revert('set: index exceeds MAX_LENGTH (packed array)');
|
|
106
|
+
}
|
|
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
|
+
|
|
83
130
|
const cap = this.getSlotCapacity();
|
|
84
131
|
const slotIndex = index / cap;
|
|
85
132
|
const subIndex = <u32>(index % cap);
|
|
@@ -95,15 +142,16 @@ export abstract class StoredPackedArray<T> {
|
|
|
95
142
|
}
|
|
96
143
|
}
|
|
97
144
|
|
|
98
|
-
|
|
145
|
+
@inline
|
|
146
|
+
public push(value: T, isPhysical: bool = false): void {
|
|
99
147
|
if (this._length >= this.MAX_LENGTH) {
|
|
100
148
|
throw new Revert('push: array has reached MAX_LENGTH');
|
|
101
149
|
}
|
|
102
150
|
|
|
103
|
-
const
|
|
151
|
+
const realIndex = ((isPhysical ? 0 : this._startIndex) + this._length) % this.MAX_LENGTH;
|
|
104
152
|
const cap = this.getSlotCapacity();
|
|
105
|
-
const slotIndex =
|
|
106
|
-
const subIndex = <u32>(
|
|
153
|
+
const slotIndex = realIndex / cap;
|
|
154
|
+
const subIndex = <u32>(realIndex % cap);
|
|
107
155
|
|
|
108
156
|
let slotData = this.ensureSlot(slotIndex);
|
|
109
157
|
const arr = this.unpackSlot(slotData);
|
|
@@ -119,11 +167,70 @@ export abstract class StoredPackedArray<T> {
|
|
|
119
167
|
this._isChangedLength = true;
|
|
120
168
|
}
|
|
121
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
|
+
|
|
122
205
|
/**
|
|
123
206
|
* "Delete" by zeroing out the element at `index`,
|
|
124
207
|
* but does not reduce the length.
|
|
125
208
|
*/
|
|
209
|
+
@inline
|
|
126
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 {
|
|
127
234
|
const cap = this.getSlotCapacity();
|
|
128
235
|
const slotIndex = index / cap;
|
|
129
236
|
const subIndex = <u32>(index % cap);
|
|
@@ -143,9 +250,10 @@ export abstract class StoredPackedArray<T> {
|
|
|
143
250
|
/**
|
|
144
251
|
* Remove the last element by zeroing it and decrementing length by 1.
|
|
145
252
|
*/
|
|
253
|
+
@inline
|
|
146
254
|
public deleteLast(): void {
|
|
147
255
|
if (this._length == 0) {
|
|
148
|
-
throw new Revert('deleteLast: array is empty');
|
|
256
|
+
throw new Revert('deleteLast: array is empty (packed array)');
|
|
149
257
|
}
|
|
150
258
|
|
|
151
259
|
const lastIndex = this._length - 1;
|
|
@@ -155,11 +263,13 @@ export abstract class StoredPackedArray<T> {
|
|
|
155
263
|
this._isChangedLength = true;
|
|
156
264
|
}
|
|
157
265
|
|
|
266
|
+
@inline
|
|
158
267
|
public setMultiple(startIndex: u64, values: T[]): void {
|
|
159
268
|
const end = startIndex + <u64>values.length;
|
|
160
269
|
if (end > this._length) {
|
|
161
|
-
throw new Revert('setMultiple: out of range');
|
|
270
|
+
throw new Revert('setMultiple: out of range (packed array)');
|
|
162
271
|
}
|
|
272
|
+
|
|
163
273
|
for (let i = 0; i < values.length; i++) {
|
|
164
274
|
this.set(startIndex + <u64>i, values[i]);
|
|
165
275
|
}
|
|
@@ -168,10 +278,10 @@ export abstract class StoredPackedArray<T> {
|
|
|
168
278
|
// -----------------------------------------------------------
|
|
169
279
|
// Public Array-Like Methods
|
|
170
280
|
// -----------------------------------------------------------
|
|
171
|
-
|
|
281
|
+
@inline
|
|
172
282
|
public getAll(startIndex: u64, count: u64): T[] {
|
|
173
283
|
if (count > <u64>u32.MAX_VALUE) {
|
|
174
|
-
throw new Revert('getAll: count too large');
|
|
284
|
+
throw new Revert('getAll: count too large (packed array)');
|
|
175
285
|
}
|
|
176
286
|
|
|
177
287
|
const out = new Array<T>(<i32>count);
|
|
@@ -182,14 +292,17 @@ export abstract class StoredPackedArray<T> {
|
|
|
182
292
|
return out;
|
|
183
293
|
}
|
|
184
294
|
|
|
295
|
+
@inline
|
|
185
296
|
public getLength(): u64 {
|
|
186
297
|
return this._length;
|
|
187
298
|
}
|
|
188
299
|
|
|
300
|
+
@inline
|
|
189
301
|
public startingIndex(): u64 {
|
|
190
302
|
return this._startIndex;
|
|
191
303
|
}
|
|
192
304
|
|
|
305
|
+
@inline
|
|
193
306
|
public setStartingIndex(index: u64): void {
|
|
194
307
|
this._startIndex = index;
|
|
195
308
|
this._isChangedStartIndex = true;
|
|
@@ -250,6 +363,9 @@ export abstract class StoredPackedArray<T> {
|
|
|
250
363
|
this._isChanged.clear();
|
|
251
364
|
}
|
|
252
365
|
|
|
366
|
+
/**
|
|
367
|
+
* Reset the array to its initial state.
|
|
368
|
+
*/
|
|
253
369
|
public reset(): void {
|
|
254
370
|
this._length = 0;
|
|
255
371
|
this._startIndex = 0;
|
|
@@ -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 {
|
|
@@ -59,6 +59,6 @@ export class StoredU128Array extends StoredPackedArray<u128> {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
protected calculateStoragePointer(slotIndex: u64): Uint8Array {
|
|
62
|
-
return bigEndianAdd(this.basePointer, slotIndex
|
|
62
|
+
return bigEndianAdd(this.basePointer, slotIndex);
|
|
63
63
|
}
|
|
64
64
|
}
|
|
@@ -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 {
|
|
@@ -53,6 +53,6 @@ export class StoredU16Array extends StoredPackedArray<u16> {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
protected calculateStoragePointer(slotIndex: u64): Uint8Array {
|
|
56
|
-
return bigEndianAdd(this.basePointer, slotIndex
|
|
56
|
+
return bigEndianAdd(this.basePointer, slotIndex);
|
|
57
57
|
}
|
|
58
58
|
}
|
|
@@ -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 {
|
|
@@ -34,6 +34,6 @@ export class StoredU256Array extends StoredPackedArray<u256> {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
protected calculateStoragePointer(slotIndex: u64): Uint8Array {
|
|
37
|
-
return bigEndianAdd(this.basePointer, slotIndex
|
|
37
|
+
return bigEndianAdd(this.basePointer, slotIndex);
|
|
38
38
|
}
|
|
39
39
|
}
|
|
@@ -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 {
|
|
@@ -52,6 +52,6 @@ export class StoredU32Array extends StoredPackedArray<u32> {
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
protected calculateStoragePointer(slotIndex: u64): Uint8Array {
|
|
55
|
-
return bigEndianAdd(this.basePointer, slotIndex
|
|
55
|
+
return bigEndianAdd(this.basePointer, slotIndex);
|
|
56
56
|
}
|
|
57
57
|
}
|
|
@@ -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 {
|
|
@@ -61,6 +61,6 @@ export class StoredU64Array extends StoredPackedArray<u64> {
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
protected calculateStoragePointer(slotIndex: u64): Uint8Array {
|
|
64
|
-
return bigEndianAdd(this.basePointer, slotIndex
|
|
64
|
+
return bigEndianAdd(this.basePointer, slotIndex);
|
|
65
65
|
}
|
|
66
66
|
}
|
|
@@ -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 {
|
|
@@ -43,6 +43,6 @@ export class StoredU8Array extends StoredPackedArray<u8> {
|
|
|
43
43
|
|
|
44
44
|
protected calculateStoragePointer(slotIndex: u64): Uint8Array {
|
|
45
45
|
// basePointer + (slotIndex+1) in big-endian
|
|
46
|
-
return bigEndianAdd(this.basePointer, slotIndex
|
|
46
|
+
return bigEndianAdd(this.basePointer, slotIndex);
|
|
47
47
|
}
|
|
48
48
|
}
|