@vbyte/btc-dev 1.1.8 → 2.1.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/CHANGELOG.md +127 -0
- package/LICENSE +21 -121
- package/README.md +69 -3
- package/dist/const.d.ts +3 -0
- package/dist/const.js +23 -22
- package/dist/error.d.ts +11 -0
- package/dist/error.js +20 -0
- package/dist/index.d.ts +12 -11
- package/dist/index.js +11 -10
- package/dist/lib/address/api.d.ts +2 -2
- package/dist/lib/address/api.js +13 -12
- package/dist/lib/address/encode.d.ts +1 -1
- package/dist/lib/address/encode.js +26 -24
- package/dist/lib/address/index.d.ts +6 -6
- package/dist/lib/address/index.js +6 -6
- package/dist/lib/address/p2pkh.d.ts +2 -2
- package/dist/lib/address/p2pkh.js +15 -15
- package/dist/lib/address/p2sh.d.ts +2 -2
- package/dist/lib/address/p2sh.js +14 -14
- package/dist/lib/address/p2tr.d.ts +2 -2
- package/dist/lib/address/p2tr.js +14 -14
- package/dist/lib/address/p2wpkh.d.ts +2 -2
- package/dist/lib/address/p2wpkh.js +15 -15
- package/dist/lib/address/p2wsh.d.ts +2 -2
- package/dist/lib/address/p2wsh.js +14 -14
- package/dist/lib/address/script.d.ts +1 -1
- package/dist/lib/address/script.js +16 -16
- package/dist/lib/address/util.d.ts +1 -1
- package/dist/lib/address/util.js +24 -22
- package/dist/lib/meta/index.d.ts +4 -4
- package/dist/lib/meta/index.js +4 -4
- package/dist/lib/meta/locktime.d.ts +1 -1
- package/dist/lib/meta/locktime.js +13 -12
- package/dist/lib/meta/ref.js +13 -9
- package/dist/lib/meta/scribe.d.ts +2 -2
- package/dist/lib/meta/scribe.js +71 -56
- package/dist/lib/meta/sequence.d.ts +1 -1
- package/dist/lib/meta/sequence.js +21 -19
- package/dist/lib/script/decode.d.ts +2 -2
- package/dist/lib/script/decode.js +53 -17
- package/dist/lib/script/encode.d.ts +1 -1
- package/dist/lib/script/encode.js +21 -16
- package/dist/lib/script/index.d.ts +5 -13
- package/dist/lib/script/index.js +5 -14
- package/dist/lib/script/lock.d.ts +2 -2
- package/dist/lib/script/lock.js +15 -12
- package/dist/lib/script/util.js +4 -4
- package/dist/lib/script/words.js +131 -130
- package/dist/lib/sighash/index.d.ts +3 -3
- package/dist/lib/sighash/index.js +3 -3
- package/dist/lib/sighash/segwit.d.ts +2 -2
- package/dist/lib/sighash/segwit.js +18 -14
- package/dist/lib/sighash/taproot.d.ts +2 -2
- package/dist/lib/sighash/taproot.js +27 -23
- package/dist/lib/sighash/util.d.ts +2 -2
- package/dist/lib/sighash/util.js +8 -7
- package/dist/lib/signer/index.d.ts +2 -2
- package/dist/lib/signer/index.js +2 -2
- package/dist/lib/signer/sign.d.ts +1 -1
- package/dist/lib/signer/sign.js +43 -7
- package/dist/lib/signer/verify.d.ts +17 -3
- package/dist/lib/signer/verify.js +232 -3
- package/dist/lib/taproot/cblock.d.ts +1 -1
- package/dist/lib/taproot/cblock.js +16 -17
- package/dist/lib/taproot/encode.d.ts +1 -1
- package/dist/lib/taproot/encode.js +9 -8
- package/dist/lib/taproot/index.d.ts +4 -4
- package/dist/lib/taproot/index.js +4 -4
- package/dist/lib/taproot/parse.d.ts +1 -1
- package/dist/lib/taproot/parse.js +15 -15
- package/dist/lib/taproot/tree.d.ts +2 -2
- package/dist/lib/taproot/tree.js +12 -7
- package/dist/lib/tx/create.d.ts +1 -1
- package/dist/lib/tx/create.js +28 -12
- package/dist/lib/tx/decode.d.ts +2 -2
- package/dist/lib/tx/decode.js +52 -17
- package/dist/lib/tx/encode.d.ts +2 -2
- package/dist/lib/tx/encode.js +13 -16
- package/dist/lib/tx/index.d.ts +7 -7
- package/dist/lib/tx/index.js +7 -7
- package/dist/lib/tx/parse.d.ts +1 -1
- package/dist/lib/tx/parse.js +9 -9
- package/dist/lib/tx/size.d.ts +2 -2
- package/dist/lib/tx/size.js +9 -11
- package/dist/lib/tx/util.d.ts +2 -2
- package/dist/lib/tx/util.js +22 -20
- package/dist/lib/tx/validate.d.ts +1 -1
- package/dist/lib/tx/validate.js +37 -9
- package/dist/lib/witness/index.d.ts +2 -2
- package/dist/lib/witness/index.js +2 -2
- package/dist/lib/witness/parse.d.ts +2 -2
- package/dist/lib/witness/parse.js +24 -23
- package/dist/lib/witness/util.d.ts +2 -2
- package/dist/lib/witness/util.js +5 -5
- package/dist/main.cjs +3305 -2035
- package/dist/main.cjs.map +1 -1
- package/dist/module.mjs +3303 -2036
- package/dist/module.mjs.map +1 -1
- package/dist/package.json +24 -19
- package/dist/schema/base.d.ts +1 -1
- package/dist/schema/base.js +17 -13
- package/dist/schema/index.d.ts +2 -2
- package/dist/schema/index.js +2 -2
- package/dist/schema/taproot.d.ts +1 -1
- package/dist/schema/taproot.js +2 -2
- package/dist/schema/tx.d.ts +1 -1
- package/dist/schema/tx.js +4 -4
- package/dist/script.js +10 -12
- package/dist/script.js.map +1 -1
- package/dist/types/address.d.ts +4 -4
- package/dist/types/index.d.ts +8 -8
- package/dist/types/index.js +8 -8
- package/dist/types/meta.d.ts +4 -4
- package/dist/types/psbt.d.ts +2 -2
- package/dist/types/script.d.ts +2 -2
- package/dist/types/sighash.d.ts +2 -2
- package/dist/types/witness.d.ts +5 -5
- package/docs/API.md +1145 -0
- package/docs/CONVENTIONS.md +316 -0
- package/docs/FAQ.md +396 -0
- package/docs/GUIDE.md +1102 -0
- package/package.json +24 -19
- package/src/const.ts +0 -61
- package/src/index.ts +0 -13
- package/src/lib/address/api.ts +0 -50
- package/src/lib/address/encode.ts +0 -183
- package/src/lib/address/index.ts +0 -7
- package/src/lib/address/p2pkh.ts +0 -94
- package/src/lib/address/p2sh.ts +0 -96
- package/src/lib/address/p2tr.ts +0 -91
- package/src/lib/address/p2wpkh.ts +0 -94
- package/src/lib/address/p2wsh.ts +0 -92
- package/src/lib/address/script.ts +0 -63
- package/src/lib/address/util.ts +0 -87
- package/src/lib/meta/index.ts +0 -4
- package/src/lib/meta/locktime.ts +0 -57
- package/src/lib/meta/ref.ts +0 -107
- package/src/lib/meta/scribe.ts +0 -256
- package/src/lib/meta/sequence.ts +0 -146
- package/src/lib/script/decode.ts +0 -85
- package/src/lib/script/encode.ts +0 -129
- package/src/lib/script/index.ts +0 -20
- package/src/lib/script/lock.ts +0 -73
- package/src/lib/script/util.ts +0 -78
- package/src/lib/script/words.ts +0 -182
- package/src/lib/sighash/index.ts +0 -3
- package/src/lib/sighash/segwit.ts +0 -152
- package/src/lib/sighash/taproot.ts +0 -206
- package/src/lib/sighash/util.ts +0 -51
- package/src/lib/signer/index.ts +0 -2
- package/src/lib/signer/sign.ts +0 -39
- package/src/lib/signer/verify.ts +0 -88
- package/src/lib/taproot/cblock.ts +0 -96
- package/src/lib/taproot/encode.ts +0 -49
- package/src/lib/taproot/index.ts +0 -4
- package/src/lib/taproot/parse.ts +0 -65
- package/src/lib/taproot/tree.ts +0 -94
- package/src/lib/tx/create.ts +0 -90
- package/src/lib/tx/decode.ts +0 -123
- package/src/lib/tx/encode.ts +0 -155
- package/src/lib/tx/index.ts +0 -7
- package/src/lib/tx/parse.ts +0 -69
- package/src/lib/tx/size.ts +0 -68
- package/src/lib/tx/util.ts +0 -111
- package/src/lib/tx/validate.ts +0 -49
- package/src/lib/witness/index.ts +0 -2
- package/src/lib/witness/parse.ts +0 -127
- package/src/lib/witness/util.ts +0 -18
- package/src/schema/base.ts +0 -57
- package/src/schema/index.ts +0 -2
- package/src/schema/taproot.ts +0 -12
- package/src/schema/tx.ts +0 -48
- package/src/types/address.ts +0 -35
- package/src/types/index.ts +0 -8
- package/src/types/meta.ts +0 -48
- package/src/types/psbt.ts +0 -15
- package/src/types/script.ts +0 -18
- package/src/types/sighash.ts +0 -16
- package/src/types/taproot.ts +0 -41
- package/src/types/txdata.ts +0 -85
- package/src/types/witness.ts +0 -42
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { Buff, Stream } from
|
|
2
|
-
import {
|
|
1
|
+
import { Buff, Stream } from "@vbyte/buff";
|
|
2
|
+
import { MAX_SCRIPT_SIZE, OP_1_OFFSET } from "../../const.js";
|
|
3
|
+
import { ValidationError } from "../../error.js";
|
|
4
|
+
import { get_asm_code } from "./words.js";
|
|
3
5
|
const MAX_WORD_SIZE = 520;
|
|
4
6
|
export function encode_script(words, varint = false) {
|
|
5
7
|
if (words.length === 0)
|
|
@@ -9,14 +11,17 @@ export function encode_script(words, varint = false) {
|
|
|
9
11
|
bytes.push(encode_script_word(word));
|
|
10
12
|
}
|
|
11
13
|
const buffer = Buff.join(bytes);
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
if (buffer.length > MAX_SCRIPT_SIZE) {
|
|
15
|
+
throw new ValidationError(`script size ${buffer.length} exceeds consensus limit of ${MAX_SCRIPT_SIZE} bytes`);
|
|
16
|
+
}
|
|
17
|
+
return varint
|
|
18
|
+
? buffer.prepend(Buff.create_varint(buffer.length, "le"))
|
|
14
19
|
: buffer;
|
|
15
20
|
}
|
|
16
21
|
export function encode_script_word(word) {
|
|
17
22
|
let buff;
|
|
18
|
-
if (typeof
|
|
19
|
-
if (word.startsWith(
|
|
23
|
+
if (typeof word === "string") {
|
|
24
|
+
if (word.startsWith("OP_")) {
|
|
20
25
|
const asm_code = get_asm_code(word);
|
|
21
26
|
return Buff.num(asm_code, 1);
|
|
22
27
|
}
|
|
@@ -27,23 +32,23 @@ export function encode_script_word(word) {
|
|
|
27
32
|
buff = Buff.str(word);
|
|
28
33
|
}
|
|
29
34
|
}
|
|
30
|
-
else if (typeof
|
|
35
|
+
else if (typeof word === "number") {
|
|
31
36
|
buff = Buff.num(word);
|
|
32
37
|
}
|
|
33
38
|
else if (word instanceof Uint8Array) {
|
|
34
39
|
buff = new Buff(word);
|
|
35
40
|
}
|
|
36
41
|
else {
|
|
37
|
-
throw new
|
|
42
|
+
throw new ValidationError(`invalid script word type: ${typeof word}. Expected string, number, or Uint8Array`);
|
|
38
43
|
}
|
|
39
44
|
if (buff.length === 1 && buff[0] <= 16) {
|
|
40
45
|
if (buff[0] !== 0)
|
|
41
|
-
buff[0] +=
|
|
46
|
+
buff[0] += OP_1_OFFSET;
|
|
42
47
|
}
|
|
43
48
|
else if (buff.length > MAX_WORD_SIZE) {
|
|
44
49
|
let words;
|
|
45
50
|
words = split_script_word(buff);
|
|
46
|
-
words = words.map(e => prefix_word_size(e));
|
|
51
|
+
words = words.map((e) => prefix_word_size(e));
|
|
47
52
|
buff = Buff.join(words);
|
|
48
53
|
}
|
|
49
54
|
else {
|
|
@@ -68,13 +73,13 @@ export function get_size_varint(size) {
|
|
|
68
73
|
const OP_PUSHDATA1 = Buff.num(0x4c, 1);
|
|
69
74
|
const OP_PUSHDATA2 = Buff.num(0x4d, 1);
|
|
70
75
|
switch (true) {
|
|
71
|
-
case
|
|
76
|
+
case size <= 0x4b:
|
|
72
77
|
return Buff.num(size);
|
|
73
|
-
case
|
|
74
|
-
return Buff.join([OP_PUSHDATA1, Buff.num(size, 1,
|
|
75
|
-
case
|
|
76
|
-
return Buff.join([OP_PUSHDATA2, Buff.num(size, 2,
|
|
78
|
+
case size > 0x4b && size < 0x100:
|
|
79
|
+
return Buff.join([OP_PUSHDATA1, Buff.num(size, 1, "le")]);
|
|
80
|
+
case size >= 0x100 && size <= MAX_WORD_SIZE:
|
|
81
|
+
return Buff.join([OP_PUSHDATA2, Buff.num(size, 2, "le")]);
|
|
77
82
|
default:
|
|
78
|
-
throw new
|
|
83
|
+
throw new ValidationError(`invalid script word size: ${size}. Maximum allowed is ${MAX_WORD_SIZE} bytes`);
|
|
79
84
|
}
|
|
80
85
|
}
|
|
@@ -1,13 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export * from
|
|
4
|
-
export * from
|
|
5
|
-
export * from
|
|
6
|
-
export * from './util.js';
|
|
7
|
-
export * from './words.js';
|
|
8
|
-
export declare namespace ScriptUtil {
|
|
9
|
-
const parse: typeof parse_script;
|
|
10
|
-
const decode: typeof decode_script;
|
|
11
|
-
const encode: typeof encode_script;
|
|
12
|
-
const is_valid: typeof is_valid_script;
|
|
13
|
-
}
|
|
1
|
+
export * from "./decode.js";
|
|
2
|
+
export * from "./encode.js";
|
|
3
|
+
export * from "./lock.js";
|
|
4
|
+
export * from "./util.js";
|
|
5
|
+
export * from "./words.js";
|
package/dist/lib/script/index.js
CHANGED
|
@@ -1,14 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export * from
|
|
4
|
-
export * from
|
|
5
|
-
export * from
|
|
6
|
-
export * from './util.js';
|
|
7
|
-
export * from './words.js';
|
|
8
|
-
export var ScriptUtil;
|
|
9
|
-
(function (ScriptUtil) {
|
|
10
|
-
ScriptUtil.parse = parse_script;
|
|
11
|
-
ScriptUtil.decode = decode_script;
|
|
12
|
-
ScriptUtil.encode = encode_script;
|
|
13
|
-
ScriptUtil.is_valid = is_valid_script;
|
|
14
|
-
})(ScriptUtil || (ScriptUtil = {}));
|
|
1
|
+
export * from "./decode.js";
|
|
2
|
+
export * from "./encode.js";
|
|
3
|
+
export * from "./lock.js";
|
|
4
|
+
export * from "./util.js";
|
|
5
|
+
export * from "./words.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Bytes } from
|
|
2
|
-
import type { LockScriptInfo, LockScriptType, WitnessVersion } from
|
|
1
|
+
import { type Bytes } from "@vbyte/buff";
|
|
2
|
+
import type { LockScriptInfo, LockScriptType, WitnessVersion } from "../../types/index.js";
|
|
3
3
|
export declare function is_return_script(script: Bytes): boolean;
|
|
4
4
|
export declare function get_lock_script_info(script: Bytes): LockScriptInfo;
|
|
5
5
|
export declare function get_lock_script_type(script: Bytes): LockScriptType | null;
|
package/dist/lib/script/lock.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Buff } from
|
|
2
|
-
import { LOCK_SCRIPT_REGEX } from
|
|
1
|
+
import { Buff } from "@vbyte/buff";
|
|
2
|
+
import { LOCK_SCRIPT_REGEX } from "../../const.js";
|
|
3
3
|
export function is_return_script(script) {
|
|
4
4
|
const bytes = Buff.bytes(script);
|
|
5
5
|
return bytes.at(0) === 0x6a;
|
|
@@ -7,7 +7,7 @@ export function is_return_script(script) {
|
|
|
7
7
|
export function get_lock_script_info(script) {
|
|
8
8
|
return {
|
|
9
9
|
type: get_lock_script_type(script),
|
|
10
|
-
version: get_lock_script_version(script)
|
|
10
|
+
version: get_lock_script_version(script),
|
|
11
11
|
};
|
|
12
12
|
}
|
|
13
13
|
export function get_lock_script_type(script) {
|
|
@@ -21,32 +21,35 @@ export function get_lock_script_type(script) {
|
|
|
21
21
|
export function get_lock_script_version(script) {
|
|
22
22
|
const version = Buff.bytes(script);
|
|
23
23
|
switch (version.at(0)) {
|
|
24
|
-
case 0x00:
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
case 0x00:
|
|
25
|
+
return 0;
|
|
26
|
+
case 0x51:
|
|
27
|
+
return 1;
|
|
28
|
+
default:
|
|
29
|
+
return null;
|
|
27
30
|
}
|
|
28
31
|
}
|
|
29
32
|
export function is_p2pkh_script(script) {
|
|
30
33
|
const hex = Buff.bytes(script).hex;
|
|
31
|
-
return LOCK_SCRIPT_REGEX
|
|
34
|
+
return LOCK_SCRIPT_REGEX.p2pkh.test(hex);
|
|
32
35
|
}
|
|
33
36
|
export function is_p2sh_script(script) {
|
|
34
37
|
const hex = Buff.bytes(script).hex;
|
|
35
|
-
return LOCK_SCRIPT_REGEX
|
|
38
|
+
return LOCK_SCRIPT_REGEX.p2sh.test(hex);
|
|
36
39
|
}
|
|
37
40
|
export function is_p2wpkh_script(script) {
|
|
38
41
|
const hex = Buff.bytes(script).hex;
|
|
39
|
-
return LOCK_SCRIPT_REGEX
|
|
42
|
+
return LOCK_SCRIPT_REGEX.p2wpkh.test(hex);
|
|
40
43
|
}
|
|
41
44
|
export function is_p2wsh_script(script) {
|
|
42
45
|
const hex = Buff.bytes(script).hex;
|
|
43
|
-
return LOCK_SCRIPT_REGEX
|
|
46
|
+
return LOCK_SCRIPT_REGEX.p2wsh.test(hex);
|
|
44
47
|
}
|
|
45
48
|
export function is_p2tr_script(script) {
|
|
46
49
|
const hex = Buff.bytes(script).hex;
|
|
47
|
-
return LOCK_SCRIPT_REGEX
|
|
50
|
+
return LOCK_SCRIPT_REGEX.p2tr.test(hex);
|
|
48
51
|
}
|
|
49
52
|
export function is_opreturn_script(script) {
|
|
50
53
|
const hex = Buff.bytes(script).hex;
|
|
51
|
-
return LOCK_SCRIPT_REGEX
|
|
54
|
+
return LOCK_SCRIPT_REGEX.opreturn.test(hex);
|
|
52
55
|
}
|
package/dist/lib/script/util.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { Buff } from
|
|
1
|
+
import { Buff } from "@vbyte/buff";
|
|
2
2
|
export function prefix_script_size(script) {
|
|
3
|
-
return Buff.bytes(script).prefix_varint(
|
|
3
|
+
return Buff.bytes(script).prefix_varint("le").hex;
|
|
4
4
|
}
|
|
5
5
|
export function parse_script_pubkeys(script) {
|
|
6
|
-
const scriptHex = typeof script ===
|
|
6
|
+
const scriptHex = typeof script === "string" ? script : Buff.bytes(script).hex;
|
|
7
7
|
const pubkeyPattern = /20([0-9a-f]{64})(ac|ad|ba)/gi;
|
|
8
8
|
const matches = [...scriptHex.matchAll(pubkeyPattern)];
|
|
9
|
-
return matches.map(match => match[1]);
|
|
9
|
+
return matches.map((match) => match[1]);
|
|
10
10
|
}
|
package/dist/lib/script/words.js
CHANGED
|
@@ -1,148 +1,149 @@
|
|
|
1
|
+
import { ValidationError } from "../../error.js";
|
|
1
2
|
export const OPCODE_MAP = {
|
|
2
|
-
OP_0:
|
|
3
|
-
OP_PUSHDATA1:
|
|
4
|
-
OP_PUSHDATA2:
|
|
5
|
-
OP_PUSHDATA4:
|
|
6
|
-
OP_1NEGATE:
|
|
7
|
-
OP_SUCCESS80:
|
|
8
|
-
OP_1:
|
|
9
|
-
OP_2:
|
|
10
|
-
OP_3:
|
|
11
|
-
OP_4:
|
|
12
|
-
OP_5:
|
|
13
|
-
OP_6:
|
|
14
|
-
OP_7:
|
|
15
|
-
OP_8:
|
|
16
|
-
OP_9:
|
|
17
|
-
OP_10:
|
|
18
|
-
OP_11:
|
|
19
|
-
OP_12:
|
|
20
|
-
OP_13:
|
|
21
|
-
OP_14:
|
|
22
|
-
OP_15:
|
|
23
|
-
OP_16:
|
|
24
|
-
OP_NOP:
|
|
25
|
-
OP_SUCCESS98:
|
|
26
|
-
OP_IF:
|
|
27
|
-
OP_NOTIF:
|
|
28
|
-
OP_ELSE:
|
|
29
|
-
OP_ENDIF:
|
|
30
|
-
OP_VERIFY:
|
|
31
|
-
OP_RETURN:
|
|
32
|
-
OP_TOALTSTACK:
|
|
33
|
-
OP_FROMALTSTACK:
|
|
34
|
-
OP_2DROP:
|
|
35
|
-
OP_2DUP:
|
|
36
|
-
OP_3DUP:
|
|
37
|
-
OP_2OVER:
|
|
38
|
-
OP_2ROT:
|
|
39
|
-
OP_2SWAP:
|
|
40
|
-
OP_IFDUP:
|
|
41
|
-
OP_DEPTH:
|
|
42
|
-
OP_DROP:
|
|
43
|
-
OP_DUP:
|
|
44
|
-
OP_NIP:
|
|
45
|
-
OP_OVER:
|
|
46
|
-
OP_PICK:
|
|
47
|
-
OP_ROLL:
|
|
48
|
-
OP_ROT:
|
|
49
|
-
OP_SWAP:
|
|
50
|
-
OP_TUCK:
|
|
51
|
-
OP_SUCCESS126:
|
|
52
|
-
OP_SUCCESS127:
|
|
53
|
-
OP_SUCCESS128:
|
|
54
|
-
OP_SUCCESS129:
|
|
55
|
-
OP_SIZE:
|
|
56
|
-
OP_SUCCESS131:
|
|
57
|
-
OP_SUCCESS132:
|
|
58
|
-
OP_SUCCESS133:
|
|
59
|
-
OP_SUCCESS134:
|
|
60
|
-
OP_EQUAL:
|
|
61
|
-
OP_EQUALVERIFY:
|
|
62
|
-
OP_SUCCESS137:
|
|
63
|
-
OP_SUCCESS138:
|
|
64
|
-
OP_1ADD:
|
|
65
|
-
OP_1SUB:
|
|
66
|
-
OP_SUCCESS141:
|
|
67
|
-
OP_SUCCESS142:
|
|
68
|
-
OP_NEGATE:
|
|
69
|
-
OP_ABS:
|
|
70
|
-
OP_NOT:
|
|
71
|
-
OP_0NOTEQUAL:
|
|
72
|
-
OP_ADD:
|
|
73
|
-
OP_SUB:
|
|
74
|
-
OP_SUCCESS149:
|
|
75
|
-
OP_SUCCESS150:
|
|
76
|
-
OP_SUCCESS151:
|
|
77
|
-
OP_SUCCESS152:
|
|
78
|
-
OP_SUCCESS153:
|
|
79
|
-
OP_BOOLAND:
|
|
80
|
-
OP_BOOLOR:
|
|
81
|
-
OP_NUMEQUAL:
|
|
82
|
-
OP_NUMEQUALVERIFY:
|
|
83
|
-
OP_NUMNOTEQUAL:
|
|
84
|
-
OP_LESSTHAN:
|
|
85
|
-
OP_GREATERTHAN:
|
|
86
|
-
OP_LESSTHANOREQUAL:
|
|
87
|
-
OP_GREATERTHANOREQUAL:
|
|
88
|
-
OP_MIN:
|
|
89
|
-
OP_MAX:
|
|
90
|
-
OP_WITHIN:
|
|
91
|
-
OP_RIPEMD160:
|
|
92
|
-
OP_SHA1:
|
|
93
|
-
OP_SHA256:
|
|
94
|
-
OP_HASH160:
|
|
95
|
-
OP_HASH256:
|
|
96
|
-
OP_CODESEPARATOR:
|
|
97
|
-
OP_CHECKSIG:
|
|
98
|
-
OP_CHECKSIGVERIFY:
|
|
99
|
-
OP_CHECKMULTISIG:
|
|
100
|
-
OP_CHECKMULTISIGVERIFY:
|
|
101
|
-
OP_NOP1:
|
|
102
|
-
OP_CHECKLOCKTIMEVERIFY:
|
|
103
|
-
OP_CHECKSEQUENCEVERIFY:
|
|
104
|
-
OP_NOP4:
|
|
105
|
-
OP_NOP5:
|
|
106
|
-
OP_NOP6:
|
|
107
|
-
OP_NOP7:
|
|
108
|
-
OP_NOP8:
|
|
109
|
-
OP_NOP9:
|
|
110
|
-
OP_NOP10:
|
|
111
|
-
OP_CHECKSIGADD:
|
|
3
|
+
OP_0: 0x00,
|
|
4
|
+
OP_PUSHDATA1: 0x4c,
|
|
5
|
+
OP_PUSHDATA2: 0x4d,
|
|
6
|
+
OP_PUSHDATA4: 0x4e,
|
|
7
|
+
OP_1NEGATE: 0x4f,
|
|
8
|
+
OP_SUCCESS80: 0x50,
|
|
9
|
+
OP_1: 0x51,
|
|
10
|
+
OP_2: 0x52,
|
|
11
|
+
OP_3: 0x53,
|
|
12
|
+
OP_4: 0x54,
|
|
13
|
+
OP_5: 0x55,
|
|
14
|
+
OP_6: 0x56,
|
|
15
|
+
OP_7: 0x57,
|
|
16
|
+
OP_8: 0x58,
|
|
17
|
+
OP_9: 0x59,
|
|
18
|
+
OP_10: 0x5a,
|
|
19
|
+
OP_11: 0x5b,
|
|
20
|
+
OP_12: 0x5c,
|
|
21
|
+
OP_13: 0x5d,
|
|
22
|
+
OP_14: 0x5e,
|
|
23
|
+
OP_15: 0x5f,
|
|
24
|
+
OP_16: 0x60,
|
|
25
|
+
OP_NOP: 0x61,
|
|
26
|
+
OP_SUCCESS98: 0x62,
|
|
27
|
+
OP_IF: 0x63,
|
|
28
|
+
OP_NOTIF: 0x64,
|
|
29
|
+
OP_ELSE: 0x67,
|
|
30
|
+
OP_ENDIF: 0x68,
|
|
31
|
+
OP_VERIFY: 0x69,
|
|
32
|
+
OP_RETURN: 0x6a,
|
|
33
|
+
OP_TOALTSTACK: 0x6b,
|
|
34
|
+
OP_FROMALTSTACK: 0x6c,
|
|
35
|
+
OP_2DROP: 0x6d,
|
|
36
|
+
OP_2DUP: 0x6e,
|
|
37
|
+
OP_3DUP: 0x6f,
|
|
38
|
+
OP_2OVER: 0x70,
|
|
39
|
+
OP_2ROT: 0x71,
|
|
40
|
+
OP_2SWAP: 0x72,
|
|
41
|
+
OP_IFDUP: 0x73,
|
|
42
|
+
OP_DEPTH: 0x74,
|
|
43
|
+
OP_DROP: 0x75,
|
|
44
|
+
OP_DUP: 0x76,
|
|
45
|
+
OP_NIP: 0x77,
|
|
46
|
+
OP_OVER: 0x78,
|
|
47
|
+
OP_PICK: 0x79,
|
|
48
|
+
OP_ROLL: 0x7a,
|
|
49
|
+
OP_ROT: 0x7b,
|
|
50
|
+
OP_SWAP: 0x7c,
|
|
51
|
+
OP_TUCK: 0x7d,
|
|
52
|
+
OP_SUCCESS126: 0x7e,
|
|
53
|
+
OP_SUCCESS127: 0x7f,
|
|
54
|
+
OP_SUCCESS128: 0x80,
|
|
55
|
+
OP_SUCCESS129: 0x81,
|
|
56
|
+
OP_SIZE: 0x82,
|
|
57
|
+
OP_SUCCESS131: 0x83,
|
|
58
|
+
OP_SUCCESS132: 0x84,
|
|
59
|
+
OP_SUCCESS133: 0x85,
|
|
60
|
+
OP_SUCCESS134: 0x86,
|
|
61
|
+
OP_EQUAL: 0x87,
|
|
62
|
+
OP_EQUALVERIFY: 0x88,
|
|
63
|
+
OP_SUCCESS137: 0x89,
|
|
64
|
+
OP_SUCCESS138: 0x8a,
|
|
65
|
+
OP_1ADD: 0x8b,
|
|
66
|
+
OP_1SUB: 0x8c,
|
|
67
|
+
OP_SUCCESS141: 0x8d,
|
|
68
|
+
OP_SUCCESS142: 0x8e,
|
|
69
|
+
OP_NEGATE: 0x8f,
|
|
70
|
+
OP_ABS: 0x90,
|
|
71
|
+
OP_NOT: 0x91,
|
|
72
|
+
OP_0NOTEQUAL: 0x92,
|
|
73
|
+
OP_ADD: 0x93,
|
|
74
|
+
OP_SUB: 0x94,
|
|
75
|
+
OP_SUCCESS149: 0x95,
|
|
76
|
+
OP_SUCCESS150: 0x96,
|
|
77
|
+
OP_SUCCESS151: 0x97,
|
|
78
|
+
OP_SUCCESS152: 0x98,
|
|
79
|
+
OP_SUCCESS153: 0x99,
|
|
80
|
+
OP_BOOLAND: 0x9a,
|
|
81
|
+
OP_BOOLOR: 0x9b,
|
|
82
|
+
OP_NUMEQUAL: 0x9c,
|
|
83
|
+
OP_NUMEQUALVERIFY: 0x9d,
|
|
84
|
+
OP_NUMNOTEQUAL: 0x9e,
|
|
85
|
+
OP_LESSTHAN: 0x9f,
|
|
86
|
+
OP_GREATERTHAN: 0xa0,
|
|
87
|
+
OP_LESSTHANOREQUAL: 0xa1,
|
|
88
|
+
OP_GREATERTHANOREQUAL: 0xa2,
|
|
89
|
+
OP_MIN: 0xa3,
|
|
90
|
+
OP_MAX: 0xa4,
|
|
91
|
+
OP_WITHIN: 0xa5,
|
|
92
|
+
OP_RIPEMD160: 0xa6,
|
|
93
|
+
OP_SHA1: 0xa7,
|
|
94
|
+
OP_SHA256: 0xa8,
|
|
95
|
+
OP_HASH160: 0xa9,
|
|
96
|
+
OP_HASH256: 0xaa,
|
|
97
|
+
OP_CODESEPARATOR: 0xab,
|
|
98
|
+
OP_CHECKSIG: 0xac,
|
|
99
|
+
OP_CHECKSIGVERIFY: 0xad,
|
|
100
|
+
OP_CHECKMULTISIG: 0xae,
|
|
101
|
+
OP_CHECKMULTISIGVERIFY: 0xaf,
|
|
102
|
+
OP_NOP1: 0xb0,
|
|
103
|
+
OP_CHECKLOCKTIMEVERIFY: 0xb1,
|
|
104
|
+
OP_CHECKSEQUENCEVERIFY: 0xb2,
|
|
105
|
+
OP_NOP4: 0xb3,
|
|
106
|
+
OP_NOP5: 0xb4,
|
|
107
|
+
OP_NOP6: 0xb5,
|
|
108
|
+
OP_NOP7: 0xb6,
|
|
109
|
+
OP_NOP8: 0xb7,
|
|
110
|
+
OP_NOP9: 0xb8,
|
|
111
|
+
OP_NOP10: 0xb9,
|
|
112
|
+
OP_CHECKSIGADD: 0xba,
|
|
112
113
|
};
|
|
113
114
|
export function get_op_code(num) {
|
|
114
115
|
if (num > 186 && num < 255) {
|
|
115
|
-
return
|
|
116
|
+
return `OP_SUCCESS${String(num)}`;
|
|
116
117
|
}
|
|
117
118
|
for (const [k, v] of Object.entries(OPCODE_MAP)) {
|
|
118
119
|
if (v === num)
|
|
119
120
|
return k;
|
|
120
121
|
}
|
|
121
|
-
throw new
|
|
122
|
+
throw new ValidationError(`opcode not found for value: ${num} (0x${num.toString(16)}). Valid range is 0x00-0xba`);
|
|
122
123
|
}
|
|
123
124
|
export function get_asm_code(string) {
|
|
124
125
|
for (const [k, v] of Object.entries(OPCODE_MAP)) {
|
|
125
126
|
if (k === string)
|
|
126
127
|
return Number(v);
|
|
127
128
|
}
|
|
128
|
-
throw new
|
|
129
|
+
throw new ValidationError(`opcode not found: "${string}". Valid opcodes start with "OP_" (e.g., OP_DUP, OP_CHECKSIG)`);
|
|
129
130
|
}
|
|
130
131
|
export function get_op_type(word) {
|
|
131
132
|
switch (true) {
|
|
132
|
-
case
|
|
133
|
-
return
|
|
134
|
-
case
|
|
135
|
-
return
|
|
136
|
-
case
|
|
137
|
-
return
|
|
138
|
-
case
|
|
139
|
-
return
|
|
140
|
-
case
|
|
141
|
-
return
|
|
142
|
-
case
|
|
143
|
-
return
|
|
133
|
+
case word === 0:
|
|
134
|
+
return "opcode";
|
|
135
|
+
case word >= 1 && word <= 75:
|
|
136
|
+
return "varint";
|
|
137
|
+
case word === 76:
|
|
138
|
+
return "pushdata1";
|
|
139
|
+
case word === 77:
|
|
140
|
+
return "pushdata2";
|
|
141
|
+
case word === 78:
|
|
142
|
+
return "pushdata4";
|
|
143
|
+
case word <= 254:
|
|
144
|
+
return "opcode";
|
|
144
145
|
default:
|
|
145
|
-
throw new
|
|
146
|
+
throw new ValidationError(`invalid word value: ${word}. Expected 0-254`);
|
|
146
147
|
}
|
|
147
148
|
}
|
|
148
149
|
export function is_valid_op(word) {
|
|
@@ -150,13 +151,13 @@ export function is_valid_op(word) {
|
|
|
150
151
|
const MAX_RANGE = 254;
|
|
151
152
|
const DISABLED_OPCODES = [];
|
|
152
153
|
switch (true) {
|
|
153
|
-
case
|
|
154
|
+
case typeof word !== "number":
|
|
154
155
|
return false;
|
|
155
|
-
case
|
|
156
|
+
case word === 0:
|
|
156
157
|
return true;
|
|
157
|
-
case
|
|
158
|
+
case DISABLED_OPCODES.includes(word):
|
|
158
159
|
return false;
|
|
159
|
-
case
|
|
160
|
+
case MIN_RANGE < word && word < MAX_RANGE:
|
|
160
161
|
return true;
|
|
161
162
|
default:
|
|
162
163
|
return false;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
1
|
+
export * from "./segwit.js";
|
|
2
|
+
export * from "./taproot.js";
|
|
3
|
+
export * from "./util.js";
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
1
|
+
export * from "./segwit.js";
|
|
2
|
+
export * from "./taproot.js";
|
|
3
|
+
export * from "./util.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Buff } from
|
|
2
|
-
import { SigHashOptions, TxData, TxInput, TxOutput } from
|
|
1
|
+
import { Buff } from "@vbyte/buff";
|
|
2
|
+
import type { SigHashOptions, TxData, TxInput, TxOutput } from "../../types/index.js";
|
|
3
3
|
export declare function hash_segwit_tx(txdata: TxData, options?: SigHashOptions): Buff;
|
|
4
4
|
export declare function bip143_hash_prevouts(vin: TxInput[], isAnypay?: boolean): Uint8Array;
|
|
5
5
|
export declare function bip143_hash_sequence(vin: TxInput[], sigflag: number, isAnyPay: boolean): Uint8Array;
|
|
@@ -1,24 +1,27 @@
|
|
|
1
|
-
import { Buff } from
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import
|
|
1
|
+
import { Buff } from "@vbyte/buff";
|
|
2
|
+
import { Assert } from "@vbyte/util";
|
|
3
|
+
import { hash160, hash256 } from "@vbyte/crypto/hash";
|
|
4
|
+
import * as CONST from "../../const.js";
|
|
5
|
+
import { ValidationError } from "../../error.js";
|
|
6
|
+
import { decode_script, prefix_script_size } from "../../lib/script/index.js";
|
|
7
|
+
import { encode_tx_locktime, encode_tx_version, encode_txin_sequence, encode_txin_txid, encode_txin_vout, encode_vout_value, parse_tx, } from "../../lib/tx/index.js";
|
|
8
|
+
import { parse_txinput } from "./util.js";
|
|
8
9
|
export function hash_segwit_tx(txdata, options = {}) {
|
|
9
10
|
const { sigflag = 0x01, txindex } = options;
|
|
10
11
|
const tx = parse_tx(txdata);
|
|
11
12
|
const is_anypay = (sigflag & 0x80) === 0x80;
|
|
12
13
|
const flag = sigflag % 0x80;
|
|
13
14
|
if (!CONST.SIGHASH_SEGWIT.includes(flag)) {
|
|
14
|
-
throw new
|
|
15
|
+
throw new ValidationError(`invalid sighash type: 0x${sigflag.toString(16)}. ` +
|
|
16
|
+
`Valid values: SIGHASH_ALL (0x01), SIGHASH_NONE (0x02), SIGHASH_SINGLE (0x03), ` +
|
|
17
|
+
`or combined with ANYONECANPAY (0x81, 0x82, 0x83)`);
|
|
15
18
|
}
|
|
16
19
|
const { version, vin, vout, locktime } = tx;
|
|
17
20
|
const txinput = parse_txinput(tx, options);
|
|
18
21
|
const { txid, vout: prevIdx, prevout, sequence } = txinput;
|
|
19
22
|
const { value } = prevout ?? {};
|
|
20
23
|
if (value === undefined) {
|
|
21
|
-
throw new
|
|
24
|
+
throw new ValidationError("Prevout value is required for segwit sighash calculation", "prevout.value");
|
|
22
25
|
}
|
|
23
26
|
let { pubkey, script } = options;
|
|
24
27
|
if (script === undefined && pubkey !== undefined) {
|
|
@@ -26,10 +29,10 @@ export function hash_segwit_tx(txdata, options = {}) {
|
|
|
26
29
|
script = `76a914${String(pkhash)}88ac`;
|
|
27
30
|
}
|
|
28
31
|
if (script === undefined) {
|
|
29
|
-
throw new
|
|
32
|
+
throw new ValidationError("Either pubkey or script must be provided for segwit sighash", "pubkey/script");
|
|
30
33
|
}
|
|
31
|
-
if (decode_script(script).includes(
|
|
32
|
-
throw new
|
|
34
|
+
if (decode_script(script).includes("OP_CODESEPARATOR")) {
|
|
35
|
+
throw new ValidationError("OP_CODESEPARATOR is not supported in segwit scripts", "script");
|
|
33
36
|
}
|
|
34
37
|
const sighash = [
|
|
35
38
|
encode_tx_version(version),
|
|
@@ -42,7 +45,7 @@ export function hash_segwit_tx(txdata, options = {}) {
|
|
|
42
45
|
encode_txin_sequence(sequence),
|
|
43
46
|
bip143_hash_outputs(vout, flag, txindex),
|
|
44
47
|
encode_tx_locktime(locktime),
|
|
45
|
-
Buff.num(sigflag, 4).reverse()
|
|
48
|
+
Buff.num(sigflag, 4).reverse(),
|
|
46
49
|
];
|
|
47
50
|
return hash256(Buff.join(sighash));
|
|
48
51
|
}
|
|
@@ -77,7 +80,8 @@ export function bip143_hash_outputs(vout, sigflag, idx) {
|
|
|
77
80
|
return hash256(Buff.join(stack));
|
|
78
81
|
}
|
|
79
82
|
if (sigflag === 0x03) {
|
|
80
|
-
Assert.ok(idx !== undefined);
|
|
83
|
+
Assert.ok(idx !== undefined, "txindex required for SIGHASH_SINGLE");
|
|
84
|
+
Assert.ok(idx >= 0, "txindex must be non-negative");
|
|
81
85
|
if (idx < vout.length) {
|
|
82
86
|
const { value, script_pk } = vout[idx];
|
|
83
87
|
stack.push(encode_vout_value(value));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Buff } from
|
|
2
|
-
import type { SigHashOptions, TxData, TxInput, TxOutput } from
|
|
1
|
+
import { Buff } from "@vbyte/buff";
|
|
2
|
+
import type { SigHashOptions, TxData, TxInput, TxOutput } from "../../types/index.js";
|
|
3
3
|
export declare function hash_taproot_tx(template: TxData | string, config?: SigHashOptions): Buff;
|
|
4
4
|
export declare function get_taproot_tx_preimage(template: TxData | string, config?: SigHashOptions): Buff;
|
|
5
5
|
export declare function bip341_hash_outpoints(vin: TxInput[]): Buff;
|