@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 +1 -1
- package/runtime/buffer/BytesReader.ts +20 -3
- package/runtime/buffer/BytesWriter.ts +41 -6
- package/runtime/contracts/OP721.ts +29 -1
- package/runtime/env/classes/UTXO.ts +5 -0
- package/runtime/env/decoders/TransactionDecoder.ts +8 -1
- package/runtime/env/enums/TransactionFlags.ts +1 -0
package/package.json
CHANGED
|
@@ -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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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 {
|
|
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
|
-
|
|
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 {
|