@btc-vision/btc-runtime 1.2.3 → 1.2.5

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.2.3",
3
+ "version": "1.2.5",
4
4
  "description": "Bitcoin Smart Contract Runtime",
5
5
  "main": "btc/index.ts",
6
6
  "scripts": {
@@ -1,10 +1,11 @@
1
1
  import { Address, ADDRESS_BYTE_LENGTH } from '../types/Address';
2
2
  import { Selector } from '../math/abi';
3
- import { u256 } from 'as-bignum/assembly';
3
+ import { i128, u128, u256 } from 'as-bignum/assembly';
4
4
  import { Revert } from '../types/Revert';
5
5
  import { Map } from '../generic/Map';
6
6
  import { TransactionInput, TransactionOutput } from '../env/classes/UTXO';
7
7
  import { StaticArray } from 'staticarray';
8
+ import { i256 } from '../math/i256';
8
9
 
9
10
  @final
10
11
  export class BytesReader {
@@ -49,12 +50,46 @@ export class BytesReader {
49
50
  }
50
51
 
51
52
  public readU256(): u256 {
53
+ this.verifyEnd(this.currentOffset + 32);
54
+
55
+ const next32Bytes: u8[] = this.readBytesBE(32);
56
+
57
+ return u256.fromBytesBE(next32Bytes);
58
+ }
59
+
60
+ @inline
61
+ public readBytesBE(count: i32): u8[] {
52
62
  const next32Bytes: u8[] = [];
53
- for (let i = 0; i < 32; i++) {
63
+ for (let i = 0; i < count; i++) {
54
64
  next32Bytes[i] = this.readU8();
55
65
  }
56
66
 
57
- return u256.fromBytesBE(next32Bytes);
67
+ return next32Bytes;
68
+ }
69
+
70
+ public readI64(): i64 {
71
+ this.verifyEnd(this.currentOffset + 8);
72
+
73
+ const value = this.buffer.getInt64(this.currentOffset, true);
74
+ this.currentOffset += 8;
75
+
76
+ return value;
77
+ }
78
+
79
+ public readU128(): u128 {
80
+ this.verifyEnd(this.currentOffset + 16);
81
+
82
+ const next16Bytes: u8[] = this.readBytesBE(16);
83
+
84
+ return u128.fromBytesBE(next16Bytes);
85
+ }
86
+
87
+ public readI128(): i128 {
88
+ this.verifyEnd(this.currentOffset + 16);
89
+
90
+ const next16Bytes: u8[] = this.readBytesBE(16);
91
+
92
+ return i128.fromBytesBE(next16Bytes);
58
93
  }
59
94
 
60
95
  public readBytes(length: u32, zeroStop: boolean = false): Uint8Array {
@@ -138,6 +173,14 @@ export class BytesReader {
138
173
  return result;
139
174
  }
140
175
 
176
+ public readI256(): i256 {
177
+ this.verifyEnd(this.currentOffset + 32);
178
+
179
+ const next32Bytes: u8[] = this.readBytesBE(32);
180
+
181
+ return i256.fromBytesBE(next32Bytes);
182
+ }
183
+
141
184
  public readTuple(): u256[] {
142
185
  const length = this.readU32();
143
186
  const result: u256[] = new Array<u256>(length);
@@ -187,7 +230,7 @@ export class BytesReader {
187
230
  }
188
231
 
189
232
  public readAddress(): Address {
190
- return this.readString(ADDRESS_BYTE_LENGTH);
233
+ return this.readString(<u16>ADDRESS_BYTE_LENGTH);
191
234
  }
192
235
 
193
236
  public getOffset(): i32 {
@@ -1,10 +1,11 @@
1
- import { u256 } from 'as-bignum/assembly';
1
+ import { i128, u128, u256 } from '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';
5
5
  import { Revert } from '../types/Revert';
6
6
  import { Map } from '../generic/Map';
7
7
  import { ArrayBuffer } from 'arraybuffer';
8
+ import { i256 } from '../math/i256';
8
9
 
9
10
  @final
10
11
  export class BytesWriter {
@@ -63,6 +64,15 @@ export class BytesWriter {
63
64
  this.writeU8(value ? 1 : 0);
64
65
  }
65
66
 
67
+ public writeI256(value: i256): void {
68
+ this.allocSafe(32);
69
+
70
+ const bytes = value.toUint8Array(true);
71
+ for (let i: i32 = 0; i < 32; i++) {
72
+ this.writeU8(bytes[i] || 0);
73
+ }
74
+ }
75
+
66
76
  public writeU256(value: u256): void {
67
77
  this.allocSafe(32);
68
78
 
@@ -72,6 +82,24 @@ export class BytesWriter {
72
82
  }
73
83
  }
74
84
 
85
+ public writeI128(value: i128): void {
86
+ this.allocSafe(32);
87
+
88
+ const bytes = value.toUint8Array(true);
89
+ for (let i: i32 = 0; i < 32; i++) {
90
+ this.writeU8(bytes[i] || 0);
91
+ }
92
+ }
93
+
94
+ public writeU128(value: u128): void {
95
+ this.allocSafe(32);
96
+
97
+ const bytes = value.toUint8Array(true);
98
+ for (let i: i32 = 0; i < 32; i++) {
99
+ this.writeU8(bytes[i] || 0);
100
+ }
101
+ }
102
+
75
103
  public writeTuple(value: u256[]): void {
76
104
  this.allocSafe(4 + value.length * 32);
77
105
  this.writeU32(u32(value.length));
@@ -242,7 +270,7 @@ export class BytesWriter {
242
270
  }
243
271
 
244
272
  private fromAddress(value: Address): Uint8Array {
245
- if (value.length > i32(ADDRESS_BYTE_LENGTH)) {
273
+ if (value.length > ADDRESS_BYTE_LENGTH) {
246
274
  throw new Revert(`Address is too long ${value.length} > ${ADDRESS_BYTE_LENGTH} bytes`);
247
275
  }
248
276
 
@@ -252,7 +280,7 @@ export class BytesWriter {
252
280
  bytes[i] = value.charCodeAt(i);
253
281
  }
254
282
 
255
- if (value.length < i32(ADDRESS_BYTE_LENGTH)) {
283
+ if (value.length < ADDRESS_BYTE_LENGTH) {
256
284
  bytes[value.length] = 0;
257
285
  }
258
286
 
package/runtime/index.ts CHANGED
@@ -41,6 +41,7 @@ export * from './math/bytes';
41
41
  export * from './math/cyrb53';
42
42
  export * from './math/sha256';
43
43
  export * from './math/rnd';
44
+ export * from './math/i256';
44
45
 
45
46
  /** Memory */
46
47
  export * from './memory/AddressMemoryMap';
@@ -0,0 +1,606 @@
1
+ import { i128, u128, u256 } from 'as-bignum/assembly';
2
+
3
+ export class i256 {
4
+
5
+ @inline static get Zero(): i256 { return new i256(); }
6
+ @inline static get One(): i256 { return new i256(1); }
7
+ @inline static get Min(): i256 { return new i256(0, 0, 0, 0x8000000000000000); }
8
+ @inline static get Max(): i256 { return new i256(-1, -1, -1, 0x7FFFFFFFFFFFFFFF); }
9
+
10
+ @inline
11
+ static fromI256(value: i256): i256 {
12
+ return new i256(value.lo1, value.lo2, value.hi1, value.hi2);
13
+ }
14
+
15
+ @inline
16
+ static fromU256(value: u256): i256 {
17
+ return new i256(<i64>value.lo1, <i64>value.lo2, <i64>value.hi1, <i64>value.hi2);
18
+ }
19
+
20
+ @inline
21
+ static fromI128(value: i128): i256 {
22
+ var signExt = value.hi >> 63;
23
+ return new i256(<i64>value.lo, value.hi, signExt, signExt);
24
+ }
25
+
26
+ @inline
27
+ static fromU128(value: u128): i256 {
28
+ return new i256(<i64>value.lo, <i64>value.hi, 0, 0);
29
+ }
30
+
31
+ @inline
32
+ static fromI64(value: i64): i256 {
33
+ var signExt = value >> 63;
34
+ return new i256(value, signExt, signExt, signExt);
35
+ }
36
+
37
+ @inline
38
+ static fromU64(value: u64): i256 {
39
+ return new i256(<i64>value, 0, 0, 0);
40
+ }
41
+
42
+ @inline
43
+ static fromI32(value: i32): i256 {
44
+ var signExt = value >> 31;
45
+ var signExt64 = <i64>signExt;
46
+ return new i256(<i64>value, signExt64, signExt64, signExt64);
47
+ }
48
+
49
+ @inline
50
+ static fromU32(value: u32): i256 {
51
+ return new i256(<i64>value, 0, 0, 0);
52
+ }
53
+
54
+ @inline
55
+ static fromF64(value: f64): i256 {
56
+ var signExt = reinterpret<i64>(value) >> 63;
57
+ return new i256(<i64>value, signExt, signExt, signExt);
58
+ }
59
+
60
+ @inline
61
+ static fromF32(value: f32): i256 {
62
+ var signExt = reinterpret<i32>(value) >> 31;
63
+ var signExt64 = <i64>signExt;
64
+ return new i256(<i64>value, signExt64, signExt64, signExt64);
65
+ }
66
+
67
+ @inline
68
+ static fromBits(
69
+ l0: i32, l1: i32, l2: i32, l3: i32,
70
+ h0: i32, h1: i32, h2: i32, h3: i32,
71
+ ): i256 {
72
+ return new i256(
73
+ <i64>l0 | ((<i64>l1) << 32),
74
+ <i64>l2 | ((<i64>l3) << 32),
75
+ <i64>h0 | ((<i64>h1) << 32),
76
+ <i64>h2 | ((<i64>h3) << 32),
77
+ );
78
+ }
79
+
80
+ @inline
81
+ static fromBytes<T>(array: T, bigEndian: bool = false): i256 {
82
+ if (array instanceof u8[]) {
83
+ return bigEndian
84
+ ? i256.fromBytesBE(<u8[]>array)
85
+ : i256.fromBytesLE(<u8[]>array);
86
+ } else if (array instanceof Uint8Array) {
87
+ return bigEndian
88
+ ? i256.fromUint8ArrayBE(<Uint8Array>array)
89
+ : i256.fromUint8ArrayLE(<Uint8Array>array);
90
+ } else {
91
+ throw new TypeError("Unsupported generic type");
92
+ }
93
+ }
94
+
95
+ @inline
96
+ static fromBytesLE(array: u8[]): i256 {
97
+ assert(array.length && (array.length & 31) == 0);
98
+ var buffer = array.dataStart;
99
+ return new i256(
100
+ load<i64>(buffer, 0 * sizeof<i64>()),
101
+ load<i64>(buffer, 1 * sizeof<i64>()),
102
+ load<i64>(buffer, 2 * sizeof<i64>()),
103
+ load<i64>(buffer, 3 * sizeof<i64>()),
104
+ );
105
+ }
106
+
107
+ @inline
108
+ static fromBytesBE(array: u8[]): i256 {
109
+ assert(array.length && (array.length & 31) == 0);
110
+ var buffer = array.dataStart;
111
+ return new i256(
112
+ bswap<i64>(load<i64>(buffer, 3 * sizeof<i64>())),
113
+ bswap<i64>(load<i64>(buffer, 2 * sizeof<i64>())),
114
+ bswap<i64>(load<i64>(buffer, 1 * sizeof<i64>())),
115
+ bswap<i64>(load<i64>(buffer, 0 * sizeof<i64>())),
116
+ );
117
+ }
118
+
119
+ @inline
120
+ static fromUint8ArrayLE(array: Uint8Array): i256 {
121
+ assert(array.length && (array.length & 31) == 0);
122
+ var buffer = array.dataStart;
123
+ return new i256(
124
+ load<i64>(buffer, 0 * sizeof<i64>()),
125
+ load<i64>(buffer, 1 * sizeof<i64>()),
126
+ load<i64>(buffer, 2 * sizeof<i64>()),
127
+ load<i64>(buffer, 3 * sizeof<i64>()),
128
+ );
129
+ }
130
+
131
+ @inline
132
+ static fromUint8ArrayBE(array: Uint8Array): i256 {
133
+ assert(array.length && (array.length & 31) == 0);
134
+ var buffer = array.dataStart;
135
+ return new i256(
136
+ bswap<i64>(load<i64>(buffer, 3 * sizeof<i64>())),
137
+ bswap<i64>(load<i64>(buffer, 2 * sizeof<i64>())),
138
+ bswap<i64>(load<i64>(buffer, 1 * sizeof<i64>())),
139
+ bswap<i64>(load<i64>(buffer, 0 * sizeof<i64>())),
140
+ );
141
+ }
142
+
143
+ @inline
144
+ static from<T>(value: T): i256 {
145
+ if (value instanceof bool) return i256.fromU64(<u64>value);
146
+ else if (value instanceof i8) return i256.fromI64(<i64>value);
147
+ else if (value instanceof u8) return i256.fromU64(<u64>value);
148
+ else if (value instanceof i16) return i256.fromI64(<i64>value);
149
+ else if (value instanceof u16) return i256.fromU64(<u64>value);
150
+ else if (value instanceof i32) return i256.fromI32(<i32>value);
151
+ else if (value instanceof u32) return i256.fromU32(<u32>value);
152
+ else if (value instanceof i64) return i256.fromI64(<i64>value);
153
+ else if (value instanceof u64) return i256.fromU64(<u64>value);
154
+ else if (value instanceof f32) return i256.fromF64(<f64>value);
155
+ else if (value instanceof f64) return i256.fromF64(<f64>value);
156
+ else if (value instanceof i128) return i256.fromI128(<i128>value);
157
+ else if (value instanceof u128) return i256.fromU128(<u128>value);
158
+ else if (value instanceof i256) return i256.fromI256(<i256>value);
159
+ else if (value instanceof u256) return i256.fromU256(<u256>value);
160
+ else if (value instanceof u8[]) return i256.fromBytes(<u8[]>value);
161
+ else if (value instanceof Uint8Array) return i256.fromBytes(<Uint8Array>value);
162
+ else throw new TypeError("Unsupported generic type");
163
+ }
164
+
165
+ constructor(
166
+ public lo1: i64 = 0,
167
+ public lo2: i64 = 0,
168
+ public hi1: i64 = 0,
169
+ public hi2: i64 = 0,
170
+ ) {}
171
+
172
+ @inline
173
+ set(value: i256): this {
174
+ this.lo1 = value.lo1;
175
+ this.lo2 = value.lo2;
176
+ this.hi1 = value.hi1;
177
+ this.hi2 = value.hi2;
178
+ return this;
179
+ }
180
+
181
+ @inline
182
+ isNeg(): bool {
183
+ return <bool>(this.hi2 >>> 63);
184
+ }
185
+
186
+ @inline
187
+ isZero(): bool {
188
+ return !(this.lo1 | this.lo2 | this.hi1 | this.hi2);
189
+ }
190
+
191
+ @inline @operator.prefix('!')
192
+ static isEmpty(value: i256): bool {
193
+ return value.isZero();
194
+ }
195
+
196
+ @operator.prefix('~')
197
+ not(): i256 {
198
+ return new i256(~this.lo1, ~this.lo2, ~this.hi1, ~this.hi2);
199
+ }
200
+
201
+ @operator.prefix('+')
202
+ pos(): i256 {
203
+ return this;
204
+ }
205
+
206
+ @operator.prefix('-')
207
+ neg(): i256 {
208
+ var lo1 = ~this.lo1;
209
+ var lo2 = ~this.lo2;
210
+ var hi1 = ~this.hi1;
211
+ var hi2 = ~this.hi2;
212
+
213
+ var lo1p = lo1 + 1;
214
+ var carry = lo1p == 0 ? 1 : 0;
215
+
216
+ var lo2p = lo2 + carry;
217
+ carry = (lo2p == 0 && carry == 1) ? 1 : 0;
218
+
219
+ var hi1p = hi1 + carry;
220
+ carry = (hi1p == 0 && carry == 1) ? 1 : 0;
221
+
222
+ var hi2p = hi2 + carry;
223
+
224
+ return new i256(lo1p, lo2p, hi1p, hi2p);
225
+ }
226
+
227
+ @operator('+')
228
+ static add(a: i256, b: i256): i256 {
229
+ var lo1 = a.lo1 + b.lo1;
230
+ var carry = lo1 < a.lo1 ? 1 : 0;
231
+
232
+ var lo2 = a.lo2 + b.lo2 + carry;
233
+ carry = (lo2 < a.lo2 || (carry == 1 && lo2 == a.lo2)) ? 1 : 0;
234
+
235
+ var hi1 = a.hi1 + b.hi1 + carry;
236
+ carry = (hi1 < a.hi1 || (carry == 1 && hi1 == a.hi1)) ? 1 : 0;
237
+
238
+ var hi2 = a.hi2 + b.hi2 + carry;
239
+
240
+ return new i256(lo1, lo2, hi1, hi2);
241
+ }
242
+
243
+ @operator('-')
244
+ static sub(a: i256, b: i256): i256 {
245
+ var lo1 = a.lo1 - b.lo1;
246
+ var borrow = a.lo1 < b.lo1 ? 1 : 0;
247
+
248
+ var lo2 = a.lo2 - b.lo2 - borrow;
249
+ borrow = a.lo2 < b.lo2 + borrow ? 1 : 0;
250
+
251
+ var hi1 = a.hi1 - b.hi1 - borrow;
252
+ borrow = hi1 < b.hi1 + borrow ? 1 : 0;
253
+
254
+ var hi2 = a.hi2 - b.hi2 - borrow;
255
+
256
+ return new i256(lo1, lo2, hi1, hi2);
257
+ }
258
+
259
+ @inline @operator('|')
260
+ static or(a: i256, b: i256): i256 {
261
+ return new i256(a.lo1 | b.lo1, a.lo2 | b.lo2, a.hi1 | b.hi1, a.hi2 | b.hi2);
262
+ }
263
+
264
+ @inline @operator('^')
265
+ static xor(a: i256, b: i256): i256 {
266
+ return new i256(a.lo1 ^ b.lo1, a.lo2 ^ b.lo2, a.hi1 ^ b.hi1, a.hi2 ^ b.hi2);
267
+ }
268
+
269
+ @inline @operator('&')
270
+ static and(a: i256, b: i256): i256 {
271
+ return new i256(a.lo1 & b.lo1, a.lo2 & b.lo2, a.hi1 & b.hi1, a.hi2 & b.hi2);
272
+ }
273
+
274
+ @operator('<')
275
+ static lt(a: i256, b: i256): bool {
276
+ if (a.hi2 == b.hi2) {
277
+ if (a.hi1 == b.hi1) {
278
+ if (a.lo2 == b.lo2) {
279
+ return a.lo1 < b.lo1;
280
+ } else {
281
+ return a.lo2 < b.lo2;
282
+ }
283
+ } else {
284
+ return a.hi1 < b.hi1;
285
+ }
286
+ } else {
287
+ return a.hi2 < b.hi2;
288
+ }
289
+ }
290
+
291
+ @inline @operator('>')
292
+ static gt(a: i256, b: i256): bool {
293
+ return b < a;
294
+ }
295
+
296
+ @inline @operator('==')
297
+ static eq(a: i256, b: i256): bool {
298
+ return a.lo1 == b.lo1 && a.lo2 == b.lo2 && a.hi1 == b.hi1 && a.hi2 == b.hi2;
299
+ }
300
+
301
+ @inline @operator('!=')
302
+ static ne(a: i256, b: i256): bool {
303
+ return !i256.eq(a, b);
304
+ }
305
+
306
+ @inline @operator('<=')
307
+ static le(a: i256, b: i256): bool {
308
+ return !i256.gt(a, b);
309
+ }
310
+
311
+ @inline @operator('>=')
312
+ static ge(a: i256, b: i256): bool {
313
+ return !i256.lt(a, b);
314
+ }
315
+
316
+ @operator('<<')
317
+ static shl(value: i256, shift: i32): i256 {
318
+ shift &= 255;
319
+ if (shift == 0) return value;
320
+ if (shift >= 256) return new i256();
321
+ var lo1 = value.lo1;
322
+ var lo2 = value.lo2;
323
+ var hi1 = value.hi1;
324
+ var hi2 = value.hi2;
325
+ if (shift >= 192) {
326
+ let s = shift - 192;
327
+ return new i256(0, 0, 0, lo1 << s);
328
+ } else if (shift >= 128) {
329
+ let s = shift - 128;
330
+ return new i256(0, 0, lo1 << s, (lo2 << s) | (lo1 >>> (64 - s)));
331
+ } else if (shift >= 64) {
332
+ let s = shift - 64;
333
+ return new i256(0, (lo1 << s), (lo2 << s) | (lo1 >>> (64 - s)), (hi1 << s) | (lo2 >>> (64 - s)));
334
+ } else {
335
+ let s = shift;
336
+ return new i256(
337
+ lo1 << s,
338
+ (lo2 << s) | (lo1 >>> (64 - s)),
339
+ (hi1 << s) | (lo2 >>> (64 - s)),
340
+ (hi2 << s) | (hi1 >>> (64 - s)),
341
+ );
342
+ }
343
+ }
344
+
345
+ @operator('>>')
346
+ static shr(value: i256, shift: i32): i256 {
347
+ shift &= 255;
348
+ if (shift == 0) return value;
349
+ if (shift >= 256) {
350
+ let sign = value.isNeg() ? -1 : 0;
351
+ return new i256(sign, sign, sign, sign);
352
+ }
353
+ var lo1 = value.lo1;
354
+ var lo2 = value.lo2;
355
+ var hi1 = value.hi1;
356
+ var hi2 = value.hi2;
357
+ if (shift >= 192) {
358
+ let s = shift - 192;
359
+ let sign = value.isNeg() ? -1 : 0;
360
+ return new i256((hi2 >> s) | (sign << (64 - s)), sign, sign, sign);
361
+ } else if (shift >= 128) {
362
+ let s = shift - 128;
363
+ return new i256((hi1 >> s) | (hi2 << (64 - s)), (hi2 >> s) | (hi2 >> 63) << (64 - s), hi2 >> 63, hi2 >> 63);
364
+ } else if (shift >= 64) {
365
+ let s = shift - 64;
366
+ return new i256(
367
+ (lo2 >> s) | (hi1 << (64 - s)),
368
+ (hi1 >> s) | (hi2 << (64 - s)),
369
+ (hi2 >> s) | (hi2 >> 63) << (64 - s),
370
+ hi2 >> 63,
371
+ );
372
+ } else {
373
+ let s = shift;
374
+ return new i256(
375
+ (lo1 >> s) | (lo2 << (64 - s)),
376
+ (lo2 >> s) | (hi1 << (64 - s)),
377
+ (hi1 >> s) | (hi2 << (64 - s)),
378
+ (hi2 >> s) | (hi2 >> 63) << (64 - s),
379
+ );
380
+ }
381
+ }
382
+
383
+ @operator('>>>')
384
+ static shr_u(value: i256, shift: i32): i256 {
385
+ shift &= 255;
386
+ if (shift == 0) return value;
387
+ if (shift >= 256) return new i256();
388
+ var lo1 = value.lo1;
389
+ var lo2 = value.lo2;
390
+ var hi1 = value.hi1;
391
+ var hi2 = value.hi2;
392
+ if (shift >= 192) {
393
+ let s = shift - 192;
394
+ return new i256((hi2 >>> s), 0, 0, 0);
395
+ } else if (shift >= 128) {
396
+ let s = shift - 128;
397
+ return new i256((hi1 >>> s) | (hi2 << (64 - s)), (hi2 >>> s), 0, 0);
398
+ } else if (shift >= 64) {
399
+ let s = shift - 64;
400
+ return new i256(
401
+ (lo2 >>> s) | (hi1 << (64 - s)),
402
+ (hi1 >>> s) | (hi2 << (64 - s)),
403
+ (hi2 >>> s),
404
+ 0,
405
+ );
406
+ } else {
407
+ let s = shift;
408
+ return new i256(
409
+ (lo1 >>> s) | (lo2 << (64 - s)),
410
+ (lo2 >>> s) | (hi1 << (64 - s)),
411
+ (hi1 >>> s) | (hi2 << (64 - s)),
412
+ hi2 >>> s,
413
+ );
414
+ }
415
+ }
416
+
417
+ clone(): i256 {
418
+ return new i256(this.lo1, this.lo2, this.hi1, this.hi2);
419
+ }
420
+
421
+ // Helper methods to write the internal representation to a buffer
422
+ @inline
423
+ private toArrayBufferLE(buffer: usize): void {
424
+ store<i64>(buffer, this.lo1, 0 * sizeof<i64>());
425
+ store<i64>(buffer, this.lo2, 1 * sizeof<i64>());
426
+ store<i64>(buffer, this.hi1, 2 * sizeof<i64>());
427
+ store<i64>(buffer, this.hi2, 3 * sizeof<i64>());
428
+ }
429
+
430
+ @inline
431
+ private toArrayBufferBE(buffer: usize): void {
432
+ store<i64>(buffer, bswap<i64>(this.hi2), 0 * sizeof<i64>());
433
+ store<i64>(buffer, bswap<i64>(this.hi1), 1 * sizeof<i64>());
434
+ store<i64>(buffer, bswap<i64>(this.lo2), 2 * sizeof<i64>());
435
+ store<i64>(buffer, bswap<i64>(this.lo1), 3 * sizeof<i64>());
436
+ }
437
+
438
+ @inline
439
+ private toArrayBuffer(buffer: usize, bigEndian: bool = false): void {
440
+ if (bigEndian) {
441
+ this.toArrayBufferBE(buffer);
442
+ } else {
443
+ this.toArrayBufferLE(buffer);
444
+ }
445
+ }
446
+
447
+ /**
448
+ * Convert to Uint8Array
449
+ * @param bigEndian Little or Big Endian? Default: false
450
+ * @returns Uint8Array
451
+ */
452
+ @inline
453
+ toUint8Array(bigEndian: bool = false): Uint8Array {
454
+ var result = new Uint8Array(32);
455
+ this.toArrayBuffer(result.dataStart, bigEndian);
456
+ return result;
457
+ }
458
+
459
+ /**
460
+ * Convert to byte array
461
+ * @param bigEndian Little or Big Endian? Default: false
462
+ * @returns Array of bytes
463
+ */
464
+ @inline
465
+ toBytes(bigEndian: bool = false): u8[] {
466
+ var result = new Array<u8>(32);
467
+ this.toArrayBuffer(result.dataStart, bigEndian);
468
+ return result;
469
+ }
470
+
471
+ /**
472
+ * Convert to StaticArray of bytes
473
+ * @param bigEndian Little or Big Endian? Default: false
474
+ * @returns StaticArray<u8>
475
+ */
476
+ @inline
477
+ toStaticBytes(bigEndian: bool = false): StaticArray<u8> {
478
+ var result = new StaticArray<u8>(32);
479
+ this.toArrayBuffer(changetype<usize>(result), bigEndian);
480
+ return result;
481
+ }
482
+
483
+ // Other conversion methods can be added as needed, following similar patterns.
484
+
485
+ /**
486
+ * Generic type conversion
487
+ */
488
+ @inline
489
+ as<T>(): T {
490
+ var dummy!: T;
491
+ if (dummy instanceof bool) return <T>this.toBool();
492
+ else if (dummy instanceof i8) return <T>this.toI64();
493
+ else if (dummy instanceof u8) return <T>this.toU64();
494
+ else if (dummy instanceof i16) return <T>this.toI64();
495
+ else if (dummy instanceof u16) return <T>this.toU64();
496
+ else if (dummy instanceof i32) return <T>this.toI64();
497
+ else if (dummy instanceof u32) return <T>this.toU64();
498
+ else if (dummy instanceof i64) return <T>this.toI64();
499
+ else if (dummy instanceof u64) return <T>this.toU64();
500
+ else if (dummy instanceof i128) return <T>this.toI128();
501
+ else if (dummy instanceof u128) return <T>this.toU128();
502
+ else if (dummy instanceof i256) return <T>this;
503
+ else if (dummy instanceof u256) return <T>this.toU256();
504
+ else if (dummy instanceof u8[]) return <T>this.toBytes();
505
+ else if (dummy instanceof Uint8Array) return <T>this.toUint8Array();
506
+ else if (dummy instanceof StaticArray<u8>) return <T>this.toStaticBytes();
507
+ else if (dummy instanceof String) return <T>this.toString();
508
+ else throw new TypeError('Unsupported generic type');
509
+ }
510
+
511
+ @inline
512
+ toBool(): bool {
513
+ return this.lo1 != 0 || this.lo2 != 0 || this.hi1 != 0 || this.hi2 != 0;
514
+ }
515
+
516
+ @inline
517
+ toI64(): i64 {
518
+ return this.lo1;
519
+ }
520
+
521
+ @inline
522
+ toU64(): u64 {
523
+ return <u64>this.lo1;
524
+ }
525
+
526
+ @inline
527
+ toI32(): i32 {
528
+ return <i32>this.lo1;
529
+ }
530
+
531
+ @inline
532
+ toU32(): u32 {
533
+ return <u32>this.lo1;
534
+ }
535
+
536
+ @inline
537
+ toI128(): i128 {
538
+ return new i128(<u64>this.lo1, this.lo2);
539
+ }
540
+
541
+ @inline
542
+ toU128(): u128 {
543
+ return new u128(<u64>this.lo1, <u64>this.lo2);
544
+ }
545
+
546
+ @inline
547
+ toU256(): u256 {
548
+ return new u256(<u64>this.lo1, <u64>this.lo2, <u64>this.hi1, <u64>this.hi2);
549
+ }
550
+
551
+ @inline
552
+ public toString(radix: i32 = 10): string {
553
+ assert(radix == 10 || radix == 16, 'radix argument must be 10 or 16');
554
+ if (this.isZero()) return '0';
555
+
556
+ const isNegative = this.isNeg();
557
+ const value = isNegative ? this.neg() : this.clone();
558
+ let result = '';
559
+
560
+ if (radix == 16) {
561
+ const HEX_CHARS = '0123456789abcdef';
562
+ let shift: i32 = 252 - (i256.clz(value) & ~3);
563
+ let started = false;
564
+ while (shift >= 0) {
565
+ let digit = (<u8>((value.shr_u(shift)).lo1 & 0xF));
566
+ if (digit != 0 || started) {
567
+ // @ts-ignore
568
+ result += HEX_CHARS.charAt(digit);
569
+ started = true;
570
+ }
571
+ shift -= 4;
572
+ }
573
+ if (isNegative) {
574
+ result = '-' + result;
575
+ }
576
+ return result;
577
+ } else {
578
+ // Radix 10 conversion requires division, which needs to be implemented.
579
+ // Placeholder implementation (throws an error).
580
+ throw new Error('Radix 10 conversion is not implemented yet.');
581
+ }
582
+ }
583
+
584
+ shr_u(value: i32): i256 {
585
+ return i256.shr_u(this, value);
586
+ }
587
+
588
+ @inline
589
+ static clz(value: i256): i32 {
590
+ // For signed integers, leading zeros are counted from the sign bit.
591
+ // If the value is negative, we take its two's complement to get the magnitude.
592
+ if (value.isNeg()) {
593
+ value = value.neg();
594
+ }
595
+ if (value.hi2 != 0) {
596
+ return clz<u64>(value.hi2);
597
+ } else if (value.hi1 != 0) {
598
+ return clz<u64>(value.hi1) + 64;
599
+ } else if (value.lo2 != 0) {
600
+ return clz<u64>(value.lo2) + 128;
601
+ } else {
602
+ return clz<u64>(value.lo1) + 192;
603
+ }
604
+ }
605
+
606
+ }
@@ -1,5 +1,5 @@
1
1
  import { Potential } from '../lang/Definitions';
2
2
 
3
- export const ADDRESS_BYTE_LENGTH: u8 = 66;
3
+ export const ADDRESS_BYTE_LENGTH: i32 = 66;
4
4
  export declare type Address = string;
5
5
  export declare type PotentialAddress = Potential<Address>;