@btc-vision/btc-runtime 1.9.8 → 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.8",
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);
@@ -284,6 +292,15 @@ export class BytesReader {
284
292
  return result;
285
293
  }
286
294
 
295
+ public readU8Array(be: boolean = true): u8[] {
296
+ const length = this.readU16(be);
297
+ const result = new Array<u8>(length);
298
+ for (let i: u16 = 0; i < length; i++) {
299
+ result[i] = this.readU8();
300
+ }
301
+ return result;
302
+ }
303
+
287
304
  public readU128Array(be: boolean = true): u128[] {
288
305
  const length = this.readU16(be);
289
306
  const result = new Array<u128>(length);
@@ -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,30 @@ 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
+
225
+ public writeU8Array(value: u8[], be: boolean = true): void {
226
+ if (value.length > 65535) throw new Revert(arrayTooLargeError);
227
+ this.allocSafe(U16_BYTE_LENGTH + value.length);
228
+ this.writeU16(u16(value.length), be);
229
+
230
+ for (let i = 0; i < value.length; i++) {
231
+ this.writeU8(value[i]);
232
+ }
233
+ }
234
+
200
235
  public writeU16Array(value: u16[], be: boolean = true): void {
201
- if (value.length > 65535) throw new Revert('Array size is too large');
236
+ if (value.length > 65535) throw new Revert(arrayTooLargeError);
202
237
  this.allocSafe(U16_BYTE_LENGTH + value.length * U16_BYTE_LENGTH);
203
238
  this.writeU16(u16(value.length), be);
204
239
 
@@ -208,7 +243,7 @@ export class BytesWriter {
208
243
  }
209
244
 
210
245
  public writeU32Array(value: u32[], be: boolean = true): void {
211
- if (value.length > 65535) throw new Revert('Array size is too large');
246
+ if (value.length > 65535) throw new Revert(arrayTooLargeError);
212
247
  this.allocSafe(U16_BYTE_LENGTH + value.length * U32_BYTE_LENGTH);
213
248
  this.writeU16(u16(value.length), be);
214
249
 
@@ -218,7 +253,7 @@ export class BytesWriter {
218
253
  }
219
254
 
220
255
  public writeU64Array(value: u64[], be: boolean = true): void {
221
- if (value.length > 65535) throw new Revert('Array size is too large');
256
+ if (value.length > 65535) throw new Revert(arrayTooLargeError);
222
257
  this.allocSafe(U16_BYTE_LENGTH + value.length * U64_BYTE_LENGTH);
223
258
  this.writeU16(u16(value.length), be);
224
259
 
@@ -228,7 +263,7 @@ export class BytesWriter {
228
263
  }
229
264
 
230
265
  public writeU128Array(value: u128[], be: boolean = true): void {
231
- if (value.length > 65535) throw new Revert('Array size is too large');
266
+ if (value.length > 65535) throw new Revert(arrayTooLargeError);
232
267
  this.allocSafe(U16_BYTE_LENGTH + value.length * U128_BYTE_LENGTH);
233
268
  this.writeU16(u16(value.length), be);
234
269
 
@@ -238,7 +273,7 @@ export class BytesWriter {
238
273
  }
239
274
 
240
275
  public writeU256Array(value: u256[], be: boolean = true): void {
241
- if (value.length > 65535) throw new Revert('Array size is too large');
276
+ if (value.length > 65535) throw new Revert(arrayTooLargeError);
242
277
  this.allocSafe(U16_BYTE_LENGTH + value.length * U256_BYTE_LENGTH);
243
278
  this.writeU16(u16(value.length), be);
244
279
 
@@ -248,7 +283,7 @@ export class BytesWriter {
248
283
  }
249
284
 
250
285
  public writeAddressArray(value: Address[]): void {
251
- if (value.length > 65535) throw new Revert('Array size is too large');
286
+ if (value.length > 65535) throw new Revert(arrayTooLargeError);
252
287
  this.writeU16(u16(value.length));
253
288
 
254
289
  for (let i: i32 = 0; i < value.length; i++) {
@@ -24,7 +24,13 @@ import { IOP721 } from './interfaces/IOP721';
24
24
  import { OP721InitParameters } from './interfaces/OP721InitParameters';
25
25
  import { ReentrancyGuard } from './ReentrancyGuard';
26
26
  import { StoredMapU256 } from '../storage/maps/StoredMapU256';
27
- import { ApprovedEvent, ApprovedForAllEvent, MAX_URI_LENGTH, TransferredEvent, URIEvent, } from '../events/predefined';
27
+ import {
28
+ ApprovedEvent,
29
+ ApprovedForAllEvent,
30
+ MAX_URI_LENGTH,
31
+ TransferredEvent,
32
+ URIEvent,
33
+ } from '../events/predefined';
28
34
  import {
29
35
  ON_OP721_RECEIVED_SELECTOR,
30
36
  OP712_DOMAIN_TYPE_HASH,
@@ -251,6 +257,28 @@ export abstract class OP721 extends ReentrancyGuard implements IOP721 {
251
257
  return w;
252
258
  }
253
259
 
260
+ @method('changeMetadata')
261
+ public changeMetadata(calldata: Calldata): BytesWriter {
262
+ this.onlyDeployer(Blockchain.tx.sender);
263
+
264
+ const icon: string = calldata.readStringWithLength();
265
+ const banner: string = calldata.readStringWithLength();
266
+ const description: string = calldata.readStringWithLength();
267
+ const website: string = calldata.readStringWithLength();
268
+
269
+ if (icon.length == 0) throw new Revert('Icon cannot be empty');
270
+ if (banner.length == 0) throw new Revert('Banner cannot be empty');
271
+ if (description.length == 0) throw new Revert('Description cannot be empty');
272
+ if (website.length == 0) throw new Revert('Website cannot be empty');
273
+
274
+ this._collectionIcon.value = icon;
275
+ this._collectionBanner.value = banner;
276
+ this._collectionDescription.value = description;
277
+ this._collectionWebsite.value = website;
278
+
279
+ return new BytesWriter(0);
280
+ }
281
+
254
282
  @method('totalSupply')
255
283
  @returns({ name: 'totalSupply', type: ABIDataTypes.UINT256 })
256
284
  public fn_totalSupply(_: Calldata): BytesWriter {
@@ -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 {