@btc-vision/btc-runtime 1.9.9 → 1.9.10

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.9.9",
3
+ "version": "1.9.10",
4
4
  "description": "Bitcoin Smart Contract Runtime",
5
5
  "main": "btc/index.ts",
6
6
  "scripts": {
@@ -203,8 +203,7 @@ export class BytesReader {
203
203
  }
204
204
 
205
205
  /**
206
- * [u32 length][raw bytes]. By default big-endian for the length,
207
- * to match AS BytesWriter's `writeBytesWithLength`.
206
+ * [u32 length][raw bytes]. By default big-endian for the length
208
207
  */
209
208
  public readBytesWithLength(be: boolean = true): Uint8Array {
210
209
  const length = this.readU32(be);
@@ -248,8 +247,17 @@ export class BytesReader {
248
247
 
249
248
  // ------------------- Arrays ------------------- //
250
249
 
250
+ public readArrayOfBuffer(be: boolean = true): Uint8Array[] {
251
+ const length = this.readU16(be);
252
+ const result: Uint8Array[] = new Array<Uint8Array>(length);
253
+ for (let i: u32 = 0; i < length; i++) {
254
+ result[i] = this.readBytesWithLength();
255
+ }
256
+ return result;
257
+ }
258
+
251
259
  public readU256Array(be: boolean = true): u256[] {
252
- const length = this.readU16();
260
+ const length = this.readU16(be);
253
261
  const result = new Array<u256>(length);
254
262
  for (let i: u32 = 0; i < length; i++) {
255
263
  result[i] = this.readU256(be);
@@ -19,6 +19,8 @@ import {
19
19
  } from '../utils';
20
20
  import { BytesReader } from './BytesReader';
21
21
 
22
+ const arrayTooLargeError: string = 'Array is too large';
23
+
22
24
  @final
23
25
  export class BytesWriter {
24
26
  private currentOffset: u32 = 0;
@@ -30,6 +32,17 @@ export class BytesWriter {
30
32
  this.buffer = new DataView(typedArray.buffer);
31
33
  }
32
34
 
35
+ public static estimateArrayOfBufferLength(values: Uint8Array[]): u32 {
36
+ if (values.length > 65535) throw new Revert(arrayTooLargeError);
37
+ let totalLength: u32 = U16_BYTE_LENGTH;
38
+
39
+ for (let i = 0; i < values.length; i++) {
40
+ totalLength += U32_BYTE_LENGTH + u32(values[i].length); // each entry has a u32 length prefix
41
+ }
42
+
43
+ return totalLength;
44
+ }
45
+
33
46
  public bufferLength(): u32 {
34
47
  return this.buffer.byteLength;
35
48
  }
@@ -197,8 +210,20 @@ export class BytesWriter {
197
210
 
198
211
  // ------------------ Array Writers ------------------ //
199
212
 
213
+ public writeArrayOfBuffer(values: Uint8Array[], be: boolean = true): void {
214
+ const totalLength = BytesWriter.estimateArrayOfBufferLength(values);
215
+
216
+ this.allocSafe(totalLength);
217
+ this.writeU16(u16(values.length), be);
218
+
219
+ for (let i = 0; i < values.length; i++) {
220
+ this.writeU32(u32(values[i].length), be);
221
+ this.writeBytes(values[i]);
222
+ }
223
+ }
224
+
200
225
  public writeU8Array(value: u8[], be: boolean = true): void {
201
- if (value.length > 65535) throw new Revert('Array size is too large');
226
+ if (value.length > 65535) throw new Revert(arrayTooLargeError);
202
227
  this.allocSafe(U16_BYTE_LENGTH + value.length);
203
228
  this.writeU16(u16(value.length), be);
204
229
 
@@ -208,7 +233,7 @@ export class BytesWriter {
208
233
  }
209
234
 
210
235
  public writeU16Array(value: u16[], be: boolean = true): void {
211
- if (value.length > 65535) throw new Revert('Array size is too large');
236
+ if (value.length > 65535) throw new Revert(arrayTooLargeError);
212
237
  this.allocSafe(U16_BYTE_LENGTH + value.length * U16_BYTE_LENGTH);
213
238
  this.writeU16(u16(value.length), be);
214
239
 
@@ -218,7 +243,7 @@ export class BytesWriter {
218
243
  }
219
244
 
220
245
  public writeU32Array(value: u32[], be: boolean = true): void {
221
- if (value.length > 65535) throw new Revert('Array size is too large');
246
+ if (value.length > 65535) throw new Revert(arrayTooLargeError);
222
247
  this.allocSafe(U16_BYTE_LENGTH + value.length * U32_BYTE_LENGTH);
223
248
  this.writeU16(u16(value.length), be);
224
249
 
@@ -228,7 +253,7 @@ export class BytesWriter {
228
253
  }
229
254
 
230
255
  public writeU64Array(value: u64[], be: boolean = true): void {
231
- if (value.length > 65535) throw new Revert('Array size is too large');
256
+ if (value.length > 65535) throw new Revert(arrayTooLargeError);
232
257
  this.allocSafe(U16_BYTE_LENGTH + value.length * U64_BYTE_LENGTH);
233
258
  this.writeU16(u16(value.length), be);
234
259
 
@@ -238,7 +263,7 @@ export class BytesWriter {
238
263
  }
239
264
 
240
265
  public writeU128Array(value: u128[], be: boolean = true): void {
241
- if (value.length > 65535) throw new Revert('Array size is too large');
266
+ if (value.length > 65535) throw new Revert(arrayTooLargeError);
242
267
  this.allocSafe(U16_BYTE_LENGTH + value.length * U128_BYTE_LENGTH);
243
268
  this.writeU16(u16(value.length), be);
244
269
 
@@ -248,7 +273,7 @@ export class BytesWriter {
248
273
  }
249
274
 
250
275
  public writeU256Array(value: u256[], be: boolean = true): void {
251
- if (value.length > 65535) throw new Revert('Array size is too large');
276
+ if (value.length > 65535) throw new Revert(arrayTooLargeError);
252
277
  this.allocSafe(U16_BYTE_LENGTH + value.length * U256_BYTE_LENGTH);
253
278
  this.writeU16(u16(value.length), be);
254
279
 
@@ -258,7 +283,7 @@ export class BytesWriter {
258
283
  }
259
284
 
260
285
  public writeAddressArray(value: Address[]): void {
261
- if (value.length > 65535) throw new Revert('Array size is too large');
286
+ if (value.length > 65535) throw new Revert(arrayTooLargeError);
262
287
  this.writeU16(u16(value.length));
263
288
 
264
289
  for (let i: i32 = 0; i < value.length; i++) {
@@ -7,12 +7,17 @@ export class TransactionInput {
7
7
  public readonly txId: Uint8Array,
8
8
  public readonly outputIndex: u16,
9
9
  public readonly scriptSig: Uint8Array,
10
+ public readonly witnesses: Uint8Array[] | null,
10
11
  public readonly coinbase: Uint8Array | null,
11
12
  ) {}
12
13
 
13
14
  public get isCoinbase(): boolean {
14
15
  return (this.flags & TransactionInputFlags.hasCoinbase) !== 0;
15
16
  }
17
+
18
+ public get hasWitnesses(): boolean {
19
+ return (this.flags & TransactionInputFlags.hasWitnesses) !== 0;
20
+ }
16
21
  }
17
22
 
18
23
  @final
@@ -35,7 +35,14 @@ export class TransactionDecoder {
35
35
  ? buffer.readBytesWithLength()
36
36
  : null;
37
37
 
38
- return new TransactionInput(flags, txId, outputIndex, scriptSig, coinbase);
38
+ const witnesses: Uint8Array[] | null = this.hasFlag(
39
+ flags,
40
+ TransactionInputFlags.hasWitnesses,
41
+ )
42
+ ? buffer.readArrayOfBuffer()
43
+ : null;
44
+
45
+ return new TransactionInput(flags, txId, outputIndex, scriptSig, witnesses, coinbase);
39
46
  }
40
47
 
41
48
  private decodeOutput(buffer: BytesReader): TransactionOutput {
@@ -1,5 +1,6 @@
1
1
  export enum TransactionInputFlags {
2
2
  hasCoinbase = 0b00000001,
3
+ hasWitnesses = 0b00000010,
3
4
  }
4
5
 
5
6
  export enum TransactionOutputFlags {