@btc-vision/btc-runtime 1.3.13 → 1.3.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/package.json +2 -2
  2. package/runtime/buffer/BytesReader.ts +1 -1
  3. package/runtime/buffer/BytesWriter.ts +1 -1
  4. package/runtime/contracts/DeployableOP_20.ts +1 -1
  5. package/runtime/contracts/OP_20.ts +1 -1
  6. package/runtime/contracts/OP_NET.ts +1 -1
  7. package/runtime/contracts/interfaces/OP20InitParameters.ts +1 -1
  8. package/runtime/env/BlockchainEnvironment.ts +1 -1
  9. package/runtime/env/classes/Block.ts +1 -1
  10. package/runtime/events/predefined/ApproveEvent.ts +1 -1
  11. package/runtime/events/predefined/BurnEvent.ts +1 -1
  12. package/runtime/events/predefined/ClaimEvent.ts +1 -1
  13. package/runtime/events/predefined/MintEvent.ts +1 -1
  14. package/runtime/events/predefined/StakeEvent.ts +1 -1
  15. package/runtime/events/predefined/TransferEvent.ts +1 -1
  16. package/runtime/events/predefined/UnstakeEvent.ts +1 -1
  17. package/runtime/generic/MapU256.ts +1 -1
  18. package/runtime/interfaces/DeployContractResponse.ts +1 -1
  19. package/runtime/math/bytes.ts +1 -1
  20. package/runtime/math/i256.ts +1 -1
  21. package/runtime/math/u160.ts +1 -1
  22. package/runtime/memory/AddressMemoryMap.ts +1 -1
  23. package/runtime/memory/KeyMerger.ts +1 -1
  24. package/runtime/memory/MemorySlotPointer.ts +1 -1
  25. package/runtime/memory/MultiAddressMemoryMap.ts +1 -1
  26. package/runtime/memory/MultiStringMemoryMap.ts +1 -1
  27. package/runtime/memory/StringMemoryMap.ts +1 -1
  28. package/runtime/memory/Uint8ArrayMerger.ts +1 -1
  29. package/runtime/secp256k1/ECPoint.ts +1 -1
  30. package/runtime/shared-libraries/OP20Utils.ts +1 -1
  31. package/runtime/shared-libraries/TransferHelper.ts +1 -1
  32. package/runtime/storage/Serializable.ts +1 -1
  33. package/runtime/storage/StorageBacked.ts +1 -1
  34. package/runtime/storage/StorageSlot.ts +1 -1
  35. package/runtime/storage/StorageValue.ts +1 -1
  36. package/runtime/storage/StoredAddress.ts +1 -1
  37. package/runtime/storage/StoredAddressArray.ts +410 -0
  38. package/runtime/storage/StoredBoolean.ts +1 -1
  39. package/runtime/storage/StoredBooleanArray.ts +1 -1
  40. package/runtime/storage/StoredString.ts +1 -1
  41. package/runtime/storage/StoredU128Array.ts +2 -3
  42. package/runtime/storage/StoredU16Array.ts +3 -3
  43. package/runtime/storage/StoredU256.ts +1 -1
  44. package/runtime/storage/StoredU256Array.ts +2 -3
  45. package/runtime/storage/StoredU64.ts +1 -1
  46. package/runtime/tests/tests.ts +1 -1
  47. package/runtime/types/SafeMath.ts +76 -25
  48. package/runtime/types/index.ts +1 -1
  49. package/runtime/utils/encodings.ts +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@btc-vision/btc-runtime",
3
- "version": "1.3.13",
3
+ "version": "1.3.15",
4
4
  "description": "Bitcoin Smart Contract Runtime",
5
5
  "main": "btc/index.ts",
6
6
  "scripts": {
@@ -43,8 +43,8 @@
43
43
  ],
