@btc-vision/btc-runtime 1.8.1 → 1.9.0
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/README.md +57 -79
- package/package.json +8 -8
- package/runtime/buffer/BytesReader.ts +36 -45
- package/runtime/buffer/BytesWriter.ts +60 -20
- package/runtime/contracts/OP20.ts +636 -0
- package/runtime/contracts/OP_NET.ts +3 -3
- package/runtime/contracts/interfaces/IOP20.ts +15 -0
- package/runtime/contracts/interfaces/OP20InitParameters.ts +3 -1
- package/runtime/env/BlockchainEnvironment.ts +28 -7
- package/runtime/env/classes/Transaction.ts +1 -2
- package/runtime/env/global.ts +171 -23
- package/runtime/events/NetEvent.ts +1 -1
- package/runtime/events/predefined/{ApproveEvent.ts → ApprovedEvent.ts} +3 -3
- package/runtime/events/predefined/{MintEvent.ts → BurnedEvent.ts} +5 -6
- package/runtime/events/predefined/{TransferEvent.ts → MintedEvent.ts} +5 -6
- package/runtime/events/predefined/TransferredEvent.ts +18 -0
- package/runtime/events/predefined/index.ts +4 -4
- package/runtime/exports/index.ts +4 -4
- package/runtime/index.ts +13 -3
- package/runtime/math/abi.ts +10 -6
- package/runtime/math/bytes.ts +5 -17
- package/runtime/memory/AddressMemoryMap.ts +4 -5
- package/runtime/memory/KeyMerger.ts +7 -7
- package/runtime/memory/MapOfMap.ts +2 -7
- package/runtime/memory/Nested.ts +6 -8
- package/runtime/nested/PointerManager.ts +1 -1
- package/runtime/nested/codecs/AddressCodec.ts +1 -1
- package/runtime/nested/codecs/BooleanCodec.ts +1 -1
- package/runtime/nested/codecs/Ids.ts +1 -1
- package/runtime/nested/codecs/NumericCodec.ts +1 -1
- package/runtime/nested/codecs/StringCodec.ts +1 -1
- package/runtime/nested/codecs/VariableBytesCodec.ts +3 -3
- package/runtime/nested/storage/StorageMap.ts +3 -3
- package/runtime/nested/storage/StorageSet.ts +2 -2
- package/runtime/plugins/Plugin.ts +5 -7
- package/runtime/script/Bech32.ts +369 -0
- package/runtime/script/BitcoinAddresses.ts +208 -0
- package/runtime/script/BitcoinCodec.ts +395 -0
- package/runtime/script/Networks.ts +94 -0
- package/runtime/script/Opcodes.ts +155 -0
- package/runtime/script/Script.ts +463 -0
- package/runtime/script/ScriptUtils.ts +101 -0
- package/runtime/script/Segwit.ts +185 -0
- package/runtime/script/reader/ScriptReader.ts +247 -0
- package/runtime/secp256k1/ECPoint.ts +6 -12
- package/runtime/shared-libraries/TransferHelper.ts +72 -31
- package/runtime/storage/AdvancedStoredString.ts +1 -1
- package/runtime/storage/StoredAddress.ts +1 -1
- package/runtime/storage/StoredBoolean.ts +2 -4
- package/runtime/storage/StoredString.ts +6 -3
- package/runtime/storage/StoredU256.ts +1 -3
- package/runtime/storage/StoredU32.ts +1 -6
- package/runtime/storage/StoredU64.ts +1 -4
- package/runtime/storage/arrays/StoredBooleanArray.ts +7 -12
- package/runtime/storage/arrays/StoredPackedArray.ts +3 -13
- package/runtime/storage/maps/StoredMapU256.ts +5 -5
- package/runtime/types/Address.ts +49 -39
- package/runtime/types/SafeMath.ts +19 -18
- package/runtime/types/SafeMathI128.ts +14 -13
- package/runtime/utils/hex.ts +41 -19
- package/runtime/utils/index.ts +0 -2
- package/runtime/contracts/DeployableOP_20.ts +0 -415
- package/runtime/contracts/OP_20.ts +0 -9
- package/runtime/contracts/interfaces/IOP_20.ts +0 -19
- package/runtime/events/predefined/BurnEvent.ts +0 -14
- package/runtime/utils/b32.ts +0 -243
- package/runtime/utils/box.ts +0 -134
- package/runtime/utils/encodings.ts +0 -45
- /package/{LICENSE → LICENSE.md} +0 -0
|
@@ -3,72 +3,113 @@ import { BytesWriter } from '../buffer/BytesWriter';
|
|
|
3
3
|
import { Blockchain } from '../env';
|
|
4
4
|
import { encodeSelector, Selector } from '../math/abi';
|
|
5
5
|
import { Address } from '../types/Address';
|
|
6
|
-
import {
|
|
7
|
-
|
|
6
|
+
import {
|
|
7
|
+
ADDRESS_BYTE_LENGTH,
|
|
8
|
+
SELECTOR_BYTE_LENGTH,
|
|
9
|
+
U256_BYTE_LENGTH,
|
|
10
|
+
U32_BYTE_LENGTH,
|
|
11
|
+
} from '../utils';
|
|
8
12
|
|
|
9
|
-
export const
|
|
10
|
-
export const
|
|
11
|
-
export const
|
|
13
|
+
export const SafeTransferSignature = 'safeTransfer(address,uint256,bytes)';
|
|
14
|
+
export const SafeTransferFromSignature = 'safeTransferFrom(address,address,uint256,bytes)';
|
|
15
|
+
export const IncreaseAllowanceSignature = 'increaseAllowance(address,uint256)';
|
|
16
|
+
export const DecreaseAllowanceSignature = 'decreaseAllowance(address,uint256)';
|
|
17
|
+
export const BurnSignature = 'burn(uint256)';
|
|
12
18
|
|
|
13
19
|
export class TransferHelper {
|
|
14
|
-
public static get
|
|
15
|
-
return encodeSelector(
|
|
20
|
+
public static get INCREASE_ALLOWANCE_SELECTOR(): Selector {
|
|
21
|
+
return encodeSelector(IncreaseAllowanceSignature);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
public static get DECREASE_ALLOWANCE_SELECTOR(): Selector {
|
|
25
|
+
return encodeSelector(DecreaseAllowanceSignature);
|
|
16
26
|
}
|
|
17
27
|
|
|
18
28
|
public static get TRANSFER_SELECTOR(): Selector {
|
|
19
|
-
return encodeSelector(
|
|
29
|
+
return encodeSelector(SafeTransferSignature);
|
|
20
30
|
}
|
|
21
31
|
|
|
22
32
|
public static get TRANSFER_FROM_SELECTOR(): Selector {
|
|
23
|
-
return encodeSelector(
|
|
33
|
+
return encodeSelector(SafeTransferFromSignature);
|
|
24
34
|
}
|
|
25
35
|
|
|
26
|
-
public static
|
|
36
|
+
public static safeIncreaseAllowance(token: Address, spender: Address, amount: u256): void {
|
|
27
37
|
const calldata = new BytesWriter(
|
|
28
38
|
SELECTOR_BYTE_LENGTH + ADDRESS_BYTE_LENGTH + U256_BYTE_LENGTH,
|
|
29
39
|
);
|
|
30
|
-
calldata.writeSelector(this.
|
|
40
|
+
calldata.writeSelector(this.INCREASE_ALLOWANCE_SELECTOR);
|
|
31
41
|
calldata.writeAddress(spender);
|
|
32
42
|
calldata.writeU256(amount);
|
|
33
43
|
|
|
34
|
-
|
|
35
|
-
const isOk = response.readBoolean();
|
|
36
|
-
|
|
37
|
-
if (!isOk) {
|
|
38
|
-
throw new Revert(`TransferHelper: APPROVE_FAILED`);
|
|
39
|
-
}
|
|
44
|
+
Blockchain.call(token, calldata);
|
|
40
45
|
}
|
|
41
46
|
|
|
42
|
-
public static
|
|
47
|
+
public static safeDecreaseAllowance(token: Address, spender: Address, amount: u256): void {
|
|
43
48
|
const calldata = new BytesWriter(
|
|
44
49
|
SELECTOR_BYTE_LENGTH + ADDRESS_BYTE_LENGTH + U256_BYTE_LENGTH,
|
|
45
50
|
);
|
|
51
|
+
calldata.writeSelector(this.DECREASE_ALLOWANCE_SELECTOR);
|
|
52
|
+
calldata.writeAddress(spender);
|
|
53
|
+
calldata.writeU256(amount);
|
|
54
|
+
|
|
55
|
+
Blockchain.call(token, calldata);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
public static safeTransfer(
|
|
59
|
+
token: Address,
|
|
60
|
+
to: Address,
|
|
61
|
+
amount: u256,
|
|
62
|
+
data: Uint8Array = new Uint8Array(0),
|
|
63
|
+
): void {
|
|
64
|
+
const calldata = new BytesWriter(
|
|
65
|
+
SELECTOR_BYTE_LENGTH +
|
|
66
|
+
ADDRESS_BYTE_LENGTH +
|
|
67
|
+
U256_BYTE_LENGTH +
|
|
68
|
+
U32_BYTE_LENGTH +
|
|
69
|
+
data.length,
|
|
70
|
+
);
|
|
46
71
|
calldata.writeSelector(this.TRANSFER_SELECTOR);
|
|
47
72
|
calldata.writeAddress(to);
|
|
48
73
|
calldata.writeU256(amount);
|
|
74
|
+
calldata.writeBytesWithLength(data);
|
|
49
75
|
|
|
50
|
-
|
|
51
|
-
|
|
76
|
+
Blockchain.call(token, calldata);
|
|
77
|
+
}
|
|
52
78
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
79
|
+
/**
|
|
80
|
+
* Burns the specified amount of tokens from the contract.
|
|
81
|
+
* This function is used to destroy tokens, reducing the total supply.
|
|
82
|
+
* @param token The address of the token contract.
|
|
83
|
+
* @param amount The amount of tokens to burn.
|
|
84
|
+
*/
|
|
85
|
+
public static burn(token: Address, amount: u256): void {
|
|
86
|
+
const calldata = new BytesWriter(SELECTOR_BYTE_LENGTH + U256_BYTE_LENGTH);
|
|
87
|
+
calldata.writeSelector(encodeSelector(BurnSignature));
|
|
88
|
+
calldata.writeU256(amount);
|
|
89
|
+
|
|
90
|
+
Blockchain.call(token, calldata);
|
|
56
91
|
}
|
|
57
92
|
|
|
58
|
-
public static safeTransferFrom(
|
|
93
|
+
public static safeTransferFrom(
|
|
94
|
+
token: Address,
|
|
95
|
+
from: Address,
|
|
96
|
+
to: Address,
|
|
97
|
+
amount: u256,
|
|
98
|
+
data: Uint8Array = new Uint8Array(0),
|
|
99
|
+
): void {
|
|
59
100
|
const calldata = new BytesWriter(
|
|
60
|
-
SELECTOR_BYTE_LENGTH +
|
|
101
|
+
SELECTOR_BYTE_LENGTH +
|
|
102
|
+
ADDRESS_BYTE_LENGTH * 2 +
|
|
103
|
+
U256_BYTE_LENGTH +
|
|
104
|
+
U32_BYTE_LENGTH +
|
|
105
|
+
data.length,
|
|
61
106
|
);
|
|
62
107
|
calldata.writeSelector(this.TRANSFER_FROM_SELECTOR);
|
|
63
108
|
calldata.writeAddress(from);
|
|
64
109
|
calldata.writeAddress(to);
|
|
65
110
|
calldata.writeU256(amount);
|
|
111
|
+
calldata.writeBytesWithLength(data);
|
|
66
112
|
|
|
67
|
-
|
|
68
|
-
const isOk = response.readBoolean();
|
|
69
|
-
|
|
70
|
-
if (!isOk) {
|
|
71
|
-
throw new Revert(`TransferHelper: TRANSFER_FROM_FAILED`);
|
|
72
|
-
}
|
|
113
|
+
Blockchain.call(token, calldata);
|
|
73
114
|
}
|
|
74
115
|
}
|
|
@@ -44,7 +44,7 @@ export class AdvancedStoredString {
|
|
|
44
44
|
* chunkIndex=0 => header slot, 1 => second slot, etc.
|
|
45
45
|
*/
|
|
46
46
|
private getPointer(chunkIndex: u64): Uint8Array {
|
|
47
|
-
const base = encodePointer(this.pointer, this.subPointer);
|
|
47
|
+
const base = encodePointer(this.pointer, this.subPointer, true, 'AdvancedStoredString');
|
|
48
48
|
return bigEndianAdd(base, chunkIndex);
|
|
49
49
|
}
|
|
50
50
|
|
|
@@ -12,7 +12,7 @@ export class StoredAddress {
|
|
|
12
12
|
private readonly addressPointer: Uint8Array;
|
|
13
13
|
|
|
14
14
|
constructor(public pointer: u16) {
|
|
15
|
-
this.addressPointer = encodePointer(pointer, EMPTY_POINTER);
|
|
15
|
+
this.addressPointer = encodePointer(pointer, EMPTY_POINTER, true, 'StoredAddress');
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
private _value: Address = Address.dead();
|
|
@@ -12,7 +12,7 @@ export class StoredBoolean {
|
|
|
12
12
|
) {
|
|
13
13
|
const pointerBuffer = GET_EMPTY_BUFFER();
|
|
14
14
|
pointerBuffer[0] = pointer & 255;
|
|
15
|
-
pointerBuffer[1] = (pointer
|
|
15
|
+
pointerBuffer[1] = (pointer >> 8) & 255;
|
|
16
16
|
|
|
17
17
|
this.pointerBuffer = pointerBuffer;
|
|
18
18
|
|
|
@@ -49,8 +49,6 @@ export class StoredBoolean {
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
private ensureValue(): void {
|
|
52
|
-
this._value = Blockchain.getStorageAt(
|
|
53
|
-
this.pointerBuffer,
|
|
54
|
-
);
|
|
52
|
+
this._value = Blockchain.getStorageAt(this.pointerBuffer);
|
|
55
53
|
}
|
|
56
54
|
}
|
|
@@ -21,7 +21,10 @@ const MAX_LENGTH_U256 = u256.fromU32(<u32>MAX_LENGTH);
|
|
|
21
21
|
export class StoredString {
|
|
22
22
|
private readonly subPointer: Uint8Array;
|
|
23
23
|
|
|
24
|
-
constructor(
|
|
24
|
+
constructor(
|
|
25
|
+
public pointer: u16,
|
|
26
|
+
index: u64 = 0,
|
|
27
|
+
) {
|
|
25
28
|
const indexed = SafeMath.mul(u256.fromU64(index), MAX_LENGTH_U256);
|
|
26
29
|
this.subPointer = indexed.toUint8Array(true).slice(0, 30);
|
|
27
30
|
}
|
|
@@ -49,7 +52,7 @@ export class StoredString {
|
|
|
49
52
|
* chunkIndex=0 => header slot, 1 => second slot, etc.
|
|
50
53
|
*/
|
|
51
54
|
private getPointer(chunkIndex: u64): Uint8Array {
|
|
52
|
-
const base = encodePointer(this.pointer, this.subPointer);
|
|
55
|
+
const base = encodePointer(this.pointer, this.subPointer, true, 'StoredString');
|
|
53
56
|
return bigEndianAdd(base, chunkIndex);
|
|
54
57
|
}
|
|
55
58
|
|
|
@@ -201,4 +204,4 @@ export class StoredString {
|
|
|
201
204
|
// Decode UTF-8 into a normal string
|
|
202
205
|
this._value = String.UTF8.decode(out.buffer, false);
|
|
203
206
|
}
|
|
204
|
-
}
|
|
207
|
+
}
|
|
@@ -11,9 +11,7 @@ export class StoredU256 {
|
|
|
11
11
|
public pointer: u16,
|
|
12
12
|
public subPointer: Uint8Array,
|
|
13
13
|
) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
this.pointerBuffer = encodePointer(pointer, subPointer);
|
|
14
|
+
this.pointerBuffer = encodePointer(pointer, subPointer, true, 'StoredU256');
|
|
17
15
|
}
|
|
18
16
|
|
|
19
17
|
private _value: u256 = u256.Zero;
|
|
@@ -30,12 +30,7 @@ export class StoredU32 {
|
|
|
30
30
|
public pointer: u16,
|
|
31
31
|
public subPointer: Uint8Array,
|
|
32
32
|
) {
|
|
33
|
-
|
|
34
|
-
subPointer.length <= 30,
|
|
35
|
-
`You must pass a 30 bytes sub-pointer. (StoredU32, got ${subPointer.length})`,
|
|
36
|
-
);
|
|
37
|
-
|
|
38
|
-
this.bufferPointer = encodePointer(pointer, subPointer);
|
|
33
|
+
this.bufferPointer = encodePointer(pointer, subPointer, true, 'StoredU32');
|
|
39
34
|
}
|
|
40
35
|
|
|
41
36
|
/**
|
|
@@ -30,9 +30,7 @@ export class StoredU64 {
|
|
|
30
30
|
public pointer: u16,
|
|
31
31
|
public subPointer: Uint8Array,
|
|
32
32
|
) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
this.bufferPointer = encodePointer(pointer, subPointer);
|
|
33
|
+
this.bufferPointer = encodePointer(pointer, subPointer, true, 'StoredU64');
|
|
36
34
|
}
|
|
37
35
|
|
|
38
36
|
/**
|
|
@@ -118,7 +116,6 @@ export class StoredU64 {
|
|
|
118
116
|
return `[${this._values[0].toString()}, ${this._values[1].toString()}, ${this._values[2].toString()}, ${this._values[3].toString()}]`;
|
|
119
117
|
}
|
|
120
118
|
|
|
121
|
-
|
|
122
119
|
/**
|
|
123
120
|
* @method reset
|
|
124
121
|
* @description Resets the cached values to default and marks as changed.
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import {BytesWriter} from '../../buffer/BytesWriter';
|
|
2
|
-
import {Blockchain} from '../../env';
|
|
3
|
-
import {Revert} from '../../types/Revert';
|
|
1
|
+
import { BytesWriter } from '../../buffer/BytesWriter';
|
|
2
|
+
import { Blockchain } from '../../env';
|
|
3
|
+
import { Revert } from '../../types/Revert';
|
|
4
4
|
import {
|
|
5
5
|
addUint8ArraysBE,
|
|
6
6
|
bigEndianAdd,
|
|
7
|
-
encodeBasePointer,
|
|
8
7
|
GET_EMPTY_BUFFER,
|
|
9
8
|
getBit,
|
|
10
9
|
readLengthAndStartIndex,
|
|
11
10
|
setBit,
|
|
12
11
|
u64ToBE32Bytes,
|
|
13
12
|
} from '../../math/bytes';
|
|
14
|
-
import {DEFAULT_MAX_LENGTH} from './StoredPackedArray';
|
|
13
|
+
import { DEFAULT_MAX_LENGTH } from './StoredPackedArray';
|
|
14
|
+
import { encodePointer } from '../../math/abi';
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* @class StoredBooleanArray
|
|
@@ -52,12 +52,7 @@ export class StoredBooleanArray {
|
|
|
52
52
|
public subPtr: Uint8Array,
|
|
53
53
|
protected MAX_LENGTH: u32 = DEFAULT_MAX_LENGTH,
|
|
54
54
|
) {
|
|
55
|
-
|
|
56
|
-
subPtr.length <= 30,
|
|
57
|
-
`You must pass a 30 bytes sub-pointer. (StoredBooleanArray, got ${subPtr.length})`,
|
|
58
|
-
);
|
|
59
|
-
|
|
60
|
-
const basePointer = encodeBasePointer(pointer, subPtr);
|
|
55
|
+
const basePointer = encodePointer(pointer, subPtr, true, 'StoredBooleanArray');
|
|
61
56
|
this.lengthPointer = Uint8Array.wrap(basePointer.buffer);
|
|
62
57
|
this.basePointer = bigEndianAdd(basePointer, 1);
|
|
63
58
|
|
|
@@ -72,7 +67,7 @@ export class StoredBooleanArray {
|
|
|
72
67
|
public get previousOffset(): u32 {
|
|
73
68
|
return <u32>(
|
|
74
69
|
((this._startIndex +
|
|
75
|
-
|
|
70
|
+
<u64>(this.nextItemOffset === 0 ? this.nextItemOffset : this.nextItemOffset - 1)) %
|
|
76
71
|
this.MAX_LENGTH)
|
|
77
72
|
);
|
|
78
73
|
}
|
|
@@ -1,12 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
bigEndianAdd,
|
|
3
|
-
encodeBasePointer,
|
|
4
|
-
GET_EMPTY_BUFFER,
|
|
5
|
-
readLengthAndStartIndex,
|
|
6
|
-
writeLengthAndStartIndex,
|
|
7
|
-
} from '../../math/bytes';
|
|
1
|
+
import { bigEndianAdd, GET_EMPTY_BUFFER, readLengthAndStartIndex, writeLengthAndStartIndex, } from '../../math/bytes';
|
|
8
2
|
import { Blockchain } from '../../env';
|
|
9
3
|
import { Revert } from '../../types/Revert';
|
|
4
|
+
import { encodePointer } from '../../math/abi';
|
|
10
5
|
|
|
11
6
|
export const DEFAULT_MAX_LENGTH: u32 = u32.MAX_VALUE - 1;
|
|
12
7
|
|
|
@@ -55,12 +50,7 @@ export abstract class StoredPackedArray<T> {
|
|
|
55
50
|
protected defaultValue: T,
|
|
56
51
|
protected MAX_LENGTH: u32 = DEFAULT_MAX_LENGTH,
|
|
57
52
|
) {
|
|
58
|
-
|
|
59
|
-
subPointer.length <= 30,
|
|
60
|
-
`You must pass a 30 bytes sub-pointer. (Array, got ${subPointer.length})`,
|
|
61
|
-
);
|
|
62
|
-
|
|
63
|
-
const basePointer = encodeBasePointer(pointer, subPointer);
|
|
53
|
+
const basePointer = encodePointer(pointer, subPointer, true, 'StoredPackedArray');
|
|
64
54
|
this.lengthPointer = Uint8Array.wrap(basePointer.buffer);
|
|
65
55
|
this.basePointer = bigEndianAdd(basePointer, 1);
|
|
66
56
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {u256} from '@btc-vision/as-bignum/assembly';
|
|
2
|
-
import {Blockchain} from '../../env';
|
|
3
|
-
import {EMPTY_BUFFER} from
|
|
4
|
-
import {BytesWriter} from
|
|
5
|
-
import {encodePointerUnknownLength} from
|
|
1
|
+
import { u256 } from '@btc-vision/as-bignum/assembly';
|
|
2
|
+
import { Blockchain } from '../../env';
|
|
3
|
+
import { EMPTY_BUFFER } from '../../math/bytes';
|
|
4
|
+
import { BytesWriter } from '../../buffer/BytesWriter';
|
|
5
|
+
import { encodePointerUnknownLength } from '../../math/abi';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* StoredMap<K, V> implementation using u256 as keys.
|
package/runtime/types/Address.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { Potential } from '../lang/Definitions';
|
|
2
2
|
import { ADDRESS_BYTE_LENGTH, decodeHexArray, encodeHexFromBuffer } from '../utils';
|
|
3
|
-
import { bech32m as _bech32m, toWords } from '../utils/b32';
|
|
4
3
|
import { Revert } from './Revert';
|
|
4
|
+
import { BitcoinAddresses } from '../script/BitcoinAddresses';
|
|
5
|
+
import { Blockchain } from '../env';
|
|
6
|
+
import { Network } from '../script/Networks';
|
|
5
7
|
|
|
6
8
|
@final
|
|
7
9
|
export class Address extends Uint8Array {
|
|
@@ -35,6 +37,23 @@ export class Address extends Uint8Array {
|
|
|
35
37
|
return new Address(decodeHexArray(pubKey));
|
|
36
38
|
}
|
|
37
39
|
|
|
40
|
+
public static fromUint8Array(bytes: Uint8Array): Address {
|
|
41
|
+
const cloned = new Address();
|
|
42
|
+
// Copy the raw memory directly:
|
|
43
|
+
memory.copy(cloned.dataStart, bytes.dataStart, ADDRESS_BYTE_LENGTH);
|
|
44
|
+
|
|
45
|
+
return cloned;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
public static toCSV(address: Uint8Array, blocks: u32): string {
|
|
49
|
+
return BitcoinAddresses.csvP2wshAddress(address, blocks, Network.hrp(Blockchain.network))
|
|
50
|
+
.address;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
public static p2wpkh(address: Uint8Array): string {
|
|
54
|
+
return BitcoinAddresses.p2wpkh(address, Network.hrp(Blockchain.network));
|
|
55
|
+
}
|
|
56
|
+
|
|
38
57
|
public isZero(): bool {
|
|
39
58
|
for (let i = 0; i < this.length; i++) {
|
|
40
59
|
if (this[i] != 0) {
|
|
@@ -45,6 +64,19 @@ export class Address extends Uint8Array {
|
|
|
45
64
|
return true;
|
|
46
65
|
}
|
|
47
66
|
|
|
67
|
+
public isDead(): bool {
|
|
68
|
+
for (let i = 0; i < this.length; i++) {
|
|
69
|
+
if (this[i] != DEAD_ADDRESS[i]) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
public p2tr(): string {
|
|
77
|
+
return BitcoinAddresses.p2trKeyPathAddress(this, Network.hrp(Blockchain.network));
|
|
78
|
+
}
|
|
79
|
+
|
|
48
80
|
/**
|
|
49
81
|
* Create a new Address that is a copy of the current Address.
|
|
50
82
|
* @returns {Address}
|
|
@@ -60,47 +92,10 @@ export class Address extends Uint8Array {
|
|
|
60
92
|
return cloned;
|
|
61
93
|
}
|
|
62
94
|
|
|
63
|
-
public static fromUint8Array(bytes: Uint8Array): Address {
|
|
64
|
-
const cloned = new Address();
|
|
65
|
-
// Copy the raw memory directly:
|
|
66
|
-
memory.copy(cloned.dataStart, bytes.dataStart, ADDRESS_BYTE_LENGTH);
|
|
67
|
-
|
|
68
|
-
return cloned;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
95
|
public toHex(): string {
|
|
72
96
|
return encodeHexFromBuffer(this.buffer);
|
|
73
97
|
}
|
|
74
98
|
|
|
75
|
-
public empty(): bool {
|
|
76
|
-
for (let i = 0; i < this.length; i++) {
|
|
77
|
-
if (this[i] != 0) {
|
|
78
|
-
return false;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
return true;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Set the public key
|
|
87
|
-
* @param {ArrayLike} publicKey The public key
|
|
88
|
-
* @returns {void}
|
|
89
|
-
*/
|
|
90
|
-
public newSet(publicKey: u8[]): void {
|
|
91
|
-
if (publicKey.length !== 32) {
|
|
92
|
-
throw new Error('Invalid public key length');
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
super.set(publicKey);
|
|
96
|
-
|
|
97
|
-
this.isDefined = true;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
public toBech32m(): string {
|
|
101
|
-
return String.UTF8.decode(_bech32m(String.UTF8.encode('bc'), toWords(this.buffer)));
|
|
102
|
-
}
|
|
103
|
-
|
|
104
99
|
@operator('==')
|
|
105
100
|
public equals(a: Address): bool {
|
|
106
101
|
if (a.length != this.length) {
|
|
@@ -166,7 +161,22 @@ export class Address extends Uint8Array {
|
|
|
166
161
|
}
|
|
167
162
|
|
|
168
163
|
public toString(): string {
|
|
169
|
-
return this.
|
|
164
|
+
return this.p2tr();
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Set the public key
|
|
169
|
+
* @param {ArrayLike} publicKey The public key
|
|
170
|
+
* @returns {void}
|
|
171
|
+
*/
|
|
172
|
+
private newSet(publicKey: u8[]): void {
|
|
173
|
+
if (publicKey.length !== 32) {
|
|
174
|
+
throw new Revert(`Invalid public key length (${publicKey.length})`);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
super.set(publicKey);
|
|
178
|
+
|
|
179
|
+
this.isDefined = true;
|
|
170
180
|
}
|
|
171
181
|
|
|
172
182
|
@operator('[]')
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { u128, u256 } from '@btc-vision/as-bignum/assembly';
|
|
2
|
+
import { Revert } from './Revert';
|
|
2
3
|
|
|
3
4
|
export class SafeMath {
|
|
4
5
|
public static ZERO: u256 = u256.fromU32(0);
|
|
@@ -6,7 +7,7 @@ export class SafeMath {
|
|
|
6
7
|
public static add(a: u256, b: u256): u256 {
|
|
7
8
|
const c: u256 = u256.add(a, b);
|
|
8
9
|
if (c < a) {
|
|
9
|
-
throw new
|
|
10
|
+
throw new Revert('SafeMath: addition overflow');
|
|
10
11
|
}
|
|
11
12
|
return c;
|
|
12
13
|
}
|
|
@@ -14,7 +15,7 @@ export class SafeMath {
|
|
|
14
15
|
public static add128(a: u128, b: u128): u128 {
|
|
15
16
|
const c: u128 = u128.add(a, b);
|
|
16
17
|
if (c < a) {
|
|
17
|
-
throw new
|
|
18
|
+
throw new Revert('SafeMath: addition overflow');
|
|
18
19
|
}
|
|
19
20
|
return c;
|
|
20
21
|
}
|
|
@@ -23,14 +24,14 @@ export class SafeMath {
|
|
|
23
24
|
const c: u64 = a + b;
|
|
24
25
|
|
|
25
26
|
if (c < a) {
|
|
26
|
-
throw new
|
|
27
|
+
throw new Revert('SafeMath: addition overflow');
|
|
27
28
|
}
|
|
28
29
|
return c;
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
public static sub(a: u256, b: u256): u256 {
|
|
32
33
|
if (a < b) {
|
|
33
|
-
throw new
|
|
34
|
+
throw new Revert('SafeMath: subtraction overflow');
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
return u256.sub(a, b);
|
|
@@ -38,7 +39,7 @@ export class SafeMath {
|
|
|
38
39
|
|
|
39
40
|
public static sub128(a: u128, b: u128): u128 {
|
|
40
41
|
if (a < b) {
|
|
41
|
-
throw new
|
|
42
|
+
throw new Revert('SafeMath: subtraction overflow');
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
return u128.sub(a, b);
|
|
@@ -46,7 +47,7 @@ export class SafeMath {
|
|
|
46
47
|
|
|
47
48
|
public static sub64(a: u64, b: u64): u64 {
|
|
48
49
|
if (a < b) {
|
|
49
|
-
throw new
|
|
50
|
+
throw new Revert('SafeMath: subtraction overflow');
|
|
50
51
|
}
|
|
51
52
|
|
|
52
53
|
return a - b;
|
|
@@ -54,7 +55,7 @@ export class SafeMath {
|
|
|
54
55
|
|
|
55
56
|
// Computes (a * b) % modulus with full precision
|
|
56
57
|
public static mulmod(a: u256, b: u256, modulus: u256): u256 {
|
|
57
|
-
if (u256.eq(modulus, u256.Zero)) throw new
|
|
58
|
+
if (u256.eq(modulus, u256.Zero)) throw new Revert('SafeMath: modulo by zero');
|
|
58
59
|
|
|
59
60
|
const mul = SafeMath.mul(a, b);
|
|
60
61
|
return SafeMath.mod(mul, modulus);
|
|
@@ -64,7 +65,7 @@ export class SafeMath {
|
|
|
64
65
|
@operator('%')
|
|
65
66
|
public static mod(a: u256, b: u256): u256 {
|
|
66
67
|
if (u256.eq(b, u256.Zero)) {
|
|
67
|
-
throw new
|
|
68
|
+
throw new Revert('SafeMath: modulo by zero');
|
|
68
69
|
}
|
|
69
70
|
|
|
70
71
|
const divResult = SafeMath.div(a, b);
|
|
@@ -85,7 +86,7 @@ export class SafeMath {
|
|
|
85
86
|
{
|
|
86
87
|
// old_r - (quotient * r)
|
|
87
88
|
const tmp = r;
|
|
88
|
-
r = u256.sub(old_r, u256.mul(quotient, r));
|
|
89
|
+
r = u256.sub(old_r, u256.mul(quotient, r)); // unchecked subtract
|
|
89
90
|
old_r = tmp;
|
|
90
91
|
}
|
|
91
92
|
|
|
@@ -93,7 +94,7 @@ export class SafeMath {
|
|
|
93
94
|
{
|
|
94
95
|
// old_s - (quotient * s)
|
|
95
96
|
const tmp = s;
|
|
96
|
-
s = u256.sub(old_s, u256.mul(quotient, s));
|
|
97
|
+
s = u256.sub(old_s, u256.mul(quotient, s)); // unchecked subtract
|
|
97
98
|
old_s = tmp;
|
|
98
99
|
}
|
|
99
100
|
}
|
|
@@ -133,7 +134,7 @@ export class SafeMath {
|
|
|
133
134
|
const d: u256 = SafeMath.div(c, a);
|
|
134
135
|
|
|
135
136
|
if (u256.ne(d, b)) {
|
|
136
|
-
throw new
|
|
137
|
+
throw new Revert('SafeMath: multiplication overflow');
|
|
137
138
|
}
|
|
138
139
|
|
|
139
140
|
return c;
|
|
@@ -148,7 +149,7 @@ export class SafeMath {
|
|
|
148
149
|
const d: u128 = SafeMath.div128(c, a);
|
|
149
150
|
|
|
150
151
|
if (u128.ne(d, b)) {
|
|
151
|
-
throw new
|
|
152
|
+
throw new Revert('SafeMath: multiplication overflow');
|
|
152
153
|
}
|
|
153
154
|
|
|
154
155
|
return c;
|
|
@@ -162,7 +163,7 @@ export class SafeMath {
|
|
|
162
163
|
const c: u64 = a * b;
|
|
163
164
|
|
|
164
165
|
if (c / a !== b) {
|
|
165
|
-
throw new
|
|
166
|
+
throw new Revert('SafeMath: multiplication overflow');
|
|
166
167
|
}
|
|
167
168
|
|
|
168
169
|
return c;
|
|
@@ -170,7 +171,7 @@ export class SafeMath {
|
|
|
170
171
|
|
|
171
172
|
public static div64(a: u64, b: u64): u64 {
|
|
172
173
|
if (b === 0) {
|
|
173
|
-
throw new
|
|
174
|
+
throw new Revert('Division by zero');
|
|
174
175
|
}
|
|
175
176
|
|
|
176
177
|
if (a === 0) {
|
|
@@ -190,7 +191,7 @@ export class SafeMath {
|
|
|
190
191
|
|
|
191
192
|
public static div128(a: u128, b: u128): u128 {
|
|
192
193
|
if (b.isZero()) {
|
|
193
|
-
throw new
|
|
194
|
+
throw new Revert('Division by zero');
|
|
194
195
|
}
|
|
195
196
|
|
|
196
197
|
if (a.isZero()) {
|
|
@@ -227,7 +228,7 @@ export class SafeMath {
|
|
|
227
228
|
@operator('/')
|
|
228
229
|
public static div(a: u256, b: u256): u256 {
|
|
229
230
|
if (b.isZero()) {
|
|
230
|
-
throw new
|
|
231
|
+
throw new Revert('Division by zero');
|
|
231
232
|
}
|
|
232
233
|
|
|
233
234
|
if (a.isZero()) {
|
|
@@ -431,7 +432,7 @@ export class SafeMath {
|
|
|
431
432
|
*/
|
|
432
433
|
static inc(value: u256): u256 {
|
|
433
434
|
if (u256.eq(value, u256.Max)) {
|
|
434
|
-
throw new
|
|
435
|
+
throw new Revert('SafeMath: increment overflow');
|
|
435
436
|
}
|
|
436
437
|
|
|
437
438
|
return value.preInc();
|
|
@@ -444,7 +445,7 @@ export class SafeMath {
|
|
|
444
445
|
*/
|
|
445
446
|
public static dec(value: u256): u256 {
|
|
446
447
|
if (u256.eq(value, u256.Zero)) {
|
|
447
|
-
throw new
|
|
448
|
+
throw new Revert('SafeMath: decrement overflow');
|
|
448
449
|
}
|
|
449
450
|
|
|
450
451
|
return value.preDec();
|