@btc-vision/btc-runtime 1.3.15 → 1.3.17

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@btc-vision/btc-runtime",
3
- "version": "1.3.15",
3
+ "version": "1.3.17",
4
4
  "description": "Bitcoin Smart Contract Runtime",
5
5
  "main": "btc/index.ts",
6
6
  "scripts": {
@@ -1,10 +1,22 @@
1
- import { Address, ADDRESS_BYTE_LENGTH } from '../types/Address';
2
- import { Selector } from '../math/abi';
3
1
  import { i128, u128, u256 } from '@btc-vision/as-bignum/assembly';
4
- import { Revert } from '../types/Revert';
5
2
  import { TransactionInput, TransactionOutput } from '../env/classes/UTXO';
6
- import { i256 } from '../math/i256';
7
3
  import { AddressMap } from '../generic/AddressMap';
4
+ import { Selector } from '../math/abi';
5
+ import { i256 } from '../math/i256';
6
+ import { Address } from '../types/Address';
7
+ import { Revert } from '../types/Revert';
8
+ import {
9
+ ADDRESS_BYTE_LENGTH,
10
+ I128_BYTE_LENGTH,
11
+ I256_BYTE_LENGTH,
12
+ I64_BYTE_LENGTH,
13
+ U128_BYTE_LENGTH,
14
+ U16_BYTE_LENGTH,
15
+ U256_BYTE_LENGTH,
16
+ U32_BYTE_LENGTH,
17
+ U64_BYTE_LENGTH,
18
+ U8_BYTE_LENGTH,
19
+ } from '../utils/lengths';
8
20
 
9
21
  @final
10
22
  export class BytesReader {
@@ -17,41 +29,44 @@ export class BytesReader {
17
29
  }
18
30
 
19
31
  public readU8(): u8 {
20
- this.verifyEnd(this.currentOffset + 1);
32
+ this.verifyEnd(this.currentOffset + U8_BYTE_LENGTH);
33
+
34
+ const value = this.buffer.getUint8(this.currentOffset);
35
+ this.currentOffset += U8_BYTE_LENGTH;
21
36
 
22
- return this.buffer.getUint8(this.currentOffset++);
37
+ return value;
23
38
  }
24
39
 
25
40
  public readU16(): u16 {
26
- this.verifyEnd(this.currentOffset + 2);
41
+ this.verifyEnd(this.currentOffset + U16_BYTE_LENGTH);
27
42
 
28
43
  const value = this.buffer.getUint16(this.currentOffset, true);
29
- this.currentOffset += 2;
44
+ this.currentOffset += U16_BYTE_LENGTH;
30
45
 
31
46
  return value;
32
47
  }
33
48
 
34
49
  public readU32(le: boolean = true): u32 {
35
- this.verifyEnd(this.currentOffset + 4);
50
+ this.verifyEnd(this.currentOffset + U32_BYTE_LENGTH);
36
51
 
37
52
  const value = this.buffer.getUint32(this.currentOffset, le);
38
- this.currentOffset += 4;
53
+ this.currentOffset += U32_BYTE_LENGTH;
39
54
  return value;
40
55
  }
41
56
 
42
57
  public readU64(): u64 {
43
- this.verifyEnd(this.currentOffset + 8);
58
+ this.verifyEnd(this.currentOffset + U64_BYTE_LENGTH);
44
59
 
45
60
  const value = this.buffer.getUint64(this.currentOffset, true);
46
- this.currentOffset += 8;
61
+ this.currentOffset += U64_BYTE_LENGTH;
47
62
 
48
63
  return value;
49
64
  }
50
65
 
51
66
  public readU256(): u256 {
52
- this.verifyEnd(this.currentOffset + 32);
67
+ this.verifyEnd(this.currentOffset + U256_BYTE_LENGTH);
53
68
 
54
- const next32Bytes: u8[] = this.readBytesBE(32);
69
+ const next32Bytes: u8[] = this.readBytesBE(U256_BYTE_LENGTH);
55
70
 
56
71
  return u256.fromBytesBE(next32Bytes);
57
72
  }
@@ -67,26 +82,26 @@ export class BytesReader {
67
82
  }
68
83
 
69
84
  public readI64(): i64 {
70
- this.verifyEnd(this.currentOffset + 8);
85
+ this.verifyEnd(this.currentOffset + I64_BYTE_LENGTH);
71
86
 
72
87
  const value = this.buffer.getInt64(this.currentOffset, true);
73
- this.currentOffset += 8;
88
+ this.currentOffset += I64_BYTE_LENGTH;
74
89
 
75
90
  return value;
76
91
  }
77
92
 
78
93
  public readU128(): u128 {
79
- this.verifyEnd(this.currentOffset + 16);
94
+ this.verifyEnd(this.currentOffset + U128_BYTE_LENGTH);
80
95
 
81
- const next16Bytes: u8[] = this.readBytesBE(16);
96
+ const next16Bytes: u8[] = this.readBytesBE(U128_BYTE_LENGTH);
82
97
 
83
98
  return u128.fromBytesBE(next16Bytes);
84
99
  }
85
100
 
86
101
  public readI128(): i128 {
87
- this.verifyEnd(this.currentOffset + 16);
102
+ this.verifyEnd(this.currentOffset + I128_BYTE_LENGTH);
88
103
 
89
- const next16Bytes: u8[] = this.readBytesBE(16);
104
+ const next16Bytes: u8[] = this.readBytesBE(I128_BYTE_LENGTH);
90
105
 
91
106
  return i128.fromBytesBE(next16Bytes);
92
107
  }
@@ -173,9 +188,9 @@ export class BytesReader {
173
188
  }
174
189
 
175
190
  public readI256(): i256 {
176
- this.verifyEnd(this.currentOffset + 32);
191
+ this.verifyEnd(this.currentOffset + I256_BYTE_LENGTH);
177
192
 
178
- const next32Bytes: u8[] = this.readBytesBE(32);
193
+ const next32Bytes: u8[] = this.readBytesBE(I256_BYTE_LENGTH);
179
194
 
180
195
  return i256.fromBytesBE(next32Bytes);
181
196
  }
@@ -1,11 +1,22 @@
1
1
  import { i128, u128, u256 } from '@btc-vision/as-bignum/assembly';
2
- import { Address, ADDRESS_BYTE_LENGTH } from '../types/Address';
3
- import { Selector } from '../math/abi';
4
- import { BytesReader } from './BytesReader';
5
- import { Revert } from '../types/Revert';
6
2
  import { ArrayBuffer } from 'arraybuffer';
7
- import { i256 } from '../math/i256';
8
3
  import { AddressMap } from '../generic/AddressMap';
4
+ import { Selector } from '../math/abi';
5
+ import { i256 } from '../math/i256';
6
+ import { Address } from '../types/Address';
7
+ import { Revert } from '../types/Revert';
8
+ import {
9
+ ADDRESS_BYTE_LENGTH,
10
+ I128_BYTE_LENGTH,
11
+ I256_BYTE_LENGTH,
12
+ U128_BYTE_LENGTH,
13
+ U16_BYTE_LENGTH,
14
+ U256_BYTE_LENGTH,
15
+ U32_BYTE_LENGTH,
16
+ U64_BYTE_LENGTH,
17
+ U8_BYTE_LENGTH,
18
+ } from '../utils/lengths';
19
+ import { BytesReader } from './BytesReader';
9
20
 
10
21
  @final
11
22
  export class BytesWriter {
@@ -24,26 +35,27 @@ export class BytesWriter {
24
35
  }
25
36
 
26
37
  public writeU8(value: u8): void {
27
- this.allocSafe(1);
28
- this.buffer.setUint8(this.currentOffset++, value);
38
+ this.allocSafe(U8_BYTE_LENGTH);
39
+ this.buffer.setUint8(this.currentOffset, value);
40
+ this.currentOffset += U8_BYTE_LENGTH;
29
41
  }
30
42
 
31
43
  public writeU16(value: u16): void {
32
- this.allocSafe(2);
44
+ this.allocSafe(U16_BYTE_LENGTH);
33
45
  this.buffer.setUint16(this.currentOffset, value, true);
34
- this.currentOffset += 2;
46
+ this.currentOffset += U16_BYTE_LENGTH;
35
47
  }
36
48
 
37
49
  public writeU32(value: u32, le: boolean = true): void {
38
- this.allocSafe(4);
50
+ this.allocSafe(U32_BYTE_LENGTH);
39
51
  this.buffer.setUint32(this.currentOffset, value, le);
40
- this.currentOffset += 4;
52
+ this.currentOffset += U32_BYTE_LENGTH;
41
53
  }
42
54
 
43
55
  public writeU64(value: u64): void {
44
- this.allocSafe(8);
56
+ this.allocSafe(U64_BYTE_LENGTH);
45
57
  this.buffer.setUint64(this.currentOffset, value || 0, true);
46
- this.currentOffset += 8;
58
+ this.currentOffset += U64_BYTE_LENGTH;
47
59
  }
48
60
 
49
61
  public writeAddressArray(value: Address[]): void {
@@ -65,10 +77,10 @@ export class BytesWriter {
65
77
  }
66
78
 
67
79
  public writeI256(value: i256): void {
68
- this.allocSafe(32);
80
+ this.allocSafe(I256_BYTE_LENGTH);
69
81
 
70
82
  const bytes = value.toUint8Array(true);
71
- for (let i: i32 = 0; i < 32; i++) {
83
+ for (let i: i32 = 0; i < I256_BYTE_LENGTH; i++) {
72
84
  this.writeU8(bytes[i] || 0);
73
85
  }
74
86
  }
@@ -78,34 +90,34 @@ export class BytesWriter {
78
90
  }
79
91
 
80
92
  public writeU256(value: u256): void {
81
- this.allocSafe(32);
93
+ this.allocSafe(U256_BYTE_LENGTH);
82
94
 
83
95
  const bytes = value.toUint8Array(true);
84
- for (let i: i32 = 0; i < 32; i++) {
96
+ for (let i: i32 = 0; i < U256_BYTE_LENGTH; i++) {
85
97
  this.writeU8(bytes[i] || 0);
86
98
  }
87
99
  }
88
100
 
89
101
  public writeI128(value: i128): void {
90
- this.allocSafe(32);
102
+ this.allocSafe(I128_BYTE_LENGTH);
91
103
 
92
104
  const bytes = value.toUint8Array(true);
93
- for (let i: i32 = 0; i < 32; i++) {
105
+ for (let i: i32 = 0; i < I128_BYTE_LENGTH; i++) {
94
106
  this.writeU8(bytes[i] || 0);
95
107
  }
96
108
  }
97
109
 
98
110
  public writeU128(value: u128): void {
99
- this.allocSafe(16);
111
+ this.allocSafe(U128_BYTE_LENGTH);
100
112
 
101
113
  const bytes = value.toUint8Array(true);
102
- for (let i: i32 = 0; i < 16; i++) {
114
+ for (let i: i32 = 0; i < U128_BYTE_LENGTH; i++) {
103
115
  this.writeU8(bytes[i] || 0);
104
116
  }
105
117
  }
106
118
 
107
119
  public writeTuple(value: u256[]): void {
108
- this.allocSafe(4 + value.length * 32);
120
+ this.allocSafe(U32_BYTE_LENGTH + value.length * U256_BYTE_LENGTH);
109
121
  this.writeU32(u32(value.length));
110
122
 
111
123
  for (let i = 0; i < value.length; i++) {
@@ -116,8 +128,8 @@ export class BytesWriter {
116
128
  public writeU128Array(value: u128[]): void {
117
129
  if (value.length > 65535) throw new Revert('Array size is too large');
118
130
 
119
- this.allocSafe(2 + value.length * 16);
120
- this.writeU32(u16(value.length));
131
+ this.allocSafe(U16_BYTE_LENGTH + value.length * U128_BYTE_LENGTH);
132
+ this.writeU16(u16(value.length));
121
133
 
122
134
  for (let i = 0; i < value.length; i++) {
123
135
  this.writeU128(value[i]);
@@ -144,7 +156,7 @@ export class BytesWriter {
144
156
  public writeBytesWithLength(value: Uint8Array): void {
145
157
  const length: u32 = u32(value.length);
146
158
 
147
- this.allocSafe(length + 4);
159
+ this.allocSafe(length + U32_BYTE_LENGTH);
148
160
  this.writeU32(length);
149
161
 
150
162
  for (let i: u32 = 0; i < length; i++) {
@@ -172,7 +184,7 @@ export class BytesWriter {
172
184
  public writeAddressValueTupleMap(map: AddressMap<u256>): void {
173
185
  if (map.size > 65535) throw new Revert('Map size is too large');
174
186
 
175
- /*const requiredSize: u32 = 2 + map.size * (ADDRESS_BYTE_LENGTH + 32);
187
+ /*const requiredSize: u32 = U16_BYTE_LENGTH + map.size * (ADDRESS_BYTE_LENGTH + U256_BYTE_LENGTH);
176
188
 
177
189
  if (this.buffer.byteLength < requiredSize) {
178
190
  abort(
@@ -195,7 +207,7 @@ export class BytesWriter {
195
207
  public writeLimitedAddressBytesMap(map: AddressMap<Uint8Array[]>): void {
196
208
  if (map.size > 8) throw new Revert('Too many contract called.'); // no more than 8 different contracts.
197
209
 
198
- /*let requiredSize: u32 = 1 + (map.size * ADDRESS_BYTE_LENGTH + 1);
210
+ /*let requiredSize: u32 = U8_BYTE_LENGTH + (map.size * ADDRESS_BYTE_LENGTH + U8_BYTE_LENGTH);
199
211
 
200
212
 
201
213
  for (let i = 0; i < map.size; i++) {
@@ -296,7 +308,9 @@ export class BytesWriter {
296
308
 
297
309
  private resize(size: u32): void {
298
310
  abort(
299
- `Buffer is getting resized. This is very bad for performance. Expected size: ${this.buffer.byteLength + size} - Current size: ${this.buffer.byteLength}`,
311
+ `Buffer is getting resized. This is very bad for performance. Expected size: ${
312
+ this.buffer.byteLength + size
313
+ } - Current size: ${this.buffer.byteLength}`,
300
314
  );
301
315
 
302
316
  /*const buf: Uint8Array = new Uint8Array(u32(this.buffer.byteLength) + size);
@@ -12,6 +12,7 @@ import { Revert } from '../types/Revert';
12
12
  import { SafeMath } from '../types/SafeMath';
13
13
 
14
14
  import { Calldata } from '../types';
15
+ import { BOOLEAN_BYTE_LENGTH, U256_BYTE_LENGTH } from '../utils/lengths';
15
16
  import { IOP_20 } from './interfaces/IOP_20';
16
17
  import { OP20InitParameters } from './interfaces/OP20InitParameters';
17
18
  import { OP_NET } from './OP_NET';
@@ -100,7 +101,7 @@ export abstract class DeployableOP_20 extends OP_NET implements IOP_20 {
100
101
 
101
102
  /** METHODS */
102
103
  public allowance(callData: Calldata): BytesWriter {
103
- const response = new BytesWriter(32);
104
+ const response = new BytesWriter(U256_BYTE_LENGTH);
104
105
 
105
106
  const resp = this._allowance(callData.readAddress(), callData.readAddress());
106
107
  response.writeU256(resp);
@@ -115,7 +116,7 @@ export abstract class DeployableOP_20 extends OP_NET implements IOP_20 {
115
116
  const value = callData.readU256();
116
117
 
117
118
  // Response buffer
118
- const response = new BytesWriter(1);
119
+ const response = new BytesWriter(BOOLEAN_BYTE_LENGTH);
119
120
 
120
121
  const resp = this._approve(owner, spender, value);
121
122
  response.writeBoolean(resp);
@@ -124,7 +125,7 @@ export abstract class DeployableOP_20 extends OP_NET implements IOP_20 {
124
125
  }
125
126
 
126
127
  public balanceOf(callData: Calldata): BytesWriter {
127
- const response = new BytesWriter(32);
128
+ const response = new BytesWriter(U256_BYTE_LENGTH);
128
129
  const address: Address = callData.readAddress();
129
130
  const resp = this._balanceOf(address);
130
131
 
@@ -134,7 +135,7 @@ export abstract class DeployableOP_20 extends OP_NET implements IOP_20 {
134
135
  }
135
136
 
136
137
  public burn(callData: Calldata): BytesWriter {
137
- const response = new BytesWriter(1);
138
+ const response = new BytesWriter(BOOLEAN_BYTE_LENGTH);
138
139
  const resp = this._burn(callData.readU256());
139
140
  response.writeBoolean(resp);
140
141
 
@@ -142,7 +143,7 @@ export abstract class DeployableOP_20 extends OP_NET implements IOP_20 {
142
143
  }
143
144
 
144
145
  public transfer(callData: Calldata): BytesWriter {
145
- const response = new BytesWriter(1);
146
+ const response = new BytesWriter(BOOLEAN_BYTE_LENGTH);
146
147
  const resp = this._transfer(callData.readAddress(), callData.readU256());
147
148
 
148
149
  response.writeBoolean(resp);
@@ -151,7 +152,7 @@ export abstract class DeployableOP_20 extends OP_NET implements IOP_20 {
151
152
  }
152
153
 
153
154
  public transferFrom(callData: Calldata): BytesWriter {
154
- const response = new BytesWriter(1);
155
+ const response = new BytesWriter(BOOLEAN_BYTE_LENGTH);
155
156
  const resp = this._transferFrom(
156
157
  callData.readAddress(),
157
158
  callData.readAddress(),
@@ -168,7 +169,7 @@ export abstract class DeployableOP_20 extends OP_NET implements IOP_20 {
168
169
 
169
170
  switch (method) {
170
171
  case encodeSelector('decimals'):
171
- response = new BytesWriter(1);
172
+ response = new BytesWriter(BOOLEAN_BYTE_LENGTH);
172
173
  response.writeU8(this.decimals);
173
174
  break;
174
175
  case encodeSelector('name'):
@@ -180,11 +181,11 @@ export abstract class DeployableOP_20 extends OP_NET implements IOP_20 {
180
181
  response.writeStringWithLength(this.symbol);
181
182
  break;
182
183
  case encodeSelector('totalSupply'):
183
- response = new BytesWriter(32);
184
+ response = new BytesWriter(U256_BYTE_LENGTH);
184
185
  response.writeU256(this.totalSupply);
185
186
  break;
186
187
  case encodeSelector('maximumSupply'):
187
- response = new BytesWriter(32);
188
+ response = new BytesWriter(U256_BYTE_LENGTH);
188
189
  response.writeU256(this.maxSupply);
189
190
  break;
190
191
  case encodeSelector('allowance'):
@@ -1,11 +1,12 @@
1
- import { IBTC } from '../interfaces/IBTC';
2
- import { Address, ADDRESS_BYTE_LENGTH } from '../types/Address';
3
- import { Blockchain } from '../env';
4
1
  import { BytesWriter } from '../buffer/BytesWriter';
5
- import { encodeSelector, Selector } from '../math/abi';
6
- import { Revert } from '../types/Revert';
2
+ import { Blockchain } from '../env';
7
3
  import { MAX_EVENT_DATA_SIZE, NetEvent } from '../events/NetEvent';
4
+ import { IBTC } from '../interfaces/IBTC';
5
+ import { encodeSelector, Selector } from '../math/abi';
8
6
  import { Calldata } from '../types';
7
+ import { Address } from '../types/Address';
8
+ import { Revert } from '../types/Revert';
9
+ import { ADDRESS_BYTE_LENGTH } from '../utils/lengths';
9
10
 
10
11
  export class OP_NET implements IBTC {
11
12
  public get address(): Address {
@@ -1,30 +1,29 @@
1
- import { Address, ADDRESS_BYTE_LENGTH } from '../types/Address';
2
- import { MemorySlotPointer } from '../memory/MemorySlotPointer';
3
- import { MemorySlotData } from '../memory/MemorySlot';
4
1
  import { u256 } from '@btc-vision/as-bignum/assembly';
5
2
  import { BytesReader } from '../buffer/BytesReader';
6
3
  import { BytesWriter } from '../buffer/BytesWriter';
4
+ import { OP_NET } from '../contracts/OP_NET';
7
5
  import { NetEvent } from '../events/NetEvent';
6
+ import { MapU256 } from '../generic/MapU256';
7
+ import { DeployContractResponse } from '../interfaces/DeployContractResponse';
8
8
  import { Potential } from '../lang/Definitions';
9
- import { OP_NET } from '../contracts/OP_NET';
9
+ import { MemorySlotData } from '../memory/MemorySlot';
10
+ import { MemorySlotPointer } from '../memory/MemorySlotPointer';
10
11
  import { PointerStorage } from '../types';
12
+ import { Address } from '../types/Address';
13
+ import { ADDRESS_BYTE_LENGTH, U256_BYTE_LENGTH } from '../utils/lengths';
14
+ import { Block } from './classes/Block';
15
+ import { Transaction } from './classes/Transaction';
11
16
  import {
12
17
  callContract,
13
- deploy,
14
18
  deployFromAddress,
15
19
  emit,
16
20
  encodeAddress,
17
21
  loadPointer,
18
22
  log,
19
- nextPointerGreaterThan,
20
23
  storePointer,
21
24
  validateBitcoinAddress,
22
25
  verifySchnorrSignature,
23
26
  } from './global';
24
- import { DeployContractResponse } from '../interfaces/DeployContractResponse';
25
- import { MapU256 } from '../generic/MapU256';
26
- import { Block } from './classes/Block';
27
- import { Transaction } from './classes/Transaction';
28
27
 
29
28
  export * from '../env/global';
30
29
 
@@ -186,8 +185,8 @@ export class BlockchainEnvironment {
186
185
  return reader.readAddress();
187
186
  }
188
187
 
189
- public deployContract(hash: u256, bytecode: Uint8Array): DeployContractResponse {
190
- const writer = new BytesWriter(32 + bytecode.length);
188
+ /*public deployContract(hash: u256, bytecode: Uint8Array): DeployContractResponse {
189
+ const writer = new BytesWriter(U256_BYTE_LENGTH + bytecode.length);
191
190
  writer.writeU256(hash);
192
191
  writer.writeBytes(bytecode);
193
192
 
@@ -199,13 +198,13 @@ export class BlockchainEnvironment {
199
198
  const contractAddress: Address = reader.readAddress();
200
199
 
201
200
  return new DeployContractResponse(virtualAddress, contractAddress);
202
- }
201
+ }*/
203
202
 
204
203
  public deployContractFromExisting(
205
204
  existingAddress: Address,
206
205
  salt: u256,
207
206
  ): DeployContractResponse {
208
- const writer = new BytesWriter(ADDRESS_BYTE_LENGTH + 32);
207
+ const writer = new BytesWriter(ADDRESS_BYTE_LENGTH + U256_BYTE_LENGTH);
209
208
  writer.writeAddress(existingAddress);
210
209
  writer.writeU256(salt);
211
210
 
@@ -220,6 +219,7 @@ export class BlockchainEnvironment {
220
219
  return new DeployContractResponse(virtualAddress, contractAddress);
221
220
  }
222
221
 
222
+ // TODO: Change MemorySlotData type to a Uint8Array instead of a u256.
223
223
  public getStorageAt(
224
224
  pointerHash: MemorySlotPointer,
225
225
  defaultValue: MemorySlotData<u256>,
@@ -233,12 +233,12 @@ export class BlockchainEnvironment {
233
233
  return defaultValue;
234
234
  }
235
235
 
236
- public getNextPointerGreaterThan(
236
+ /*public getNextPointerGreaterThan(
237
237
  targetPointer: MemorySlotPointer,
238
238
  valueAtLeast: u256,
239
239
  lte: boolean = true,
240
240
  ): MemorySlotData<u256> {
241
- const writer = new BytesWriter(65);
241
+ const writer = new BytesWriter(U256_BYTE_LENGTH * 2 + BOOLEAN_BYTE_LENGTH);
242
242
  writer.writeU256(targetPointer);
243
243
  writer.writeU256(valueAtLeast);
244
244
  writer.writeBoolean(lte);
@@ -247,14 +247,14 @@ export class BlockchainEnvironment {
247
247
  const reader: BytesReader = new BytesReader(result);
248
248
 
249
249
  return reader.readU256();
250
- }
250
+ }*/
251
251
 
252
252
  public verifySchnorrSignature(
253
253
  publicKey: Address,
254
254
  signature: Uint8Array,
255
255
  hash: Uint8Array,
256
256
  ): boolean {
257
- const writer = new BytesWriter(128);
257
+ const writer = new BytesWriter(ADDRESS_BYTE_LENGTH + 64 + 32);
258
258
  writer.writeBytes(publicKey);
259
259
  writer.writeBytes(signature);
260
260
  writer.writeBytes(hash);
@@ -265,6 +265,7 @@ export class BlockchainEnvironment {
265
265
  return reader.readBoolean();
266
266
  }
267
267
 
268
+ // TODO: Change MemorySlotData type to a Uint8Array instead of a u256.
268
269
  public hasStorageAt(pointerHash: MemorySlotPointer): bool {
269
270
  // We mark zero as the default value for the storage, if something is 0, the storage slot get deleted or is non-existent
270
271
  const val: u256 = this.getStorageAt(pointerHash, u256.Zero);
@@ -293,7 +294,7 @@ export class BlockchainEnvironment {
293
294
  private _internalSetStorageAt(pointerHash: u256, value: MemorySlotData<u256>): void {
294
295
  this.storage.set(pointerHash, value);
295
296
 
296
- const writer: BytesWriter = new BytesWriter(64);
297
+ const writer: BytesWriter = new BytesWriter(U256_BYTE_LENGTH * 2);
297
298
  writer.writeU256(pointerHash);
298
299
  writer.writeU256(value);
299
300
 
@@ -307,7 +308,7 @@ export class BlockchainEnvironment {
307
308
  }
308
309
 
309
310
  // we attempt to load the requested pointer.
310
- const writer = new BytesWriter(32);
311
+ const writer = new BytesWriter(U256_BYTE_LENGTH);
311
312
  writer.writeU256(pointer);
312
313
 
313
314
  const result: Uint8Array = loadPointer(writer.getBuffer());
@@ -1,12 +1,13 @@
1
1
  import { u256 } from '@btc-vision/as-bignum/assembly';
2
- import { Address, ADDRESS_BYTE_LENGTH } from '../../types/Address';
3
- import { NetEvent } from '../NetEvent';
4
2
  import { BytesWriter } from '../../buffer/BytesWriter';
3
+ import { Address } from '../../types/Address';
4
+ import { ADDRESS_BYTE_LENGTH, U256_BYTE_LENGTH } from '../../utils/lengths';
5
+ import { NetEvent } from '../NetEvent';
5
6
 
6
7
  @final
7
8
  export class ApproveEvent extends NetEvent {
8
9
  constructor(owner: Address, spender: Address, value: u256) {
9
- const data: BytesWriter = new BytesWriter(ADDRESS_BYTE_LENGTH * 2 + 32);
10
+ const data: BytesWriter = new BytesWriter(ADDRESS_BYTE_LENGTH * 2 + U256_BYTE_LENGTH);
10
11
  data.writeAddress(owner);
11
12
  data.writeAddress(spender);
12
13
  data.writeU256(value);
@@ -1,11 +1,12 @@
1
1
  import { u256 } from '@btc-vision/as-bignum/assembly';
2
- import { NetEvent } from '../NetEvent';
3
2
  import { BytesWriter } from '../../buffer/BytesWriter';
3
+ import { U256_BYTE_LENGTH } from '../../utils/lengths';
4
+ import { NetEvent } from '../NetEvent';
4
5
 
5
6
  @final
6
7
  export class BurnEvent extends NetEvent {
7
8
  constructor(amount: u256) {
8
- const data: BytesWriter = new BytesWriter(32);
9
+ const data: BytesWriter = new BytesWriter(U256_BYTE_LENGTH);
9
10
  data.writeU256(amount);
10
11
 
11
12
  super('Burn', data);
@@ -1,11 +1,12 @@
1
1
  import { u256 } from '@btc-vision/as-bignum/assembly';
2
- import { NetEvent } from '../NetEvent';
3
2
  import { BytesWriter } from '../../buffer/BytesWriter';
3
+ import { U256_BYTE_LENGTH } from '../../utils/lengths';
4
+ import { NetEvent } from '../NetEvent';
4
5
 
5
6
  @final
6
7
  export class ClaimEvent extends NetEvent {
7
8
  constructor(amount: u256) {
8
- const data: BytesWriter = new BytesWriter(32);
9
+ const data: BytesWriter = new BytesWriter(U256_BYTE_LENGTH);
9
10
  data.writeU256(amount);
10
11
 
11
12
  super('Claim', data);
@@ -1,12 +1,13 @@
1
1
  import { u256 } from '@btc-vision/as-bignum/assembly';
2
- import { NetEvent } from '../NetEvent';
3
2
  import { BytesWriter } from '../../buffer/BytesWriter';
4
- import { Address, ADDRESS_BYTE_LENGTH } from '../../types/Address';
3
+ import { Address } from '../../types/Address';
4
+ import { ADDRESS_BYTE_LENGTH, U256_BYTE_LENGTH } from '../../utils/lengths';
5
+ import { NetEvent } from '../NetEvent';
5
6
 
6
7
  @final
7
8
  export class MintEvent extends NetEvent {
8
9
  constructor(address: Address, amount: u256) {
9
- const data: BytesWriter = new BytesWriter(32 + ADDRESS_BYTE_LENGTH);
10
+ const data: BytesWriter = new BytesWriter(ADDRESS_BYTE_LENGTH + U256_BYTE_LENGTH);
10
11
 
11
12
  data.writeAddress(address);
12
13
  data.writeU256(amount);
@@ -1,11 +1,12 @@
1
1
  import { u256 } from '@btc-vision/as-bignum/assembly';
2
- import { NetEvent } from '../NetEvent';
3
2
  import { BytesWriter } from '../../buffer/BytesWriter';
3
+ import { U256_BYTE_LENGTH } from '../../utils/lengths';
4
+ import { NetEvent } from '../NetEvent';
4
5
 
5
6
  @final
6
7
  export class StakeEvent extends NetEvent {
7
8
  constructor(amount: u256) {
8
- const data: BytesWriter = new BytesWriter(32);
9
+ const data: BytesWriter = new BytesWriter(U256_BYTE_LENGTH);
9
10
  data.writeU256(amount);
10
11
 
11
12
  super('Stake', data);
@@ -1,12 +1,13 @@
1
1
  import { u256 } from '@btc-vision/as-bignum/assembly';
2
- import { NetEvent } from '../NetEvent';
3
- import { Address, ADDRESS_BYTE_LENGTH } from '../../types/Address';
4
2
  import { BytesWriter } from '../../buffer/BytesWriter';
3
+ import { Address } from '../../types/Address';
4
+ import { ADDRESS_BYTE_LENGTH, U256_BYTE_LENGTH } from '../../utils/lengths';
5
+ import { NetEvent } from '../NetEvent';
5
6
 
6
7
  @final
7
8
  export class TransferEvent extends NetEvent {
8
9
  constructor(from: Address, to: Address, amount: u256) {
9
- const data: BytesWriter = new BytesWriter(ADDRESS_BYTE_LENGTH * 2 + 32);
10
+ const data: BytesWriter = new BytesWriter(ADDRESS_BYTE_LENGTH * 2 + U256_BYTE_LENGTH);
10
11
  data.writeAddress(from);
11
12
  data.writeAddress(to);
12
13
  data.writeU256(amount);
@@ -1,11 +1,12 @@
1
1
  import { u256 } from '@btc-vision/as-bignum/assembly';
2
- import { NetEvent } from '../NetEvent';
3
2
  import { BytesWriter } from '../../buffer/BytesWriter';
3
+ import { U256_BYTE_LENGTH } from '../../utils/lengths';
4
+ import { NetEvent } from '../NetEvent';
4
5
 
5
6
  @final
6
7
  export class UnstakeEvent extends NetEvent {
7
8
  constructor(amount: u256) {
8
- const data: BytesWriter = new BytesWriter(32);
9
+ const data: BytesWriter = new BytesWriter(U256_BYTE_LENGTH);
9
10
  data.writeU256(amount);
10
11
 
11
12
  super('Unstake', data);
package/runtime/index.ts CHANGED
@@ -70,6 +70,7 @@ export * from './storage/StoredString';
70
70
  export * from './storage/StoredAddress';
71
71
  export * from './storage/StoredBoolean';
72
72
  export * from './storage/Serializable';
73
+ export * from './storage/StoredAddressArray';
73
74
 
74
75
  export * from './storage/StorageBacked';
75
76
  export * from './storage/StorageSlot';
@@ -1,8 +1,9 @@
1
- import { Address, ADDRESS_BYTE_LENGTH } from '../types/Address';
2
1
  import { u256 } from '@btc-vision/as-bignum/assembly';
3
2
  import { BytesWriter } from '../buffer/BytesWriter';
4
3
  import { Blockchain } from '../env';
5
4
  import { encodeSelector, Selector } from '../math/abi';
5
+ import { Address } from '../types/Address';
6
+ import { ADDRESS_BYTE_LENGTH, SELECTOR_BYTE_LENGTH } from '../utils/lengths';
6
7
 
7
8
  export class OP20Utils {
8
9
  public static get BALANCE_OF_SELECTOR(): Selector {
@@ -10,7 +11,7 @@ export class OP20Utils {
10
11
  }
11
12
 
12
13
  public static balanceOf(token: Address, owner: Address): u256 {
13
- const calldata: BytesWriter = new BytesWriter(4 + ADDRESS_BYTE_LENGTH);
14
+ const calldata: BytesWriter = new BytesWriter(SELECTOR_BYTE_LENGTH + ADDRESS_BYTE_LENGTH);
14
15
  calldata.writeSelector(OP20Utils.BALANCE_OF_SELECTOR);
15
16
  calldata.writeAddress(owner);
16
17
 
@@ -1,9 +1,10 @@
1
1
  import { u256 } from '@btc-vision/as-bignum/assembly';
2
- import { encodeSelector, Selector } from '../math/abi';
3
- import { Address, ADDRESS_BYTE_LENGTH } from '../types/Address';
4
2
  import { BytesWriter } from '../buffer/BytesWriter';
5
3
  import { Blockchain } from '../env';
4
+ import { encodeSelector, Selector } from '../math/abi';
5
+ import { Address } from '../types/Address';
6
6
  import { Revert } from '../types/Revert';
7
+ import { ADDRESS_BYTE_LENGTH, SELECTOR_BYTE_LENGTH, U256_BYTE_LENGTH } from '../utils/lengths';
7
8
 
8
9
  export class TransferHelper {
9
10
  public static get APPROVE_SELECTOR(): Selector {
@@ -19,7 +20,9 @@ export class TransferHelper {
19
20
  }
20
21
 
21
22
  public static safeApprove(token: Address, spender: Address, amount: u256): void {
22
- const calldata = new BytesWriter(4 + ADDRESS_BYTE_LENGTH + 32);
23
+ const calldata = new BytesWriter(
24
+ SELECTOR_BYTE_LENGTH + ADDRESS_BYTE_LENGTH + U256_BYTE_LENGTH,
25
+ );
23
26
  calldata.writeSelector(this.APPROVE_SELECTOR);
24
27
  calldata.writeAddress(spender);
25
28
  calldata.writeU256(amount);
@@ -33,7 +36,9 @@ export class TransferHelper {
33
36
  }
34
37
 
35
38
  public static safeTransfer(token: Address, to: Address, amount: u256): void {
36
- const calldata = new BytesWriter(4 + ADDRESS_BYTE_LENGTH + 32);
39
+ const calldata = new BytesWriter(
40
+ SELECTOR_BYTE_LENGTH + ADDRESS_BYTE_LENGTH + U256_BYTE_LENGTH,
41
+ );
37
42
  calldata.writeSelector(this.TRANSFER_SELECTOR);
38
43
  calldata.writeAddress(to);
39
44
  calldata.writeU256(amount);
@@ -47,9 +52,10 @@ export class TransferHelper {
47
52
  }
48
53
 
49
54
  public static safeTransferFrom(token: Address, from: Address, to: Address, amount: u256): void {
50
- const calldata = new BytesWriter(4 + ADDRESS_BYTE_LENGTH + ADDRESS_BYTE_LENGTH + 32);
55
+ const calldata = new BytesWriter(
56
+ SELECTOR_BYTE_LENGTH + ADDRESS_BYTE_LENGTH * 2 + U256_BYTE_LENGTH,
57
+ );
51
58
  calldata.writeSelector(this.TRANSFER_FROM_SELECTOR);
52
-
53
59
  calldata.writeAddress(from);
54
60
  calldata.writeAddress(to);
55
61
  calldata.writeU256(amount);
@@ -1,10 +1,11 @@
1
1
  import { u256 } from '@btc-vision/as-bignum/assembly';
2
+ import { BytesReader } from '../buffer/BytesReader';
3
+ import { BytesWriter } from '../buffer/BytesWriter';
2
4
  import { Blockchain } from '../env';
5
+ import { encodePointer } from '../math/abi';
3
6
  import { MemorySlotPointer } from '../memory/MemorySlotPointer';
4
- import { BytesWriter } from '../buffer/BytesWriter';
5
- import { BytesReader } from '../buffer/BytesReader';
6
7
  import { Revert } from '../types/Revert';
7
- import { encodePointer } from '../math/abi';
8
+ import { U256_BYTE_LENGTH } from '../utils/lengths';
8
9
 
9
10
  // Similar to a struct in Solidity. (Use in worst case scenario, consume a lot of gas)
10
11
  export abstract class Serializable {
@@ -99,7 +100,7 @@ export abstract class Serializable {
99
100
  }
100
101
 
101
102
  protected getPointer(subPointer: u256, index: u8): u256 {
102
- const writer = new BytesWriter(32);
103
+ const writer = new BytesWriter(U256_BYTE_LENGTH);
103
104
  writer.writeU256(subPointer);
104
105
 
105
106
  // Discard the first byte for offset.
@@ -1,7 +1,7 @@
1
1
  import { u256 } from '@btc-vision/as-bignum/assembly';
2
+ import { BytesWriter } from '../buffer/BytesWriter';
2
3
  import { Blockchain } from '../env';
3
4
  import { encodePointer } from '../math/abi';
4
- import { BytesWriter } from '../buffer/BytesWriter';
5
5
  import { Address } from '../types/Address';
6
6
 
7
7
  @final
@@ -9,10 +9,7 @@ export class StoredAddress {
9
9
  private readonly addressPointer: u256;
10
10
  private readonly defaultValue: u256;
11
11
 
12
- constructor(
13
- public pointer: u16,
14
- defaultValue: Address,
15
- ) {
12
+ constructor(public pointer: u16, defaultValue: Address) {
16
13
  const writer = new BytesWriter(32);
17
14
 
18
15
  this.defaultValue = u256.fromBytes(defaultValue);
@@ -1,13 +1,14 @@
1
1
  import { u256 } from '@btc-vision/as-bignum/assembly';
2
- import { Blockchain } from '../env';
3
2
  import { BytesWriter } from '../buffer/BytesWriter';
4
- import { SafeMath } from '../types/SafeMath';
3
+ import { Blockchain } from '../env';
5
4
  import { Address } from '../types/Address';
6
5
  import { Revert } from '../types/Revert';
6
+ import { SafeMath } from '../types/SafeMath';
7
7
 
8
8
  /**
9
9
  * @class StoredAddressArray
10
- * @description Manages an array of u256 values across multiple storage slots. Each slot holds one u256 value.
10
+ * @description Manages an array of Address values across multiple storage slots.
11
+ * Each slot holds one Address (stored as u256 in storage).
11
12
  */
12
13
  @final
13
14
  export class StoredAddressArray {
@@ -15,7 +16,7 @@ export class StoredAddressArray {
15
16
  private readonly lengthPointer: u256;
16
17
 
17
18
  // Internal cache for storage slots
18
- private _values: Map<u64, Address> = new Map(); // Map from slotIndex to u256 value
19
+ private _values: Map<u64, Address> = new Map(); // Map from slotIndex to Address value
19
20
  private _isLoaded: Set<u64> = new Set(); // Set of slotIndexes that are loaded
20
21
  private _isChanged: Set<u64> = new Set(); // Set of slotIndexes that are modified
21
22
 
@@ -26,25 +27,20 @@ export class StoredAddressArray {
26
27
  private _isChangedStartIndex: bool = false; // Indicates if the startIndex has been modified
27
28
 
28
29
  // Define a maximum allowed length to prevent excessive storage usage
29
- private readonly MAX_LENGTH: u64 = u64(u32.MAX_VALUE - 1); // we need to check what happen in overflow situation to be able to set it to u64.MAX_VALUE
30
+ private readonly MAX_LENGTH: u64 = u64(u32.MAX_VALUE - 1);
30
31
 
31
32
  /**
32
33
  * @constructor
33
34
  * @param {u16} pointer - The primary pointer identifier.
34
35
  * @param {Uint8Array} subPointer - The sub-pointer for memory slot addressing.
35
- * @param {u256} defaultValue - The default u256 value if storage is uninitialized.
36
+ * @param {Address} defaultValue - The default Address value if storage is uninitialized.
36
37
  */
37
- constructor(
38
- public pointer: u16,
39
- public subPointer: Uint8Array,
40
- private defaultValue: Address,
41
- ) {
42
- // Initialize the base u256 pointer using the primary pointer and subPointer
38
+ constructor(public pointer: u16, public subPointer: Uint8Array, private defaultValue: Address) {
39
+ // Initialize the base pointer
43
40
  const writer = new BytesWriter(32);
44
41
  writer.writeU16(pointer);
45
42
  writer.writeBytes(subPointer);
46
43
 
47
- // Initialize the base and length pointers
48
44
  const baseU256Pointer = u256.fromBytes(writer.getBuffer(), true);
49
45
  const lengthPointer = baseU256Pointer.clone();
50
46
 
@@ -60,7 +56,7 @@ export class StoredAddressArray {
60
56
  /**
61
57
  * @method get
62
58
  * @description Retrieves the Address value at the specified global index.
63
- * @param {u64} index - The global index (0 to ∞) of the Address value to retrieve.
59
+ * @param {u64} index - The global index of the Address to retrieve.
64
60
  * @returns {Address} - The Address value at the specified index.
65
61
  */
66
62
  @inline
@@ -75,7 +71,7 @@ export class StoredAddressArray {
75
71
  /**
76
72
  * @method set
77
73
  * @description Sets the Address value at the specified global index.
78
- * @param {u64} index - The global index (0 to ∞) of the Address value to set.
74
+ * @param {u64} index - The global index of the Address to set.
79
75
  * @param {Address} value - The Address value to assign.
80
76
  */
81
77
  @inline
@@ -91,10 +87,38 @@ export class StoredAddressArray {
91
87
  }
92
88
  }
93
89
 
90
+ /**
91
+ * @method indexOf
92
+ * @description Searches for the first occurrence of the specified Address value and returns its index.
93
+ * @param {Address} value - The Address to locate.
94
+ * @returns {i64} - The index of the first occurrence, or -1 if not found.
95
+ */
96
+ @inline
97
+ public indexOf(value: Address): i64 {
98
+ for (let i: u64 = 0; i < this._length; i++) {
99
+ const currentValue = this.get(i);
100
+ if (currentValue == value) {
101
+ return i64(i);
102
+ }
103
+ }
104
+ return -1;
105
+ }
106
+
107
+ /**
108
+ * @method contains
109
+ * @description Determines whether the array contains the specified Address value.
110
+ * @param {Address} value - The Address to locate.
111
+ * @returns {boolean} - True if found; otherwise, false.
112
+ */
113
+ @inline
114
+ public contains(value: Address): boolean {
115
+ return this.indexOf(value) !== -1;
116
+ }
117
+
94
118
  /**
95
119
  * @method push
96
- * @description Appends a new u256 value to the end of the array.
97
- * @param {u256} value - The u256 value to append.
120
+ * @description Appends a new Address value to the end of the array.
121
+ * @param {Address} value - The Address to append.
98
122
  */
99
123
  public push(value: Address): void {
100
124
  if (this._length >= this.MAX_LENGTH) {
@@ -104,23 +128,22 @@ export class StoredAddressArray {
104
128
  }
105
129
 
106
130
  const newIndex: u64 = this._length;
107
- const effectiveIndex: u64 = this._startIndex + newIndex;
108
131
  const wrappedIndex: u64 =
109
- effectiveIndex < this.MAX_LENGTH ? effectiveIndex : effectiveIndex % this.MAX_LENGTH;
132
+ newIndex < this.MAX_LENGTH ? newIndex : newIndex % this.MAX_LENGTH;
110
133
  const slotIndex: u32 = <u32>wrappedIndex;
111
134
 
112
- // Ensure the slot is loaded
113
135
  this.ensureValues(slotIndex);
114
-
115
- // Set the new value
116
136
  this._values.set(slotIndex, value);
117
137
  this._isChanged.add(slotIndex);
118
138
 
119
- // Increment the length
120
139
  this._length += 1;
121
140
  this._isChangedLength = true;
122
141
  }
123
142
 
143
+ /**
144
+ * @method deleteLast
145
+ * @description Deletes the last element from the array.
146
+ */
124
147
  public deleteLast(): void {
125
148
  if (this._length === 0) {
126
149
  throw new Revert('Delete operation failed: Array is empty.');
@@ -136,11 +159,15 @@ export class StoredAddressArray {
136
159
  this._isChanged.add(slotIndex);
137
160
  }
138
161
 
139
- // Decrement the length
140
162
  this._length -= 1;
141
163
  this._isChangedLength = true;
142
164
  }
143
165
 
166
+ /**
167
+ * @method setStartingIndex
168
+ * @description Sets the starting index of the array.
169
+ * @param {u64} index - The new starting index.
170
+ */
144
171
  public setStartingIndex(index: u64): void {
145
172
  this._startIndex = index;
146
173
  this._isChangedStartIndex = true;
@@ -148,8 +175,8 @@ export class StoredAddressArray {
148
175
 
149
176
  /**
150
177
  * @method delete
151
- * @description Deletes the Address value at the specified index by setting it to zero. Does not reorder the array.
152
- * @param {u64} index - The global index of the u256 value to delete.
178
+ * @description Deletes the Address value at the specified index by setting it to defaultValue.
179
+ * @param {u64} index - The global index of the Address value to delete.
153
180
  */
154
181
  public delete(index: u64): void {
155
182
  if (index >= this._length) {
@@ -168,8 +195,7 @@ export class StoredAddressArray {
168
195
 
169
196
  /**
170
197
  * @method shift
171
- * @description Removes the first element of the array by setting it to this.defaultValue, decrementing the length, and incrementing the startIndex.
172
- * If the startIndex reaches the maximum value of u64, it wraps around to 0.
198
+ * @description Removes the first element of the array.
173
199
  */
174
200
  public shift(): void {
175
201
  if (this._length === 0) {
@@ -186,7 +212,6 @@ export class StoredAddressArray {
186
212
  this._isChanged.add(slotIndex);
187
213
  }
188
214
 
189
- // Decrement the length
190
215
  this._length -= 1;
191
216
  this._isChangedLength = true;
192
217
 
@@ -201,7 +226,7 @@ export class StoredAddressArray {
201
226
 
202
227
  /**
203
228
  * @method save
204
- * @description Persists all cached u256 values, the length, and the startIndex to their respective storage slots if any have been modified.
229
+ * @description Persists all changes to storage.
205
230
  */
206
231
  public save(): void {
207
232
  // Save all changed slots
@@ -227,10 +252,10 @@ export class StoredAddressArray {
227
252
 
228
253
  /**
229
254
  * @method deleteAll
230
- * @description Deletes all storage slots by setting them to this.defaultValue, including the length and startIndex slots.
255
+ * @description Deletes the entire array and resets length and startIndex.
231
256
  */
232
257
  public deleteAll(): void {
233
- // Iterate over all loaded slots and clear them
258
+ // Clear all loaded slots
234
259
  const keys = this._values.keys();
235
260
  for (let i = 0; i < keys.length; i++) {
236
261
  const slotIndex = keys[i];
@@ -238,7 +263,7 @@ export class StoredAddressArray {
238
263
  Blockchain.setStorageAt(storagePointer, u256.fromBytes(this.defaultValue));
239
264
  }
240
265
 
241
- // Reset the length and startIndex to zero
266
+ // Reset the length and startIndex
242
267
  const zeroLengthAndStartIndex = u256.Zero;
243
268
  Blockchain.setStorageAt(this.lengthPointer, zeroLengthAndStartIndex);
244
269
  this._length = 0;
@@ -254,9 +279,9 @@ export class StoredAddressArray {
254
279
 
255
280
  /**
256
281
  * @method setMultiple
257
- * @description Sets multiple u256 values starting from a specific global index.
282
+ * @description Sets multiple Address values starting from a specific global index.
258
283
  * @param {u32} startIndex - The starting global index.
259
- * @param {u256[]} values - An array of u256 values to set.
284
+ * @param {Address[]} values - An array of Address values to set.
260
285
  */
261
286
  @inline
262
287
  public setMultiple(startIndex: u32, values: Address[]): void {
@@ -267,10 +292,10 @@ export class StoredAddressArray {
267
292
 
268
293
  /**
269
294
  * @method getAll
270
- * @description Retrieves a range of values starting from a specific global index.
271
- * @param {u32} startIndex - The starting global index.
272
- * @param {u32} count - The number of values to retrieve.
273
- * @returns {Address[]} - An array containing the retrieved Address values.
295
+ * @description Retrieves a range of Address values.
296
+ * @param {u32} startIndex - The start index.
297
+ * @param {u32} count - The number of items to get.
298
+ * @returns {Address[]} - The requested Address values.
274
299
  */
275
300
  @inline
276
301
  public getAll(startIndex: u32, count: u32): Address[] {
@@ -284,8 +309,8 @@ export class StoredAddressArray {
284
309
 
285
310
  /**
286
311
  * @method toString
287
- * @description Returns a string representation of all cached values.
288
- * @returns {string} - A string in the format "[value0, value1, ..., valueN]".
312
+ * @description Returns a string representation of the array.
313
+ * @returns {string} - A string of the form "[addr0, addr1, ...]".
289
314
  */
290
315
  @inline
291
316
  public toString(): string {
@@ -304,7 +329,7 @@ export class StoredAddressArray {
304
329
  /**
305
330
  * @method toBytes
306
331
  * @description Returns the packed Address values as a byte array.
307
- * @returns {u8[]} - The packed values in byte form.
332
+ * @returns {u8[]} - The packed byte array.
308
333
  */
309
334
  @inline
310
335
  public toBytes(): u8[] {
@@ -313,7 +338,7 @@ export class StoredAddressArray {
313
338
  this.ensureValues(i);
314
339
  const value = this._values.get(i);
315
340
  if (value) {
316
- const valueBytes = value;
341
+ const valueBytes = value; // Address is assumed to be or contain a Uint8Array
317
342
  for (let j: u32 = 0; j < valueBytes.length; j++) {
318
343
  bytes.push(valueBytes[j]);
319
344
  }
@@ -324,16 +349,14 @@ export class StoredAddressArray {
324
349
 
325
350
  /**
326
351
  * @method reset
327
- * @description Resets all cached u256 values to zero and marks them as changed, including resetting the length and startIndex.
352
+ * @description Resets the array by clearing all elements and resetting length and startIndex to zero.
328
353
  */
329
354
  @inline
330
355
  public reset(): void {
331
- // Reset the length and startIndex to zero
332
356
  this._length = 0;
333
357
  this._startIndex = 0;
334
358
  this._isChangedLength = true;
335
359
  this._isChangedStartIndex = true;
336
-
337
360
  this.save();
338
361
  }
339
362
 
@@ -358,8 +381,8 @@ export class StoredAddressArray {
358
381
 
359
382
  /**
360
383
  * @method setLength
361
- * @description Sets the length of the array.
362
- * @param {u64} newLength - The new length to set.
384
+ * @description Sets the length of the array, truncating if necessary.
385
+ * @param {u64} newLength - The new length.
363
386
  */
364
387
  public setLength(newLength: u64): void {
365
388
  if (newLength > this.MAX_LENGTH) {
@@ -380,15 +403,15 @@ export class StoredAddressArray {
380
403
  /**
381
404
  * @private
382
405
  * @method ensureValues
383
- * @description Loads and caches the u256 value from the specified storage slot.
406
+ * @description Loads and caches the Address from the specified storage slot if not already loaded.
384
407
  * @param {u32} slotIndex - The index of the storage slot.
385
408
  */
386
409
  private ensureValues(slotIndex: u32): void {
387
410
  if (!this._isLoaded.has(slotIndex)) {
388
411
  const storagePointer = this.calculateStoragePointer(slotIndex);
389
- const storedU256 = Blockchain.getStorageAt(storagePointer, u256.Zero);
412
+ const storedU256: u256 = Blockchain.getStorageAt(storagePointer, u256.Zero);
390
413
  const storedAddress: Address =
391
- storedU256 === u256.Zero ? this.defaultValue : new Address(storedU256.toBytes());
414
+ storedU256 == u256.Zero ? this.defaultValue : new Address(storedU256.toBytes());
392
415
  this._values.set(slotIndex, storedAddress);
393
416
  this._isLoaded.add(slotIndex);
394
417
  }
@@ -397,13 +420,13 @@ export class StoredAddressArray {
397
420
  /**
398
421
  * @private
399
422
  * @method calculateStoragePointer
400
- * @description Calculates the storage pointer for a given slot index by incrementing the base pointer.
401
- * @param {u32} slotIndex - The index of the storage slot.
423
+ * @description Calculates the storage pointer for a given slot index.
424
+ * @param {u64} slotIndex - The index of the storage slot.
402
425
  * @returns {u256} - The calculated storage pointer.
403
426
  */
404
427
  private calculateStoragePointer(slotIndex: u64): u256 {
405
428
  // Each slot is identified by baseU256Pointer + slotIndex + 1
406
- // Slot 0: baseU256Pointer + 1 (first element)
429
+ // Slot 0: baseU256Pointer + 1
407
430
  // Slot 1: baseU256Pointer + 2, etc.
408
431
  return SafeMath.add(this.baseU256Pointer, u256.fromU64(slotIndex + 1));
409
432
  }
@@ -1,8 +1,8 @@
1
1
  import { u256 } from '@btc-vision/as-bignum/assembly';
2
- import { Blockchain } from '../env';
3
2
  import { BytesWriter } from '../buffer/BytesWriter';
4
- import { SafeMath } from '../types/SafeMath';
3
+ import { Blockchain } from '../env';
5
4
  import { Revert } from '../types/Revert';
5
+ import { SafeMath } from '../types/SafeMath';
6
6
 
7
7
  /**
8
8
  * @class StoredBooleanArray
@@ -33,11 +33,7 @@ export class StoredBooleanArray {
33
33
  * @param {Uint8Array} subPointer - The sub-pointer for memory slot addressing.
34
34
  * @param {u256} defaultValue - The default u256 value if storage is uninitialized.
35
35
  */
36
- constructor(
37
- public pointer: u16,
38
- public subPointer: Uint8Array,
39
- private defaultValue: u256,
40
- ) {
36
+ constructor(public pointer: u16, public subPointer: Uint8Array, private defaultValue: u256) {
41
37
  // Initialize the base u256 pointer using the primary pointer and subPointer
42
38
  const writer = new BytesWriter(32);
43
39
  writer.writeU16(pointer);
@@ -1,15 +1,13 @@
1
1
  import { u256 } from '@btc-vision/as-bignum/assembly';
2
+ import { BytesWriter } from '../buffer/BytesWriter';
2
3
  import { Blockchain } from '../env';
3
- import { SafeMath } from '../types/SafeMath';
4
4
  import { encodePointer } from '../math/abi';
5
- import { BytesWriter } from '../buffer/BytesWriter';
5
+ import { SafeMath } from '../types/SafeMath';
6
+ import { U256_BYTE_LENGTH } from '../utils/lengths';
6
7
 
7
8
  @final
8
9
  export class StoredString {
9
- constructor(
10
- public pointer: u16,
11
- private defaultValue?: string,
12
- ) {}
10
+ constructor(public pointer: u16, private defaultValue?: string) {}
13
11
 
14
12
  private _value: string = '';
15
13
 
@@ -33,7 +31,7 @@ export class StoredString {
33
31
  }
34
32
 
35
33
  private getPointer(key: u256): u256 {
36
- const buf = new BytesWriter(32);
34
+ const buf = new BytesWriter(U256_BYTE_LENGTH);
37
35
  buf.writeU256(key);
38
36
 
39
37
  return encodePointer(this.pointer, buf.getBuffer());
@@ -1,9 +1,10 @@
1
1
  import { u256 } from '@btc-vision/as-bignum/assembly';
2
- import { SafeMath } from '../types/SafeMath';
3
- import { MemorySlotPointer } from '../memory/MemorySlotPointer';
2
+ import { BytesWriter } from '../buffer/BytesWriter';
4
3
  import { Blockchain } from '../env';
5
4
  import { encodePointer } from '../math/abi';
6
- import { BytesWriter } from '../buffer/BytesWriter';
5
+ import { MemorySlotPointer } from '../memory/MemorySlotPointer';
6
+ import { SafeMath } from '../types/SafeMath';
7
+ import { U256_BYTE_LENGTH } from '../utils/lengths';
7
8
 
8
9
  @final
9
10
  export class StoredU256 {
@@ -14,7 +15,7 @@ export class StoredU256 {
14
15
  public subPointer: MemorySlotPointer,
15
16
  private defaultValue: u256,
16
17
  ) {
17
- const writer = new BytesWriter(32);
18
+ const writer = new BytesWriter(U256_BYTE_LENGTH);
18
19
  writer.writeU256(subPointer);
19
20
 
20
21
  this.u256Pointer = encodePointer(pointer, writer.getBuffer());
@@ -1,8 +1,9 @@
1
- import { MemorySlotPointer } from '../memory/MemorySlotPointer';
1
+ import { u256 } from '@btc-vision/as-bignum/assembly';
2
+ import { BytesWriter } from '../buffer/BytesWriter';
2
3
  import { Blockchain } from '../env';
3
4
  import { encodePointer } from '../math/abi';
4
- import { BytesWriter } from '../buffer/BytesWriter';
5
- import { u256 } from '@btc-vision/as-bignum/assembly';
5
+ import { MemorySlotPointer } from '../memory/MemorySlotPointer';
6
+ import { U256_BYTE_LENGTH } from '../utils/lengths';
6
7
 
7
8
  /**
8
9
  * @class StoredU64
@@ -32,7 +33,7 @@ export class StoredU64 {
32
33
  public subPointer: MemorySlotPointer,
33
34
  private defaultValue: u256,
34
35
  ) {
35
- const writer = new BytesWriter(32);
36
+ const writer = new BytesWriter(U256_BYTE_LENGTH);
36
37
  writer.writeU256(subPointer);
37
38
 
38
39
  this.u256Pointer = encodePointer(pointer, writer.getBuffer());
@@ -2,10 +2,11 @@ import { u256 } from '@btc-vision/as-bignum/assembly';
2
2
  import { BytesWriter } from '../buffer/BytesWriter';
3
3
  import { Blockchain } from '../env';
4
4
  import { Box } from '../utils/box';
5
+ import { U256_BYTE_LENGTH } from '../utils/lengths';
5
6
  import { assertEq } from './assert';
6
7
 
7
8
  export function test_encode(): void {
8
- const writer = new BytesWriter(64);
9
+ const writer = new BytesWriter(U256_BYTE_LENGTH * 2);
9
10
  writer.writeU256(u256.from(10));
10
11
  writer.writeU256(u256.from(20));
11
12
  const buffer = writer.getBuffer().buffer;
@@ -1,8 +1,7 @@
1
1
  import { Potential } from '../lang/Definitions';
2
- import { bech32m as _bech32m, toWords } from '../utils/b32';
3
2
  import { decodeHexArray, encodeHexFromBuffer } from '../utils';
4
-
5
- export const ADDRESS_BYTE_LENGTH: i32 = 32;
3
+ import { bech32m as _bech32m, toWords } from '../utils/b32';
4
+ import { ADDRESS_BYTE_LENGTH } from '../utils/lengths';
6
5
 
7
6
  @final
8
7
  export class Address extends Uint8Array {
@@ -1,3 +1,4 @@
1
- export * from './hex';
2
1
  export * from './box';
3
2
  export * from './encodings';
3
+ export * from './hex';
4
+ export * from './lengths';
@@ -0,0 +1,18 @@
1
+ export const ADDRESS_BYTE_LENGTH: i32 = 32;
2
+ export const SELECTOR_BYTE_LENGTH: i32 = 4;
3
+
4
+ export const U256_BYTE_LENGTH: i32 = 32;
5
+ export const U128_BYTE_LENGTH: i32 = 16;
6
+ export const U64_BYTE_LENGTH: i32 = 8;
7
+ export const U32_BYTE_LENGTH: i32 = 4;
8
+ export const U16_BYTE_LENGTH: i32 = 2;
9
+ export const U8_BYTE_LENGTH: i32 = 1;
10
+
11
+ export const I256_BYTE_LENGTH: i32 = 32;
12
+ export const I128_BYTE_LENGTH: i32 = 16;
13
+ export const I64_BYTE_LENGTH: i32 = 8;
14
+ export const I32_BYTE_LENGTH: i32 = 4;
15
+ export const I16_BYTE_LENGTH: i32 = 2;
16
+ export const I8_BYTE_LENGTH: i32 = 1;
17
+
18
+ export const BOOLEAN_BYTE_LENGTH: i32 = 1;