44
44
  "dependencies": {
45
45
  "@assemblyscript/loader": "^0.27.30",
46
+ "@btc-vision/as-bignum": "^0.0.2",
46
47
  "@eslint/js": "^9.10.0",
47
- "as-bignum": "^0.3.1",
48
48
  "gulplog": "^2.2.0",
49
49
  "mocha": "^10.7.3",
50
50
  "ts-node": "^10.9.2",
@@ -1,6 +1,6 @@
1
1
  import { Address, ADDRESS_BYTE_LENGTH } from '../types/Address';
2
2
  import { Selector } from '../math/abi';
3
- import { i128, u128, u256 } from 'as-bignum/assembly';
3
+ import { i128, u128, u256 } from '@btc-vision/as-bignum/assembly';
4
4
  import { Revert } from '../types/Revert';
5
5
  import { TransactionInput, TransactionOutput } from '../env/classes/UTXO';
6
6
  import { i256 } from '../math/i256';
@@ -1,4 +1,4 @@
1
- import { i128, u128, u256 } from 'as-bignum/assembly';
1
+ import { i128, u128, u256 } from '@btc-vision/as-bignum/assembly';
2
2
  import { Address, ADDRESS_BYTE_LENGTH } from '../types/Address';
3
3
  import { Selector } from '../math/abi';
4
4
  import { BytesReader } from './BytesReader';
@@ -1,4 +1,4 @@
1
- import { u256 } from 'as-bignum/assembly';
1
+ import { u256 } from '@btc-vision/as-bignum/assembly';
2
2
  import { BytesWriter } from '../buffer/BytesWriter';
3
3
  import { Blockchain } from '../env';
4
4
  import { ApproveEvent, BurnEvent, MintEvent, TransferEvent } from '../events/predefined';
@@ -1,5 +1,5 @@
1
1
  import { DeployableOP_20 } from './DeployableOP_20';
2
- import { u256 } from 'as-bignum/assembly';
2
+ 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 {
@@ -24,7 +24,7 @@ export class OP_NET implements IBTC {
24
24
  let response: BytesWriter;
25
25
 
26
26
  switch (method) {
27
- case encodeSelector('owner'):
27
+ case encodeSelector('deployer'):
28
28
  response = new BytesWriter(ADDRESS_BYTE_LENGTH);
29
29
  response.writeAddress(this.contractDeployer);
30
30
  break;
@@ -1,4 +1,4 @@
1
- import { u256 } from 'as-bignum/assembly';
1
+ import { u256 } from '@btc-vision/as-bignum/assembly';
2
2
 
3
3
  export class OP20InitParameters {
4
4
  readonly maxSupply: u256;
@@ -1,7 +1,7 @@
1
1
  import { Address, ADDRESS_BYTE_LENGTH } from '../types/Address';
2
2
  import { MemorySlotPointer } from '../memory/MemorySlotPointer';
3
3
  import { MemorySlotData } from '../memory/MemorySlot';
4
- import { u256 } from 'as-bignum/assembly';
4
+ import { u256 } from '@btc-vision/as-bignum/assembly';
5
5
  import { BytesReader } from '../buffer/BytesReader';
6
6
  import { BytesWriter } from '../buffer/BytesWriter';
7
7
  import { NetEvent } from '../events/NetEvent';
@@ -1,4 +1,4 @@
1
- import { u256 } from 'as-bignum/assembly';
1
+ import { u256 } from '@btc-vision/as-bignum/assembly';
2
2
 
3
3
  @final
4
4
  export class Block {
@@ -1,4 +1,4 @@
1
- import { u256 } from 'as-bignum/assembly';
1
+ import { u256 } from '@btc-vision/as-bignum/assembly';
2
2
  import { Address, ADDRESS_BYTE_LENGTH } from '../../types/Address';
3
3
  import { NetEvent } from '../NetEvent';
4
4
  import { BytesWriter } from '../../buffer/BytesWriter';
@@ -1,4 +1,4 @@
1
- import { u256 } from 'as-bignum/assembly';
1
+ import { u256 } from '@btc-vision/as-bignum/assembly';
2
2
  import { NetEvent } from '../NetEvent';
3
3
  import { BytesWriter } from '../../buffer/BytesWriter';
4
4
 
@@ -1,4 +1,4 @@
1
- import { u256 } from 'as-bignum/assembly';
1
+ import { u256 } from '@btc-vision/as-bignum/assembly';
2
2
  import { NetEvent } from '../NetEvent';
3
3
  import { BytesWriter } from '../../buffer/BytesWriter';
4
4
 
@@ -1,4 +1,4 @@
1
- import { u256 } from 'as-bignum/assembly';
1
+ import { u256 } from '@btc-vision/as-bignum/assembly';
2
2
  import { NetEvent } from '../NetEvent';
3
3
  import { BytesWriter } from '../../buffer/BytesWriter';
4
4
  import { Address, ADDRESS_BYTE_LENGTH } from '../../types/Address';
@@ -1,4 +1,4 @@
1
- import { u256 } from 'as-bignum/assembly';
1
+ import { u256 } from '@btc-vision/as-bignum/assembly';
2
2
  import { NetEvent } from '../NetEvent';
3
3
  import { BytesWriter } from '../../buffer/BytesWriter';
4
4
 
@@ -1,4 +1,4 @@
1
- import { u256 } from 'as-bignum/assembly';
1
+ import { u256 } from '@btc-vision/as-bignum/assembly';
2
2
  import { NetEvent } from '../NetEvent';
3
3
  import { Address, ADDRESS_BYTE_LENGTH } from '../../types/Address';
4
4
  import { BytesWriter } from '../../buffer/BytesWriter';
@@ -1,4 +1,4 @@
1
- import { u256 } from 'as-bignum/assembly';
1
+ import { u256 } from '@btc-vision/as-bignum/assembly';
2
2
  import { NetEvent } from '../NetEvent';
3
3
  import { BytesWriter } from '../../buffer/BytesWriter';
4
4
 
@@ -1,5 +1,5 @@
1
1
  import { Revert } from '../types/Revert';
2
- import { u256 } from 'as-bignum/assembly';
2
+ import { u256 } from '@btc-vision/as-bignum/assembly';
3
3
  import { Map } from './Map';
4
4
 
5
5
  export class MapU256 extends Map<u256, u256> {
@@ -1,4 +1,4 @@
1
- import { u256 } from 'as-bignum/assembly';
1
+ import { u256 } from '@btc-vision/as-bignum/assembly';
2
2
  import { Address } from '../types/Address';
3
3
 
4
4
  export class DeployContractResponse {
@@ -1,4 +1,4 @@
1
- import { u128, u256 } from 'as-bignum/assembly';
1
+ import { u128, u256 } from '@btc-vision/as-bignum/assembly';
2
2
 
3
3
  export function bytes(number: u256[]): Uint8Array {
4
4
  const result = new Uint8Array(32 * number.length);
@@ -1,4 +1,4 @@
1
- import { i128, u128, u256 } from 'as-bignum/assembly';
1
+ import { i128, u128, u256 } from '@btc-vision/as-bignum/assembly';
2
2
 
3
3
  export class i256 {
4
4
 
@@ -1,4 +1,4 @@
1
- import { i128, u128 } from 'as-bignum/assembly';
1
+ import { i128, u128 } from '@btc-vision/as-bignum/assembly';
2
2
  import { __carry, __uadd64, __umulh64 } from 'as-bignum/assembly/globals';
3
3
 
4
4
  @lazy const HEX_CHARS = '0123456789abcdef';
@@ -2,7 +2,7 @@ import { MemorySlotPointer } from './MemorySlotPointer';
2
2
  import { Blockchain } from '../env';
3
3
  import { encodePointer } from '../math/abi';
4
4
  import { MemorySlotData } from './MemorySlot';
5
- import { u256 } from 'as-bignum/assembly';
5
+ import { u256 } from '@btc-vision/as-bignum/assembly';
6
6
  import { BytesWriter } from '../buffer/BytesWriter';
7
7
  import { Address } from '../types/Address';
8
8
 
@@ -1,5 +1,5 @@
1
1
  import { MemorySlotData } from './MemorySlot';
2
- import { u256 } from 'as-bignum/assembly';
2
+ import { u256 } from '@btc-vision/as-bignum/assembly';
3
3
  import { Blockchain } from '../env';
4
4
  import { MemorySlotPointer } from './MemorySlotPointer';
5
5
  import { encodePointer } from '../math/abi';
@@ -1,3 +1,3 @@
1
- import { u256 } from 'as-bignum/assembly';
1
+ import { u256 } from '@btc-vision/as-bignum/assembly';
2
2
 
3
3
  export type MemorySlotPointer = u256;
@@ -1,5 +1,5 @@
1
1
  import { MemorySlotData } from './MemorySlot';
2
- import { u256 } from 'as-bignum/assembly';
2
+ import { u256 } from '@btc-vision/as-bignum/assembly';
3
3
  import { Uint8ArrayMerger } from './Uint8ArrayMerger';
4
4
  import { Address } from '../types/Address';
5
5
 
@@ -1,5 +1,5 @@
1
1
  import { MemorySlotData } from './MemorySlot';
2
- import { u256 } from 'as-bignum/assembly';
2
+ import { u256 } from '@btc-vision/as-bignum/assembly';
3
3
  import { KeyMerger } from './KeyMerger';
4
4
 
5
5
  @final
@@ -2,7 +2,7 @@ import { MemorySlotPointer } from './MemorySlotPointer';
2
2
  import { Blockchain } from '../env';
3
3
  import { encodePointer } from '../math/abi';
4
4
  import { MemorySlotData } from './MemorySlot';
5
- import { u256 } from 'as-bignum/assembly';
5
+ import { u256 } from '@btc-vision/as-bignum/assembly';
6
6
  import { BytesWriter } from '../buffer/BytesWriter';
7
7
 
8
8
  @final
@@ -1,5 +1,5 @@
1
1
  import { MemorySlotData } from './MemorySlot';
2
- import { u256 } from 'as-bignum/assembly';
2
+ import { u256 } from '@btc-vision/as-bignum/assembly';
3
3
  import { Blockchain } from '../env';
4
4
  import { MemorySlotPointer } from './MemorySlotPointer';
5
5
  import { encodePointer } from '../math/abi';
@@ -1,4 +1,4 @@
1
- import { u256 } from 'as-bignum/assembly';
1
+ import { u256 } from '@btc-vision/as-bignum/assembly';
2
2
  import { SafeMath } from '../types/SafeMath';
3
3
 
4
4
  // secp256k1 curve parameters (using little-endian byte arrays)
@@ -1,5 +1,5 @@
1
1
  import { Address, ADDRESS_BYTE_LENGTH } from '../types/Address';
2
- import { u256 } from 'as-bignum/assembly';
2
+ import { u256 } from '@btc-vision/as-bignum/assembly';
3
3
  import { BytesWriter } from '../buffer/BytesWriter';
4
4
  import { Blockchain } from '../env';
5
5
  import { encodeSelector, Selector } from '../math/abi';
@@ -1,4 +1,4 @@
1
- import { u256 } from 'as-bignum/assembly';
1
+ import { u256 } from '@btc-vision/as-bignum/assembly';
2
2
  import { encodeSelector, Selector } from '../math/abi';
3
3
  import { Address, ADDRESS_BYTE_LENGTH } from '../types/Address';
4
4
  import { BytesWriter } from '../buffer/BytesWriter';
@@ -1,4 +1,4 @@
1
- import { u256 } from 'as-bignum/assembly';
1
+ import { u256 } from '@btc-vision/as-bignum/assembly';
2
2
  import { Blockchain } from '../env';
3
3
  import { MemorySlotPointer } from '../memory/MemorySlotPointer';
4
4
  import { BytesWriter } from '../buffer/BytesWriter';
@@ -1,4 +1,4 @@
1
- import { u256 } from 'as-bignum/assembly';
1
+ import { u256 } from '@btc-vision/as-bignum/assembly';
2
2
 
3
3
  export interface StorageBacked {
4
4
  serialize(): Array<u256>;
@@ -1,4 +1,4 @@
1
- import { u256 } from 'as-bignum/assembly';
1
+ import { u256 } from '@btc-vision/as-bignum/assembly';
2
2
  import { BlockchainEnvironment } from '../env/BlockchainEnvironment';
3
3
  import { Sha256 } from '../math/sha256';
4
4
  import { MemorySlotPointer } from '../memory/MemorySlotPointer';
@@ -1,4 +1,4 @@
1
- import { u256 } from 'as-bignum/assembly';
1
+ import { u256 } from '@btc-vision/as-bignum/assembly';
2
2
  import { StorageSlot } from './StorageSlot';
3
3
 
4
4
  export class StorageValue<T> {
@@ -1,4 +1,4 @@
1
- import { u256 } from 'as-bignum/assembly';
1
+ import { u256 } from '@btc-vision/as-bignum/assembly';
2
2
  import { Blockchain } from '../env';
3
3
  import { encodePointer } from '../math/abi';
4
4
  import { BytesWriter } from '../buffer/BytesWriter';
@@ -0,0 +1,410 @@
1
+ import { u256 } from '@btc-vision/as-bignum/assembly';
2
+ import { Blockchain } from '../env';
3
+ import { BytesWriter } from '../buffer/BytesWriter';
4
+ import { SafeMath } from '../types/SafeMath';
5
+ import { Address } from '../types/Address';
6
+ import { Revert } from '../types/Revert';
7
+
8
+ /**
9
+ * @class StoredAddressArray
10
+ * @description Manages an array of u256 values across multiple storage slots. Each slot holds one u256 value.
11
+ */
12
+ @final
13
+ export class StoredAddressArray {
14
+ private readonly baseU256Pointer: u256;
15
+ private readonly lengthPointer: u256;
16
+
17
+ // Internal cache for storage slots
18
+ private _values: Map<u64, Address> = new Map(); // Map from slotIndex to u256 value
19
+ private _isLoaded: Set<u64> = new Set(); // Set of slotIndexes that are loaded
20
+ private _isChanged: Set<u64> = new Set(); // Set of slotIndexes that are modified
21
+
22
+ // Internal variables for length and startIndex management
23
+ private _length: u64 = 0; // Current length of the array
24
+ private _startIndex: u64 = 0; // Starting index of the array
25
+ private _isChangedLength: bool = false; // Indicates if the length has been modified
26
+ private _isChangedStartIndex: bool = false; // Indicates if the startIndex has been modified
27
+
28
+ // Define a maximum allowed length to prevent excessive storage usage
29
+ private readonly MAX_LENGTH: u64 = u64(u32.MAX_VALUE - 1); // we need to check what happen in overflow situation to be able to set it to u64.MAX_VALUE
30
+
31
+ /**
32
+ * @constructor
33
+ * @param {u16} pointer - The primary pointer identifier.
34
+ * @param {Uint8Array} subPointer - The sub-pointer for memory slot addressing.
35
+ * @param {u256} defaultValue - The default u256 value if storage is uninitialized.
36
+ */
37
+ constructor(
38
+ public pointer: u16,
39
+ public subPointer: Uint8Array,
40
+ private defaultValue: Address,
41
+ ) {
42
+ // Initialize the base u256 pointer using the primary pointer and subPointer
43
+ const writer = new BytesWriter(32);
44
+ writer.writeU16(pointer);
45
+ writer.writeBytes(subPointer);
46
+
47
+ // Initialize the base and length pointers
48
+ const baseU256Pointer = u256.fromBytes(writer.getBuffer(), true);
49
+ const lengthPointer = baseU256Pointer.clone();
50
+
51
+ // Load the current length and startIndex from storage
52
+ const storedLengthAndStartIndex: u256 = Blockchain.getStorageAt(lengthPointer, u256.Zero);
53
+ this.lengthPointer = lengthPointer;
54
+ this.baseU256Pointer = baseU256Pointer;
55
+
56
+ this._length = storedLengthAndStartIndex.lo1; // Bytes 0-7: length
57
+ this._startIndex = storedLengthAndStartIndex.lo2; // Bytes 8-15: startIndex
58
+ }
59
+
60
+ /**
61
+ * @method get
62
+ * @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.
64
+ * @returns {Address} - The Address value at the specified index.
65
+ */
66
+ @inline
67
+ public get(index: u64): Address {
68
+ assert(index < this._length, 'Index out of bounds');
69
+ const slotIndex: u32 = <u32>index;
70
+ this.ensureValues(slotIndex);
71
+ const value = this._values.get(slotIndex);
72
+ return value ? value : this.defaultValue;
73
+ }
74
+
75
+ /**
76
+ * @method set
77
+ * @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.
79
+ * @param {Address} value - The Address value to assign.
80
+ */
81
+ @inline
82
+ public set(index: u64, value: Address): void {
83
+ assert(index < this._length, 'Index exceeds current array length');
84
+ const slotIndex: u32 = <u32>index;
85
+ this.ensureValues(slotIndex);
86
+
87
+ const currentValue = this._values.get(slotIndex);
88
+ if (currentValue != value) {
89
+ this._values.set(slotIndex, value);
90
+ this._isChanged.add(slotIndex);
91
+ }
92
+ }
93
+
94
+ /**
95
+ * @method push
96
+ * @description Appends a new u256 value to the end of the array.
97
+ * @param {u256} value - The u256 value to append.
98
+ */
99
+ public push(value: Address): void {
100
+ if (this._length >= this.MAX_LENGTH) {
101
+ throw new Revert(
102
+ 'Push operation failed: Array has reached its maximum allowed length.',
103
+ );
104
+ }
105
+
106
+ const newIndex: u64 = this._length;
107
+ const effectiveIndex: u64 = this._startIndex + newIndex;
108
+ const wrappedIndex: u64 =
109
+ effectiveIndex < this.MAX_LENGTH ? effectiveIndex : effectiveIndex % this.MAX_LENGTH;
110
+ const slotIndex: u32 = <u32>wrappedIndex;
111
+
112
+ // Ensure the slot is loaded
113
+ this.ensureValues(slotIndex);
114
+
115
+ // Set the new value
116
+ this._values.set(slotIndex, value);
117
+ this._isChanged.add(slotIndex);
118
+
119
+ // Increment the length
120
+ this._length += 1;
121
+ this._isChangedLength = true;
122
+ }
123
+
124
+ public deleteLast(): void {
125
+ if (this._length === 0) {
126
+ throw new Revert('Delete operation failed: Array is empty.');
127
+ }
128
+
129
+ const lastIndex: u64 = this._length - 1;
130
+ const slotIndex: u32 = <u32>(this._startIndex + lastIndex);
131
+ this.ensureValues(slotIndex);
132
+
133
+ const currentValue = this._values.get(slotIndex);
134
+ if (currentValue != this.defaultValue) {
135
+ this._values.set(slotIndex, this.defaultValue);
136
+ this._isChanged.add(slotIndex);
137
+ }
138
+
139
+ // Decrement the length
140
+ this._length -= 1;
141
+ this._isChangedLength = true;
142
+ }
143
+
144
+ public setStartingIndex(index: u64): void {
145
+ this._startIndex = index;
146
+ this._isChangedStartIndex = true;
147
+ }
148
+
149
+ /**
150
+ * @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.
153
+ */
154
+ public delete(index: u64): void {
155
+ if (index >= this._length) {
156
+ throw new Revert('Delete operation failed: Index out of bounds.');
157
+ }
158
+
159
+ const slotIndex: u32 = <u32>index;
160
+ this.ensureValues(slotIndex);
161
+
162
+ const currentValue = this._values.get(slotIndex);
163
+ if (currentValue != this.defaultValue) {
164
+ this._values.set(slotIndex, this.defaultValue);
165
+ this._isChanged.add(slotIndex);
166
+ }
167
+ }
168
+
169
+ /**
170
+ * @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.
173
+ */
174
+ public shift(): void {
175
+ if (this._length === 0) {
176
+ throw new Revert('Shift operation failed: Array is empty.');
177
+ }
178
+
179
+ const currentStartIndex: u64 = this._startIndex;
180
+ const slotIndex: u32 = <u32>currentStartIndex;
181
+ this.ensureValues(slotIndex);
182
+
183
+ const currentValue = this._values.get(slotIndex);
184
+ if (currentValue != this.defaultValue) {
185
+ this._values.set(slotIndex, this.defaultValue);
186
+ this._isChanged.add(slotIndex);
187
+ }
188
+
189
+ // Decrement the length
190
+ this._length -= 1;
191
+ this._isChangedLength = true;
192
+
193
+ // Increment the startIndex with wrap-around
194
+ if (this._startIndex < this.MAX_LENGTH - 1) {
195
+ this._startIndex += 1;
196
+ } else {
197
+ this._startIndex = 0;
198
+ }
199
+ this._isChangedStartIndex = true;
200
+ }
201
+
202
+ /**
203
+ * @method save
204
+ * @description Persists all cached u256 values, the length, and the startIndex to their respective storage slots if any have been modified.
205
+ */
206
+ public save(): void {
207
+ // Save all changed slots
208
+ const changed = this._isChanged.values();
209
+ for (let i = 0; i < changed.length; i++) {
210
+ const slotIndex = changed[i];
211
+ const storagePointer = this.calculateStoragePointer(slotIndex);
212
+ const value = this._values.get(slotIndex);
213
+ Blockchain.setStorageAt(storagePointer, u256.fromBytes(value));
214
+ }
215
+ this._isChanged.clear();
216
+
217
+ // Save length and startIndex if changed
218
+ if (this._isChangedLength || this._isChangedStartIndex) {
219
+ const packedLengthAndStartIndex = new u256();
220
+ packedLengthAndStartIndex.lo1 = this._length;
221
+ packedLengthAndStartIndex.lo2 = this._startIndex;
222
+ Blockchain.setStorageAt(this.lengthPointer, packedLengthAndStartIndex);
223
+ this._isChangedLength = false;
224
+ this._isChangedStartIndex = false;
225
+ }
226
+ }
227
+
228
+ /**
229
+ * @method deleteAll
230
+ * @description Deletes all storage slots by setting them to this.defaultValue, including the length and startIndex slots.
231
+ */
232
+ public deleteAll(): void {
233
+ // Iterate over all loaded slots and clear them
234
+ const keys = this._values.keys();
235
+ for (let i = 0; i < keys.length; i++) {
236
+ const slotIndex = keys[i];
237
+ const storagePointer = this.calculateStoragePointer(slotIndex);
238
+ Blockchain.setStorageAt(storagePointer, u256.fromBytes(this.defaultValue));
239
+ }
240
+
241
+ // Reset the length and startIndex to zero
242
+ const zeroLengthAndStartIndex = u256.Zero;
243
+ Blockchain.setStorageAt(this.lengthPointer, zeroLengthAndStartIndex);
244
+ this._length = 0;
245
+ this._startIndex = 0;
246
+ this._isChangedLength = false;
247
+ this._isChangedStartIndex = false;
248
+
249
+ // Clear internal caches
250
+ this._values.clear();
251
+ this._isLoaded.clear();
252
+ this._isChanged.clear();
253
+ }
254
+
255
+ /**
256
+ * @method setMultiple
257
+ * @description Sets multiple u256 values starting from a specific global index.
258
+ * @param {u32} startIndex - The starting global index.
259
+ * @param {u256[]} values - An array of u256 values to set.
260
+ */
261
+ @inline
262
+ public setMultiple(startIndex: u32, values: Address[]): void {
263
+ for (let i: u32 = 0; i < values.length; i++) {
264
+ this.set(<u64>(startIndex + i), values[i]);
265
+ }
266
+ }
267
+
268
+ /**
269
+ * @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.
274
+ */
275
+ @inline
276
+ public getAll(startIndex: u32, count: u32): Address[] {
277
+ assert(startIndex + count <= this._length, 'Requested range exceeds array length');
278
+ const result: Address[] = new Array<Address>(count);
279
+ for (let i: u32 = 0; i < count; i++) {
280
+ result[i] = this.get(<u64>(startIndex + i));
281
+ }
282
+ return result;
283
+ }
284
+
285
+ /**
286
+ * @method toString
287
+ * @description Returns a string representation of all cached values.
288
+ * @returns {string} - A string in the format "[value0, value1, ..., valueN]".
289
+ */
290
+ @inline
291
+ public toString(): string {
292
+ let str = '[';
293
+ for (let i: u32 = 0; i < this._length; i++) {
294
+ const value = this.get(<u64>i);
295
+ str += value.toString();
296
+ if (i !== this._length - 1) {
297
+ str += ', ';
298
+ }
299
+ }
300
+ str += ']';
301
+ return str;
302
+ }
303
+
304
+ /**
305
+ * @method toBytes
306
+ * @description Returns the packed Address values as a byte array.
307
+ * @returns {u8[]} - The packed values in byte form.
308
+ */
309
+ @inline
310
+ public toBytes(): u8[] {
311
+ const bytes: u8[] = new Array<u8>();
312
+ for (let i: u32 = 0; i < this._length; i++) {
313
+ this.ensureValues(i);
314
+ const value = this._values.get(i);
315
+ if (value) {
316
+ const valueBytes = value;
317
+ for (let j: u32 = 0; j < valueBytes.length; j++) {
318
+ bytes.push(valueBytes[j]);
319
+ }
320
+ }
321
+ }
322
+ return bytes;
323
+ }
324
+
325
+ /**
326
+ * @method reset
327
+ * @description Resets all cached u256 values to zero and marks them as changed, including resetting the length and startIndex.
328
+ */
329
+ @inline
330
+ public reset(): void {
331
+ // Reset the length and startIndex to zero
332
+ this._length = 0;
333
+ this._startIndex = 0;
334
+ this._isChangedLength = true;
335
+ this._isChangedStartIndex = true;
336
+
337
+ this.save();
338
+ }
339
+
340
+ /**
341
+ * @method getLength
342
+ * @description Retrieves the current length of the array.
343
+ * @returns {u64} - The current length.
344
+ */
345
+ @inline
346
+ public getLength(): u64 {
347
+ return this._length;
348
+ }
349
+
350
+ /**
351
+ * @method startingIndex
352
+ * @description Retrieves the current starting index of the array.
353
+ * @returns {u64} - The starting index.
354
+ */
355
+ public startingIndex(): u64 {
356
+ return this._startIndex;
357
+ }
358
+
359
+ /**
360
+ * @method setLength
361
+ * @description Sets the length of the array.
362
+ * @param {u64} newLength - The new length to set.
363
+ */
364
+ public setLength(newLength: u64): void {
365
+ if (newLength > this.MAX_LENGTH) {
366
+ throw new Revert('SetLength operation failed: Length exceeds maximum allowed value.');
367
+ }
368
+
369
+ if (newLength < this._length) {
370
+ // Truncate the array if newLength is smaller
371
+ for (let i: u64 = newLength; i < this._length; i++) {
372
+ this.delete(i);
373
+ }
374
+ }
375
+
376
+ this._length = newLength;
377
+ this._isChangedLength = true;
378
+ }
379
+
380
+ /**
381
+ * @private
382
+ * @method ensureValues
383
+ * @description Loads and caches the u256 value from the specified storage slot.
384
+ * @param {u32} slotIndex - The index of the storage slot.
385
+ */
386
+ private ensureValues(slotIndex: u32): void {
387
+ if (!this._isLoaded.has(slotIndex)) {
388
+ const storagePointer = this.calculateStoragePointer(slotIndex);
389
+ const storedU256 = Blockchain.getStorageAt(storagePointer, u256.Zero);
390
+ const storedAddress: Address =
391
+ storedU256 === u256.Zero ? this.defaultValue : new Address(storedU256.toBytes());
392
+ this._values.set(slotIndex, storedAddress);
393
+ this._isLoaded.add(slotIndex);
394
+ }
395
+ }
396
+
397
+ /**
398
+ * @private
399
+ * @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.
402
+ * @returns {u256} - The calculated storage pointer.
403
+ */
404
+ private calculateStoragePointer(slotIndex: u64): u256 {
405
+ // Each slot is identified by baseU256Pointer + slotIndex + 1
406
+ // Slot 0: baseU256Pointer + 1 (first element)
407
+ // Slot 1: baseU256Pointer + 2, etc.
408
+ return SafeMath.add(this.baseU256Pointer, u256.fromU64(slotIndex + 1));
409
+ }
410
+ }
@@ -1,4 +1,4 @@
1
- import { u256 } from 'as-bignum/assembly';
1
+ import { u256 } from '@btc-vision/as-bignum/assembly';
2
2
  import { Blockchain } from '../env';
3
3
 
4
4
  @final
@@ -1,4 +1,4 @@
1
- import { u256 } from 'as-bignum/assembly';
1
+ import { u256 } from '@btc-vision/as-bignum/assembly';
2
2
  import { Blockchain } from '../env';
3
3
  import { BytesWriter } from '../buffer/BytesWriter';
4
4
  import { SafeMath } from '../types/SafeMath';
@@ -1,4 +1,4 @@
1
- import { u256 } from 'as-bignum/assembly';
1
+ import { u256 } from '@btc-vision/as-bignum/assembly';
2
2
  import { Blockchain } from '../env';
3
3
  import { SafeMath } from '../types/SafeMath';
4
4
  import { encodePointer } from '../math/abi';
@@ -1,4 +1,4 @@
1
- import { u128, u256 } from 'as-bignum/assembly';
1
+ import { u128, u256 } from '@btc-vision/as-bignum/assembly';
2
2
  import { Blockchain } from '../env';
3
3
  import { BytesWriter } from '../buffer/BytesWriter';
4
4
  import { SafeMath } from '../types/SafeMath';
@@ -110,9 +110,8 @@ export class StoredU128Array {
110
110
  }
111
111
 
112
112
  const newIndex: u64 = this._length;
113
- const effectiveIndex: u64 = this._startIndex + newIndex;
114
113
  const wrappedIndex: u64 =
115
- effectiveIndex < this.MAX_LENGTH ? effectiveIndex : effectiveIndex % this.MAX_LENGTH;
114
+ newIndex < this.MAX_LENGTH ? newIndex : newIndex % this.MAX_LENGTH;
116
115
  const slotIndex: u32 = <u32>(wrappedIndex / 2);
117
116
  const subIndex: u8 = <u8>(wrappedIndex % 2);
118
117
 
@@ -1,4 +1,4 @@
1
- import { u256 } from 'as-bignum/assembly';
1
+ import { u256 } from '@btc-vision/as-bignum/assembly';
2
2
  import { Blockchain } from '../env';
3
3
  import { BytesWriter } from '../buffer/BytesWriter';
4
4
  import { SafeMath } from '../types/SafeMath';
@@ -106,9 +106,9 @@ export class StoredU16Array {
106
106
  }
107
107
 
108
108
  const newIndex: u64 = this._length;
109
- const effectiveIndex: u64 = this._startIndex + newIndex;
110
109
  const wrappedIndex: u64 =
111
- effectiveIndex < this.MAX_LENGTH ? effectiveIndex : effectiveIndex % this.MAX_LENGTH;
110
+ newIndex < this.MAX_LENGTH ? newIndex : newIndex % this.MAX_LENGTH;
111
+
112
112
  const slotIndex: u64 = wrappedIndex / 16;
113
113
  const subIndex: u8 = <u8>(wrappedIndex % 16);
114
114
 
@@ -1,4 +1,4 @@
1
- import { u256 } from 'as-bignum/assembly';
1
+ import { u256 } from '@btc-vision/as-bignum/assembly';
2
2
  import { SafeMath } from '../types/SafeMath';
3
3
  import { MemorySlotPointer } from '../memory/MemorySlotPointer';
4
4
  import { Blockchain } from '../env';
@@ -1,4 +1,4 @@
1
- import { u256 } from 'as-bignum/assembly';
1
+ import { u256 } from '@btc-vision/as-bignum/assembly';
2
2
  import { Blockchain } from '../env';
3
3
  import { BytesWriter } from '../buffer/BytesWriter';
4
4
  import { SafeMath } from '../types/SafeMath';
@@ -103,9 +103,8 @@ export class StoredU256Array {
103
103
  }
104
104
 
105
105
  const newIndex: u64 = this._length;
106
- const effectiveIndex: u64 = this._startIndex + newIndex;
107
106
  const wrappedIndex: u64 =
108
- effectiveIndex < this.MAX_LENGTH ? effectiveIndex : effectiveIndex % this.MAX_LENGTH;
107
+ newIndex < this.MAX_LENGTH ? newIndex : newIndex % this.MAX_LENGTH;
109
108
  const slotIndex: u32 = <u32>wrappedIndex;
110
109
 
111
110
  // Ensure the slot is loaded
@@ -2,7 +2,7 @@ import { MemorySlotPointer } from '../memory/MemorySlotPointer';
2
2
  import { Blockchain } from '../env';
3
3
  import { encodePointer } from '../math/abi';
4
4
  import { BytesWriter } from '../buffer/BytesWriter';
5
- import { u256 } from 'as-bignum/assembly';
5
+ import { u256 } from '@btc-vision/as-bignum/assembly';
6
6
 
7
7
  /**
8
8
  * @class StoredU64
@@ -1,4 +1,4 @@
1
- import { u256 } from 'as-bignum/assembly';
1
+ 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';
@@ -1,4 +1,4 @@
1
- import { u128, u256 } from 'as-bignum/assembly';
1
+ import { u128, u256 } from '@btc-vision/as-bignum/assembly';
2
2
 
3
3
  export class SafeMath {
4
4
  public static ZERO: u256 = u256.fromU32(0);
@@ -267,17 +267,7 @@ export class SafeMath {
267
267
  const bitShift = shift % bitsPerSegment;
268
268
 
269
269
  const segments = [value.lo1, value.lo2, value.hi1, value.hi2];
270
-
271
- const result = new Array<u64>(4).fill(0);
272
-
273
- for (let i = 0; i < segments.length; i++) {
274
- if (i + segmentShift < segments.length) {
275
- result[i + segmentShift] |= segments[i] << bitShift;
276
- }
277
- if (bitShift != 0 && i + segmentShift + 1 < segments.length) {
278
- result[i + segmentShift + 1] |= segments[i] >>> (bitsPerSegment - bitShift);
279
- }
280
- }
270
+ const result = SafeMath.shlSegment(segments, segmentShift, bitShift, bitsPerSegment, 4);
281
271
 
282
272
  return new u256(result[0], result[1], result[2], result[3]);
283
273
  }
@@ -302,17 +292,7 @@ export class SafeMath {
302
292
  const bitShift = shift % bitsPerSegment;
303
293
 
304
294
  const segments = [value.lo, value.hi];
305
-
306
- const result = new Array<u64>(2).fill(0);
307
-
308
- for (let i = 0; i < segments.length; i++) {
309
- if (i + segmentShift < segments.length) {
310
- result[i + segmentShift] |= segments[i] << bitShift;
311
- }
312
- if (bitShift != 0 && i + segmentShift + 1 < segments.length) {
313
- result[i + segmentShift + 1] |= segments[i] >>> (bitsPerSegment - bitShift);
314
- }
315
- }
295
+ const result = SafeMath.shlSegment(segments, segmentShift, bitShift, bitsPerSegment, 2);
316
296
 
317
297
  return new u128(result[0], result[1]);
318
298
  }
@@ -329,8 +309,58 @@ export class SafeMath {
329
309
  return u256.xor(a, b);
330
310
  }
331
311
 
332
- public static shr(a: u256, b: u32): u256 {
333
- return u256.shr(a, b);
312
+ public static shr(a: u256, shift: i32): u256 {
313
+ shift &= 255;
314
+ if (shift == 0) return a;
315
+
316
+ const w = shift >>> 6; // how many full 64-bit words to drop
317
+ const b = shift & 63; // how many bits to shift within a word
318
+
319
+ // Extract the words
320
+ let lo1 = a.lo1;
321
+ let lo2 = a.lo2;
322
+ let hi1 = a.hi1;
323
+ let hi2 = a.hi2;
324
+
325
+ // Shift words down by w words
326
+ // For w = 1, move lo2->lo1, hi1->lo2, hi2->hi1, and hi2 = 0
327
+ // For w = 2, move hi1->lo1, hi2->lo2, and zeros in hi1, hi2
328
+ // For w = 3, move hi2->lo1 and zeros in others
329
+ // For w >= 4, everything is zero.
330
+ if (w >= 4) {
331
+ // Shifting by >= 256 bits zeros out everything
332
+ return u256.Zero;
333
+ } else if (w == 3) {
334
+ lo1 = hi2;
335
+ lo2 = 0;
336
+ hi1 = 0;
337
+ hi2 = 0;
338
+ } else if (w == 2) {
339
+ lo1 = hi1;
340
+ lo2 = hi2;
341
+ hi1 = 0;
342
+ hi2 = 0;
343
+ } else if (w == 1) {
344
+ lo1 = lo2;
345
+ lo2 = hi1;
346
+ hi1 = hi2;
347
+ hi2 = 0;
348
+ }
349
+
350
+ // Now apply the bit shift b
351
+ if (b > 0) {
352
+ // Bring down bits from the higher word
353
+ const carryLo2 = hi1 << (64 - b);
354
+ const carryLo1 = lo2 << (64 - b);
355
+ const carryHi1 = hi2 << (64 - b);
356
+
357
+ lo1 = (lo1 >>> b) | carryLo1;
358
+ lo2 = (lo2 >>> b) | carryLo2;
359
+ hi1 = (hi1 >>> b) | carryHi1;
360
+ hi2 = hi2 >>> b;
361
+ }
362
+
363
+ return new u256(lo1, lo2, hi1, hi2);
334
364
  }
335
365
 
336
366
  /**
@@ -360,4 +390,25 @@ export class SafeMath {
360
390
 
361
391
  return n;
362
392
  }
393
+
394
+ private static shlSegment(
395
+ segments: u64[],
396
+ segmentShift: i32,
397
+ bitShift: i32,
398
+ bitsPerSegment: i32,
399
+ fillCount: u8,
400
+ ): u64[] {
401
+ const result = new Array<u64>(fillCount).fill(0);
402
+
403
+ for (let i = 0; i < segments.length; i++) {
404
+ if (i + segmentShift < segments.length) {
405
+ result[i + segmentShift] |= segments[i] << bitShift;
406
+ }
407
+ if (bitShift != 0 && i + segmentShift + 1 < segments.length) {
408
+ result[i + segmentShift + 1] |= segments[i] >>> (bitsPerSegment - bitShift);
409
+ }
410
+ }
411
+
412
+ return result;
413
+ }
363
414
  }
@@ -1,7 +1,7 @@
1
1
  import { Map } from '../generic/Map';
2
2
  import { MemorySlotPointer } from '../memory/MemorySlotPointer';
3
3
  import { MemorySlotData } from '../memory/MemorySlot';
4
- import { u256 } from 'as-bignum/assembly';
4
+ import { u256 } from '@btc-vision/as-bignum/assembly';
5
5
  import { BytesReader } from '../buffer/BytesReader';
6
6
 
7
7
  export type PointerStorage = Map<MemorySlotPointer, MemorySlotData<u256>>;
@@ -1,4 +1,4 @@
1
- import { u256 } from 'as-bignum/assembly';
1
+ import { u256 } from '@btc-vision/as-bignum/assembly';
2
2
  import { MemorySlotPointer } from '../memory/MemorySlotPointer';
3
3
 
4
4
  import { b32decode as _b32decode, bech32m as _bech32m, fromWords, toWords } from './b32';