xpi-ts 0.2.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.
Files changed (216) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +516 -0
  3. package/dist/index.d.ts +9 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +8 -0
  6. package/dist/lib/bitcore/address.d.ts +66 -0
  7. package/dist/lib/bitcore/address.d.ts.map +1 -0
  8. package/dist/lib/bitcore/address.js +407 -0
  9. package/dist/lib/bitcore/block/block.d.ts +57 -0
  10. package/dist/lib/bitcore/block/block.d.ts.map +1 -0
  11. package/dist/lib/bitcore/block/block.js +233 -0
  12. package/dist/lib/bitcore/block/blockheader.d.ts +82 -0
  13. package/dist/lib/bitcore/block/blockheader.d.ts.map +1 -0
  14. package/dist/lib/bitcore/block/blockheader.js +323 -0
  15. package/dist/lib/bitcore/block/index.d.ts +5 -0
  16. package/dist/lib/bitcore/block/index.d.ts.map +1 -0
  17. package/dist/lib/bitcore/block/index.js +2 -0
  18. package/dist/lib/bitcore/chunk.d.ts +22 -0
  19. package/dist/lib/bitcore/chunk.d.ts.map +1 -0
  20. package/dist/lib/bitcore/chunk.js +46 -0
  21. package/dist/lib/bitcore/crypto/bn.d.ts +53 -0
  22. package/dist/lib/bitcore/crypto/bn.d.ts.map +1 -0
  23. package/dist/lib/bitcore/crypto/bn.js +238 -0
  24. package/dist/lib/bitcore/crypto/ecdsa.d.ts +46 -0
  25. package/dist/lib/bitcore/crypto/ecdsa.d.ts.map +1 -0
  26. package/dist/lib/bitcore/crypto/ecdsa.js +247 -0
  27. package/dist/lib/bitcore/crypto/hash.d.ts +16 -0
  28. package/dist/lib/bitcore/crypto/hash.d.ts.map +1 -0
  29. package/dist/lib/bitcore/crypto/hash.js +87 -0
  30. package/dist/lib/bitcore/crypto/index.d.ts +9 -0
  31. package/dist/lib/bitcore/crypto/index.d.ts.map +1 -0
  32. package/dist/lib/bitcore/crypto/index.js +8 -0
  33. package/dist/lib/bitcore/crypto/musig2.d.ts +40 -0
  34. package/dist/lib/bitcore/crypto/musig2.d.ts.map +1 -0
  35. package/dist/lib/bitcore/crypto/musig2.js +236 -0
  36. package/dist/lib/bitcore/crypto/point.d.ts +20 -0
  37. package/dist/lib/bitcore/crypto/point.d.ts.map +1 -0
  38. package/dist/lib/bitcore/crypto/point.js +133 -0
  39. package/dist/lib/bitcore/crypto/random.d.ts +7 -0
  40. package/dist/lib/bitcore/crypto/random.d.ts.map +1 -0
  41. package/dist/lib/bitcore/crypto/random.js +30 -0
  42. package/dist/lib/bitcore/crypto/schnorr.d.ts +40 -0
  43. package/dist/lib/bitcore/crypto/schnorr.d.ts.map +1 -0
  44. package/dist/lib/bitcore/crypto/schnorr.js +185 -0
  45. package/dist/lib/bitcore/crypto/signature.d.ts +53 -0
  46. package/dist/lib/bitcore/crypto/signature.d.ts.map +1 -0
  47. package/dist/lib/bitcore/crypto/signature.js +300 -0
  48. package/dist/lib/bitcore/crypto/sigtype.d.ts +5 -0
  49. package/dist/lib/bitcore/crypto/sigtype.d.ts.map +1 -0
  50. package/dist/lib/bitcore/crypto/sigtype.js +18 -0
  51. package/dist/lib/bitcore/encoding/base58.d.ts +16 -0
  52. package/dist/lib/bitcore/encoding/base58.d.ts.map +1 -0
  53. package/dist/lib/bitcore/encoding/base58.js +55 -0
  54. package/dist/lib/bitcore/encoding/base58check.d.ts +9 -0
  55. package/dist/lib/bitcore/encoding/base58check.d.ts.map +1 -0
  56. package/dist/lib/bitcore/encoding/base58check.js +82 -0
  57. package/dist/lib/bitcore/encoding/bufferreader.d.ts +34 -0
  58. package/dist/lib/bitcore/encoding/bufferreader.d.ts.map +1 -0
  59. package/dist/lib/bitcore/encoding/bufferreader.js +198 -0
  60. package/dist/lib/bitcore/encoding/bufferwriter.d.ts +36 -0
  61. package/dist/lib/bitcore/encoding/bufferwriter.d.ts.map +1 -0
  62. package/dist/lib/bitcore/encoding/bufferwriter.js +189 -0
  63. package/dist/lib/bitcore/encoding/varint.d.ts +20 -0
  64. package/dist/lib/bitcore/encoding/varint.d.ts.map +1 -0
  65. package/dist/lib/bitcore/encoding/varint.js +61 -0
  66. package/dist/lib/bitcore/errors.d.ts +28 -0
  67. package/dist/lib/bitcore/errors.d.ts.map +1 -0
  68. package/dist/lib/bitcore/errors.js +325 -0
  69. package/dist/lib/bitcore/hdprivatekey.d.ts +78 -0
  70. package/dist/lib/bitcore/hdprivatekey.d.ts.map +1 -0
  71. package/dist/lib/bitcore/hdprivatekey.js +381 -0
  72. package/dist/lib/bitcore/hdpublickey.d.ts +98 -0
  73. package/dist/lib/bitcore/hdpublickey.d.ts.map +1 -0
  74. package/dist/lib/bitcore/hdpublickey.js +416 -0
  75. package/dist/lib/bitcore/index.d.ts +60 -0
  76. package/dist/lib/bitcore/index.d.ts.map +1 -0
  77. package/dist/lib/bitcore/index.js +44 -0
  78. package/dist/lib/bitcore/message.d.ts +23 -0
  79. package/dist/lib/bitcore/message.d.ts.map +1 -0
  80. package/dist/lib/bitcore/message.js +112 -0
  81. package/dist/lib/bitcore/mnemonic/errors.d.ts +7 -0
  82. package/dist/lib/bitcore/mnemonic/errors.d.ts.map +1 -0
  83. package/dist/lib/bitcore/mnemonic/errors.js +20 -0
  84. package/dist/lib/bitcore/mnemonic/index.d.ts +5 -0
  85. package/dist/lib/bitcore/mnemonic/index.d.ts.map +1 -0
  86. package/dist/lib/bitcore/mnemonic/index.js +4 -0
  87. package/dist/lib/bitcore/mnemonic/mnemonic.d.ts +23 -0
  88. package/dist/lib/bitcore/mnemonic/mnemonic.d.ts.map +1 -0
  89. package/dist/lib/bitcore/mnemonic/mnemonic.js +164 -0
  90. package/dist/lib/bitcore/mnemonic/pbkdf2.d.ts +2 -0
  91. package/dist/lib/bitcore/mnemonic/pbkdf2.d.ts.map +1 -0
  92. package/dist/lib/bitcore/mnemonic/pbkdf2.js +25 -0
  93. package/dist/lib/bitcore/mnemonic/words/english.d.ts +2 -0
  94. package/dist/lib/bitcore/mnemonic/words/english.d.ts.map +1 -0
  95. package/dist/lib/bitcore/mnemonic/words/english.js +2050 -0
  96. package/dist/lib/bitcore/mnemonic/words/index.d.ts +4 -0
  97. package/dist/lib/bitcore/mnemonic/words/index.d.ts.map +1 -0
  98. package/dist/lib/bitcore/mnemonic/words/index.js +4 -0
  99. package/dist/lib/bitcore/musig2/index.d.ts +3 -0
  100. package/dist/lib/bitcore/musig2/index.d.ts.map +1 -0
  101. package/dist/lib/bitcore/musig2/index.js +2 -0
  102. package/dist/lib/bitcore/musig2/session.d.ts +79 -0
  103. package/dist/lib/bitcore/musig2/session.d.ts.map +1 -0
  104. package/dist/lib/bitcore/musig2/session.js +346 -0
  105. package/dist/lib/bitcore/musig2/signer.d.ts +61 -0
  106. package/dist/lib/bitcore/musig2/signer.d.ts.map +1 -0
  107. package/dist/lib/bitcore/musig2/signer.js +146 -0
  108. package/dist/lib/bitcore/networks.d.ts +53 -0
  109. package/dist/lib/bitcore/networks.d.ts.map +1 -0
  110. package/dist/lib/bitcore/networks.js +150 -0
  111. package/dist/lib/bitcore/opcode.d.ts +250 -0
  112. package/dist/lib/bitcore/opcode.d.ts.map +1 -0
  113. package/dist/lib/bitcore/opcode.js +270 -0
  114. package/dist/lib/bitcore/privatekey.d.ts +56 -0
  115. package/dist/lib/bitcore/privatekey.d.ts.map +1 -0
  116. package/dist/lib/bitcore/privatekey.js +237 -0
  117. package/dist/lib/bitcore/publickey.d.ts +59 -0
  118. package/dist/lib/bitcore/publickey.d.ts.map +1 -0
  119. package/dist/lib/bitcore/publickey.js +263 -0
  120. package/dist/lib/bitcore/script/interpreter.d.ts +98 -0
  121. package/dist/lib/bitcore/script/interpreter.d.ts.map +1 -0
  122. package/dist/lib/bitcore/script/interpreter.js +1704 -0
  123. package/dist/lib/bitcore/script.d.ts +111 -0
  124. package/dist/lib/bitcore/script.d.ts.map +1 -0
  125. package/dist/lib/bitcore/script.js +1112 -0
  126. package/dist/lib/bitcore/taproot/musig2.d.ts +29 -0
  127. package/dist/lib/bitcore/taproot/musig2.d.ts.map +1 -0
  128. package/dist/lib/bitcore/taproot/musig2.js +104 -0
  129. package/dist/lib/bitcore/taproot/nft.d.ts +164 -0
  130. package/dist/lib/bitcore/taproot/nft.d.ts.map +1 -0
  131. package/dist/lib/bitcore/taproot/nft.js +407 -0
  132. package/dist/lib/bitcore/taproot.d.ts +65 -0
  133. package/dist/lib/bitcore/taproot.d.ts.map +1 -0
  134. package/dist/lib/bitcore/taproot.js +288 -0
  135. package/dist/lib/bitcore/transaction/index.d.ts +12 -0
  136. package/dist/lib/bitcore/transaction/index.d.ts.map +1 -0
  137. package/dist/lib/bitcore/transaction/index.js +6 -0
  138. package/dist/lib/bitcore/transaction/input.d.ts +202 -0
  139. package/dist/lib/bitcore/transaction/input.d.ts.map +1 -0
  140. package/dist/lib/bitcore/transaction/input.js +911 -0
  141. package/dist/lib/bitcore/transaction/output.d.ts +48 -0
  142. package/dist/lib/bitcore/transaction/output.d.ts.map +1 -0
  143. package/dist/lib/bitcore/transaction/output.js +231 -0
  144. package/dist/lib/bitcore/transaction/sighash.d.ts +32 -0
  145. package/dist/lib/bitcore/transaction/sighash.d.ts.map +1 -0
  146. package/dist/lib/bitcore/transaction/sighash.js +335 -0
  147. package/dist/lib/bitcore/transaction/signature.d.ts +36 -0
  148. package/dist/lib/bitcore/transaction/signature.d.ts.map +1 -0
  149. package/dist/lib/bitcore/transaction/signature.js +130 -0
  150. package/dist/lib/bitcore/transaction/transaction.d.ts +164 -0
  151. package/dist/lib/bitcore/transaction/transaction.d.ts.map +1 -0
  152. package/dist/lib/bitcore/transaction/transaction.js +1016 -0
  153. package/dist/lib/bitcore/transaction/unspentoutput.d.ts +58 -0
  154. package/dist/lib/bitcore/transaction/unspentoutput.d.ts.map +1 -0
  155. package/dist/lib/bitcore/transaction/unspentoutput.js +167 -0
  156. package/dist/lib/bitcore/unit.d.ts +44 -0
  157. package/dist/lib/bitcore/unit.d.ts.map +1 -0
  158. package/dist/lib/bitcore/unit.js +106 -0
  159. package/dist/lib/bitcore/uri.d.ts +29 -0
  160. package/dist/lib/bitcore/uri.d.ts.map +1 -0
  161. package/dist/lib/bitcore/uri.js +163 -0
  162. package/dist/lib/bitcore/util/base32.d.ts +5 -0
  163. package/dist/lib/bitcore/util/base32.d.ts.map +1 -0
  164. package/dist/lib/bitcore/util/base32.js +58 -0
  165. package/dist/lib/bitcore/util/buffer.d.ts +18 -0
  166. package/dist/lib/bitcore/util/buffer.d.ts.map +1 -0
  167. package/dist/lib/bitcore/util/buffer.js +76 -0
  168. package/dist/lib/bitcore/util/convertBits.d.ts +2 -0
  169. package/dist/lib/bitcore/util/convertBits.d.ts.map +1 -0
  170. package/dist/lib/bitcore/util/convertBits.js +26 -0
  171. package/dist/lib/bitcore/util/js.d.ts +9 -0
  172. package/dist/lib/bitcore/util/js.d.ts.map +1 -0
  173. package/dist/lib/bitcore/util/js.js +45 -0
  174. package/dist/lib/bitcore/util/preconditions.d.ts +6 -0
  175. package/dist/lib/bitcore/util/preconditions.d.ts.map +1 -0
  176. package/dist/lib/bitcore/util/preconditions.js +31 -0
  177. package/dist/lib/bitcore/util.d.ts +14 -0
  178. package/dist/lib/bitcore/util.d.ts.map +1 -0
  179. package/dist/lib/bitcore/util.js +13 -0
  180. package/dist/lib/bitcore/xaddress.d.ts +45 -0
  181. package/dist/lib/bitcore/xaddress.d.ts.map +1 -0
  182. package/dist/lib/bitcore/xaddress.js +279 -0
  183. package/dist/lib/rank/api.d.ts +75 -0
  184. package/dist/lib/rank/api.d.ts.map +1 -0
  185. package/dist/lib/rank/api.js +4 -0
  186. package/dist/lib/rank/index.d.ts +127 -0
  187. package/dist/lib/rank/index.d.ts.map +1 -0
  188. package/dist/lib/rank/index.js +421 -0
  189. package/dist/lib/rank/opcode.d.ts +23 -0
  190. package/dist/lib/rank/opcode.d.ts.map +1 -0
  191. package/dist/lib/rank/opcode.js +23 -0
  192. package/dist/lib/rank/script.d.ts +2 -0
  193. package/dist/lib/rank/script.d.ts.map +1 -0
  194. package/dist/lib/rank/script.js +7 -0
  195. package/dist/lib/rank/transaction.d.ts +3 -0
  196. package/dist/lib/rank/transaction.d.ts.map +1 -0
  197. package/dist/lib/rank/transaction.js +12 -0
  198. package/dist/lib/rpc.d.ts +136 -0
  199. package/dist/lib/rpc.d.ts.map +1 -0
  200. package/dist/lib/rpc.js +62 -0
  201. package/dist/utils/constants.d.ts +18 -0
  202. package/dist/utils/constants.d.ts.map +1 -0
  203. package/dist/utils/constants.js +20 -0
  204. package/dist/utils/env.d.ts +3 -0
  205. package/dist/utils/env.d.ts.map +1 -0
  206. package/dist/utils/env.js +8 -0
  207. package/dist/utils/string.d.ts +11 -0
  208. package/dist/utils/string.d.ts.map +1 -0
  209. package/dist/utils/string.js +47 -0
  210. package/dist/utils/types.d.ts +2 -0
  211. package/dist/utils/types.d.ts.map +1 -0
  212. package/dist/utils/types.js +1 -0
  213. package/dist/utils/wallet.d.ts +12 -0
  214. package/dist/utils/wallet.d.ts.map +1 -0
  215. package/dist/utils/wallet.js +28 -0
  216. package/package.json +91 -0
@@ -0,0 +1,1704 @@
1
+ import { Script } from '../script.js';
2
+ import { Opcode } from '../opcode.js';
3
+ import { BN } from '../crypto/bn.js';
4
+ import { Hash } from '../crypto/hash.js';
5
+ import { Signature } from '../crypto/signature.js';
6
+ import { PublicKey } from '../publickey.js';
7
+ import { ECDSA } from '../crypto/ecdsa.js';
8
+ import { Schnorr } from '../crypto/schnorr.js';
9
+ import { Preconditions } from '../util/preconditions.js';
10
+ import { TAPROOT_INTRO_SIZE, TAPROOT_SIZE_WITHOUT_STATE, TAPROOT_SCRIPTTYPE, verifyTaprootSpend, } from '../taproot.js';
11
+ export class Interpreter {
12
+ static SCRIPT_VERIFY_NONE = 0;
13
+ static SCRIPT_VERIFY_P2SH = 1 << 0;
14
+ static SCRIPT_VERIFY_STRICTENC = 1 << 1;
15
+ static SCRIPT_VERIFY_DERSIG = 1 << 2;
16
+ static SCRIPT_VERIFY_LOW_S = 1 << 3;
17
+ static SCRIPT_VERIFY_NULLDUMMY = 1 << 4;
18
+ static SCRIPT_VERIFY_SIGPUSHONLY = 1 << 5;
19
+ static SCRIPT_VERIFY_MINIMALDATA = 1 << 6;
20
+ static SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS = 1 << 7;
21
+ static SCRIPT_VERIFY_CLEANSTACK = 1 << 8;
22
+ static SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY = 1 << 9;
23
+ static SCRIPT_VERIFY_CHECKSEQUENCEVERIFY = 1 << 10;
24
+ static SCRIPT_VERIFY_MINIMALIF = 1 << 13;
25
+ static SCRIPT_VERIFY_NULLFAIL = 1 << 14;
26
+ static SCRIPT_VERIFY_COMPRESSED_PUBKEYTYPE = 1 << 15;
27
+ static SCRIPT_ENABLE_SIGHASH_FORKID = 1 << 16;
28
+ static SCRIPT_ENABLE_REPLAY_PROTECTION = 1 << 17;
29
+ static SCRIPT_ENABLE_CHECKDATASIG = 1 << 18;
30
+ static SCRIPT_DISALLOW_SEGWIT_RECOVERY = 1 << 20;
31
+ static SCRIPT_ENABLE_SCHNORR_MULTISIG = 1 << 21;
32
+ static SCRIPT_VERIFY_INPUT_SIGCHECKS = 1 << 22;
33
+ static SCRIPT_TAPROOT_KEY_SPEND_PATH = 1 << 23;
34
+ static SCRIPT_DISABLE_TAPROOT_SIGHASH_LOTUS = 1 << 24;
35
+ static MAX_SCRIPT_ELEMENT_SIZE = 520;
36
+ static MAX_SCRIPT_SIZE = 10000;
37
+ static MAX_STACK_SIZE = 1000;
38
+ static MAX_OPCODE_COUNT = 201;
39
+ static false = Buffer.from([0]);
40
+ static true = Buffer.from([1]);
41
+ static MAXIMUM_ELEMENT_SIZE = 4;
42
+ static LOCKTIME_THRESHOLD = 500000000;
43
+ static LOCKTIME_THRESHOLD_BN = new BN(500000000);
44
+ static SEQUENCE_LOCKTIME_DISABLE_FLAG = 1 << 31;
45
+ static SEQUENCE_LOCKTIME_TYPE_FLAG = 1 << 22;
46
+ static SEQUENCE_LOCKTIME_MASK = 0x0000ffff;
47
+ script;
48
+ tx;
49
+ nin;
50
+ flags;
51
+ satoshisBN;
52
+ outputScript;
53
+ stack = [];
54
+ altstack = [];
55
+ pc = 0;
56
+ pbegincodehash = 0;
57
+ nOpCount = 0;
58
+ vfExec = [];
59
+ errstr = '';
60
+ constructor(obj) {
61
+ this.initialize();
62
+ if (obj) {
63
+ this.set(obj);
64
+ }
65
+ }
66
+ static create(obj) {
67
+ return new Interpreter(obj);
68
+ }
69
+ initialize() {
70
+ this.stack = [];
71
+ this.altstack = [];
72
+ this.pc = 0;
73
+ this.pbegincodehash = 0;
74
+ this.nOpCount = 0;
75
+ this.vfExec = [];
76
+ this.errstr = '';
77
+ this.flags = Interpreter.SCRIPT_VERIFY_NONE;
78
+ }
79
+ set(obj) {
80
+ this.script = obj.script || this.script;
81
+ this.tx = obj.tx || this.tx;
82
+ this.nin = obj.nin !== undefined ? obj.nin : this.nin;
83
+ this.flags = obj.flags !== undefined ? obj.flags : this.flags;
84
+ this.satoshisBN = obj.satoshisBN || this.satoshisBN;
85
+ this.outputScript = obj.outputScript || this.outputScript;
86
+ this.stack = obj.stack || this.stack;
87
+ return this;
88
+ }
89
+ verify(scriptSig, scriptPubkey, tx, nin, flags, satoshisBN) {
90
+ Preconditions.checkArgument(scriptSig instanceof Script, 'scriptSig', 'Must be a Script');
91
+ Preconditions.checkArgument(scriptPubkey instanceof Script, 'scriptPubkey', 'Must be a Script');
92
+ if (flags && (flags & Interpreter.SCRIPT_ENABLE_SIGHASH_FORKID) !== 0) {
93
+ flags |= Interpreter.SCRIPT_VERIFY_STRICTENC;
94
+ if (!satoshisBN) {
95
+ throw new Error('internal error - need satoshisBN to verify FORKID transactions');
96
+ }
97
+ }
98
+ this.set({
99
+ script: scriptSig,
100
+ tx: tx,
101
+ nin: nin,
102
+ flags: flags,
103
+ satoshisBN: satoshisBN,
104
+ });
105
+ let stackCopy = [];
106
+ if ((this.flags & Interpreter.SCRIPT_VERIFY_SIGPUSHONLY) !== 0) {
107
+ if (!scriptSig.isPushOnly()) {
108
+ this.errstr = 'SCRIPT_ERR_SIG_PUSHONLY';
109
+ return false;
110
+ }
111
+ }
112
+ if (!this.evaluate()) {
113
+ return false;
114
+ }
115
+ if (this.flags & Interpreter.SCRIPT_VERIFY_P2SH) {
116
+ stackCopy = this.stack.slice();
117
+ }
118
+ const stack = this.stack;
119
+ this.initialize();
120
+ this.script = scriptPubkey;
121
+ this.stack = stack;
122
+ this.tx = tx;
123
+ this.nin = nin;
124
+ this.flags = flags || Interpreter.SCRIPT_VERIFY_NONE;
125
+ this.satoshisBN = satoshisBN;
126
+ const scriptPubkeyBuf = scriptPubkey.toBuffer();
127
+ if (scriptPubkeyBuf.length > 0 &&
128
+ scriptPubkeyBuf[0] === Opcode.OP_SCRIPTTYPE) {
129
+ if (!this._verifyScriptType(scriptPubkey)) {
130
+ return false;
131
+ }
132
+ return true;
133
+ }
134
+ if (!this.evaluate()) {
135
+ return false;
136
+ }
137
+ if (this.stack.length === 0) {
138
+ this.errstr = 'SCRIPT_ERR_EVAL_FALSE_NO_RESULT';
139
+ return false;
140
+ }
141
+ const buf = this.stack[this.stack.length - 1];
142
+ if (!Interpreter.castToBool(buf)) {
143
+ this.errstr = 'SCRIPT_ERR_EVAL_FALSE_IN_STACK';
144
+ return false;
145
+ }
146
+ if (this.flags & Interpreter.SCRIPT_VERIFY_P2SH &&
147
+ scriptPubkey.isScriptHashOut()) {
148
+ if (!scriptSig.isPushOnly()) {
149
+ this.errstr = 'SCRIPT_ERR_SIG_PUSHONLY';
150
+ return false;
151
+ }
152
+ if (stackCopy.length === 0) {
153
+ throw new Error('internal error - stack copy empty');
154
+ }
155
+ const redeemScriptSerialized = stackCopy[stackCopy.length - 1];
156
+ const redeemScript = Script.fromBuffer(redeemScriptSerialized);
157
+ stackCopy.pop();
158
+ this.initialize();
159
+ this.script = redeemScript;
160
+ this.stack = stackCopy;
161
+ this.tx = tx;
162
+ this.nin = nin;
163
+ this.flags = flags || Interpreter.SCRIPT_VERIFY_NONE;
164
+ this.satoshisBN = satoshisBN;
165
+ if (!this.evaluate()) {
166
+ return false;
167
+ }
168
+ if (stackCopy.length === 0) {
169
+ this.errstr = 'SCRIPT_ERR_EVAL_FALSE_NO_P2SH_STACK';
170
+ return false;
171
+ }
172
+ if (!Interpreter.castToBool(stackCopy[stackCopy.length - 1])) {
173
+ this.errstr = 'SCRIPT_ERR_EVAL_FALSE_IN_P2SH_STACK';
174
+ return false;
175
+ }
176
+ }
177
+ if ((this.flags & Interpreter.SCRIPT_VERIFY_CLEANSTACK) != 0) {
178
+ if ((this.flags & Interpreter.SCRIPT_VERIFY_P2SH) == 0) {
179
+ throw new Error('internal error - CLEANSTACK without P2SH');
180
+ }
181
+ if (stackCopy.length != 1) {
182
+ this.errstr = 'SCRIPT_ERR_CLEANSTACK';
183
+ return false;
184
+ }
185
+ }
186
+ return true;
187
+ }
188
+ checkRawSignatureEncoding(buf) {
189
+ if (buf.length === 0) {
190
+ return true;
191
+ }
192
+ if (Interpreter.isSchnorrSig(buf)) {
193
+ return true;
194
+ }
195
+ if ((this.flags &
196
+ (Interpreter.SCRIPT_VERIFY_DERSIG |
197
+ Interpreter.SCRIPT_VERIFY_LOW_S |
198
+ Interpreter.SCRIPT_VERIFY_STRICTENC)) !==
199
+ 0 &&
200
+ !Signature.isDER(buf)) {
201
+ this.errstr = 'SCRIPT_ERR_SIG_DER_INVALID_FORMAT';
202
+ return false;
203
+ }
204
+ else if ((this.flags & Interpreter.SCRIPT_VERIFY_LOW_S) !== 0) {
205
+ const sig = Signature.fromDER(buf, false);
206
+ if (!sig.hasLowS()) {
207
+ this.errstr = 'SCRIPT_ERR_SIG_DER_HIGH_S';
208
+ return false;
209
+ }
210
+ }
211
+ return true;
212
+ }
213
+ checkSignatureEncoding(buf) {
214
+ if (buf.length === 0) {
215
+ return true;
216
+ }
217
+ try {
218
+ const sig = Signature.fromDER(buf);
219
+ if ((this.flags & Interpreter.SCRIPT_VERIFY_LOW_S) !== 0) {
220
+ if (sig.s >
221
+ new BN('7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0', 16)) {
222
+ this.errstr = 'SCRIPT_ERR_SIG_DER_HIGH_S';
223
+ return false;
224
+ }
225
+ }
226
+ const hashType = buf[buf.length - 1];
227
+ if (hashType < 0x80 || hashType > 0x84) {
228
+ this.errstr = 'SCRIPT_ERR_SIG_HASHTYPE';
229
+ return false;
230
+ }
231
+ if ((this.flags & Interpreter.SCRIPT_ENABLE_SIGHASH_FORKID) !== 0) {
232
+ if ((hashType & 0x40) === 0) {
233
+ this.errstr = 'SCRIPT_ERR_ILLEGAL_FORKID';
234
+ return false;
235
+ }
236
+ }
237
+ else {
238
+ if ((hashType & 0x40) !== 0) {
239
+ this.errstr = 'SCRIPT_ERR_MUST_USE_FORKID';
240
+ return false;
241
+ }
242
+ }
243
+ return true;
244
+ }
245
+ catch (e) {
246
+ this.errstr = 'SCRIPT_ERR_SIG_DER_INVALID_FORMAT';
247
+ return false;
248
+ }
249
+ }
250
+ checkTxSignatureEncoding(buf) {
251
+ if (buf.length === 0) {
252
+ return true;
253
+ }
254
+ if (!this.checkRawSignatureEncoding(buf.subarray(0, buf.length - 1))) {
255
+ return false;
256
+ }
257
+ if ((this.flags & Interpreter.SCRIPT_VERIFY_STRICTENC) !== 0) {
258
+ const sig = Signature.fromTxFormat(buf);
259
+ if (!sig.hasDefinedHashtype()) {
260
+ this.errstr = 'SCRIPT_ERR_SIG_HASHTYPE';
261
+ return false;
262
+ }
263
+ const isTaprootKeyPath = (this.flags & Interpreter.SCRIPT_TAPROOT_KEY_SPEND_PATH) !== 0;
264
+ if (!isTaprootKeyPath) {
265
+ if (!(this.flags & Interpreter.SCRIPT_ENABLE_SIGHASH_FORKID) &&
266
+ sig.nhashtype & Signature.SIGHASH_FORKID) {
267
+ this.errstr = 'SCRIPT_ERR_ILLEGAL_FORKID';
268
+ return false;
269
+ }
270
+ if (this.flags & Interpreter.SCRIPT_ENABLE_SIGHASH_FORKID &&
271
+ !(sig.nhashtype & Signature.SIGHASH_FORKID)) {
272
+ this.errstr = 'SCRIPT_ERR_MUST_USE_FORKID';
273
+ return false;
274
+ }
275
+ }
276
+ }
277
+ return true;
278
+ }
279
+ checkDataSignatureEncoding(buf) {
280
+ if (buf.length === 0) {
281
+ return true;
282
+ }
283
+ return this.checkRawSignatureEncoding(buf);
284
+ }
285
+ checkPubkeyEncoding(buf) {
286
+ if ((this.flags & Interpreter.SCRIPT_VERIFY_STRICTENC) !== 0) {
287
+ if (!PublicKey.isValid(buf) &&
288
+ !this.isCompressedOrUncompressedPubkey(buf)) {
289
+ this.errstr = 'SCRIPT_ERR_PUBKEYTYPE';
290
+ return false;
291
+ }
292
+ }
293
+ return true;
294
+ }
295
+ isCompressedOrUncompressedPubkey(buf) {
296
+ if (buf.length === 33) {
297
+ return buf[0] === 0x02 || buf[0] === 0x03;
298
+ }
299
+ if (buf.length === 65) {
300
+ return buf[0] === 0x04;
301
+ }
302
+ return false;
303
+ }
304
+ evaluate() {
305
+ if (this.script.toBuffer().length > Interpreter.MAX_SCRIPT_SIZE) {
306
+ this.errstr = 'SCRIPT_ERR_SCRIPT_SIZE';
307
+ return false;
308
+ }
309
+ try {
310
+ while (this.pc < this.script.chunks.length) {
311
+ if (this.stack.length > Interpreter.MAX_STACK_SIZE) {
312
+ this.errstr = 'SCRIPT_ERR_STACK_SIZE';
313
+ return false;
314
+ }
315
+ if (!this.step()) {
316
+ return false;
317
+ }
318
+ }
319
+ if (this.stack.length + this.altstack.length >
320
+ Interpreter.MAX_STACK_SIZE) {
321
+ this.errstr = 'SCRIPT_ERR_STACK_SIZE';
322
+ return false;
323
+ }
324
+ if (this.vfExec.length > 0) {
325
+ this.errstr = 'SCRIPT_ERR_UNBALANCED_CONDITIONAL';
326
+ return false;
327
+ }
328
+ return true;
329
+ }
330
+ catch (e) {
331
+ this.errstr = 'SCRIPT_ERR_UNKNOWN_ERROR: ' + e.message;
332
+ return false;
333
+ }
334
+ }
335
+ toScriptNumBuffer(value) {
336
+ const num = typeof value === 'bigint' ? value : BigInt(value);
337
+ if (num === 0n) {
338
+ return Buffer.alloc(0);
339
+ }
340
+ const isNegative = num < 0n;
341
+ const absNum = isNegative ? -num : num;
342
+ const bytes = [];
343
+ let temp = absNum;
344
+ while (temp > 0n) {
345
+ bytes.push(Number(temp & 0xffn));
346
+ temp >>= 8n;
347
+ }
348
+ if (isNegative) {
349
+ if (bytes.length > 0 && (bytes[bytes.length - 1] & 0x80) !== 0) {
350
+ bytes.push(0x80);
351
+ }
352
+ else if (bytes.length > 0) {
353
+ bytes[bytes.length - 1] |= 0x80;
354
+ }
355
+ else {
356
+ bytes.push(0x80);
357
+ }
358
+ }
359
+ return Buffer.from(bytes);
360
+ }
361
+ fromScriptNumBuffer(buf) {
362
+ if (buf.length === 0) {
363
+ return 0n;
364
+ }
365
+ let result = 0n;
366
+ for (let i = 0; i < buf.length; i++) {
367
+ result |= BigInt(buf[i]) << BigInt(i * 8);
368
+ }
369
+ if (buf.length > 0 && (buf[buf.length - 1] & 0x80) !== 0) {
370
+ const lastByte = buf[buf.length - 1] & 0x7f;
371
+ result =
372
+ (result & ~(0xffn << BigInt((buf.length - 1) * 8))) |
373
+ (BigInt(lastByte) << BigInt((buf.length - 1) * 8));
374
+ result = -result;
375
+ }
376
+ return result;
377
+ }
378
+ castToBool(buf) {
379
+ for (let i = 0; i < buf.length; i++) {
380
+ if (buf[i] !== 0) {
381
+ if (i === buf.length - 1 && buf[i] === 0x80) {
382
+ return false;
383
+ }
384
+ return true;
385
+ }
386
+ }
387
+ return false;
388
+ }
389
+ step() {
390
+ if (this.pc >= this.script.chunks.length) {
391
+ return true;
392
+ }
393
+ const chunk = this.script.chunks[this.pc];
394
+ this.pc++;
395
+ const opcodenum = chunk.opcodenum;
396
+ if (opcodenum === undefined) {
397
+ this.errstr = 'SCRIPT_ERR_UNDEFINED_OPCODE';
398
+ return false;
399
+ }
400
+ if (chunk.buf && chunk.buf.length > Interpreter.MAX_SCRIPT_ELEMENT_SIZE) {
401
+ this.errstr = 'SCRIPT_ERR_PUSH_SIZE';
402
+ return false;
403
+ }
404
+ if (opcodenum > Opcode.OP_16 &&
405
+ ++this.nOpCount > Interpreter.MAX_OPCODE_COUNT) {
406
+ this.errstr = 'SCRIPT_ERR_OP_COUNT';
407
+ return false;
408
+ }
409
+ if (this.isOpcodeDisabled(opcodenum)) {
410
+ this.errstr = 'SCRIPT_ERR_DISABLED_OPCODE';
411
+ return false;
412
+ }
413
+ const fRequireMinimal = (this.flags & Interpreter.SCRIPT_VERIFY_MINIMALDATA) !== 0;
414
+ const fExec = this.vfExec.indexOf(false) === -1;
415
+ if (fExec && opcodenum >= 0 && opcodenum <= Opcode.OP_PUSHDATA4) {
416
+ if (fRequireMinimal && !this.script.checkMinimalPush(this.pc - 1)) {
417
+ this.errstr = 'SCRIPT_ERR_MINIMALDATA';
418
+ return false;
419
+ }
420
+ if (!chunk.buf) {
421
+ this.stack.push(Interpreter.false);
422
+ }
423
+ else if (chunk.len !== chunk.buf.length) {
424
+ throw new Error('Length of push value not equal to length of data');
425
+ }
426
+ else {
427
+ this.stack.push(chunk.buf);
428
+ }
429
+ }
430
+ else if (fExec ||
431
+ (Opcode.OP_IF <= opcodenum && opcodenum <= Opcode.OP_ENDIF)) {
432
+ switch (opcodenum) {
433
+ case Opcode.OP_1NEGATE: {
434
+ this.stack.push(this.toScriptNumBuffer(-1));
435
+ break;
436
+ }
437
+ case Opcode.OP_1:
438
+ case Opcode.OP_2:
439
+ case Opcode.OP_3:
440
+ case Opcode.OP_4:
441
+ case Opcode.OP_5:
442
+ case Opcode.OP_6:
443
+ case Opcode.OP_7:
444
+ case Opcode.OP_8:
445
+ case Opcode.OP_9:
446
+ case Opcode.OP_10:
447
+ case Opcode.OP_11:
448
+ case Opcode.OP_12:
449
+ case Opcode.OP_13:
450
+ case Opcode.OP_14:
451
+ case Opcode.OP_15:
452
+ case Opcode.OP_16: {
453
+ const value = opcodenum - Opcode.OP_1 + 1;
454
+ this.stack.push(this.toScriptNumBuffer(value));
455
+ break;
456
+ }
457
+ case Opcode.OP_NOP:
458
+ case Opcode.OP_NOP1:
459
+ case Opcode.OP_NOP4:
460
+ case Opcode.OP_NOP5:
461
+ case Opcode.OP_NOP6:
462
+ case Opcode.OP_NOP7:
463
+ case Opcode.OP_NOP8:
464
+ case Opcode.OP_NOP9:
465
+ case Opcode.OP_NOP10: {
466
+ if (this.flags & Interpreter.SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) {
467
+ this.errstr = 'SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS';
468
+ return false;
469
+ }
470
+ break;
471
+ }
472
+ case Opcode.OP_NOP2:
473
+ case Opcode.OP_CHECKLOCKTIMEVERIFY: {
474
+ if (!(this.flags & Interpreter.SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY)) {
475
+ if (this.flags & Interpreter.SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) {
476
+ this.errstr = 'SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS';
477
+ return false;
478
+ }
479
+ break;
480
+ }
481
+ if (this.stack.length < 1) {
482
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
483
+ return false;
484
+ }
485
+ const fRequireMinimal = (this.flags & Interpreter.SCRIPT_VERIFY_MINIMALDATA) !== 0;
486
+ const nLockTime = BN.fromScriptNumBuffer(this.stack[this.stack.length - 1], fRequireMinimal, 5);
487
+ if (nLockTime.lt(new BN(0))) {
488
+ this.errstr = 'SCRIPT_ERR_NEGATIVE_LOCKTIME';
489
+ return false;
490
+ }
491
+ if (!this.checkLockTime(nLockTime)) {
492
+ this.errstr = 'SCRIPT_ERR_UNSATISFIED_LOCKTIME';
493
+ return false;
494
+ }
495
+ break;
496
+ }
497
+ case Opcode.OP_NOP3:
498
+ case Opcode.OP_CHECKSEQUENCEVERIFY: {
499
+ if (!(this.flags & Interpreter.SCRIPT_VERIFY_CHECKSEQUENCEVERIFY)) {
500
+ if (this.flags & Interpreter.SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) {
501
+ this.errstr = 'SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS';
502
+ return false;
503
+ }
504
+ break;
505
+ }
506
+ if (this.stack.length < 1) {
507
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
508
+ return false;
509
+ }
510
+ const fRequireMinimal = (this.flags & Interpreter.SCRIPT_VERIFY_MINIMALDATA) !== 0;
511
+ const nSequence = BN.fromScriptNumBuffer(this.stacktop(-1), fRequireMinimal, 5);
512
+ if (nSequence.lt(new BN(0))) {
513
+ this.errstr = 'SCRIPT_ERR_NEGATIVE_LOCKTIME';
514
+ return false;
515
+ }
516
+ if (!nSequence.and(Interpreter.SEQUENCE_LOCKTIME_DISABLE_FLAG).isZero()) {
517
+ break;
518
+ }
519
+ if (!this.checkSequence(nSequence)) {
520
+ this.errstr = 'SCRIPT_ERR_UNSATISFIED_LOCKTIME';
521
+ return false;
522
+ }
523
+ break;
524
+ }
525
+ case Opcode.OP_IF:
526
+ case Opcode.OP_NOTIF: {
527
+ let fValue = false;
528
+ if (fExec) {
529
+ if (this.stack.length < 1) {
530
+ this.errstr = 'SCRIPT_ERR_UNBALANCED_CONDITIONAL';
531
+ return false;
532
+ }
533
+ const buf = this.stacktop(-1);
534
+ if (this.flags & Interpreter.SCRIPT_VERIFY_MINIMALIF) {
535
+ if (buf.length > 1) {
536
+ this.errstr = 'SCRIPT_ERR_MINIMALIF';
537
+ return false;
538
+ }
539
+ if (buf.length == 1 && buf[0] != 1) {
540
+ this.errstr = 'SCRIPT_ERR_MINIMALIF';
541
+ return false;
542
+ }
543
+ }
544
+ fValue = Interpreter.castToBool(buf);
545
+ if (opcodenum === Opcode.OP_NOTIF) {
546
+ fValue = !fValue;
547
+ }
548
+ this.stack.pop();
549
+ }
550
+ this.vfExec.push(fValue);
551
+ break;
552
+ }
553
+ case Opcode.OP_ELSE: {
554
+ if (this.vfExec.length === 0) {
555
+ this.errstr = 'SCRIPT_ERR_UNBALANCED_CONDITIONAL';
556
+ return false;
557
+ }
558
+ this.vfExec[this.vfExec.length - 1] =
559
+ !this.vfExec[this.vfExec.length - 1];
560
+ break;
561
+ }
562
+ case Opcode.OP_ENDIF: {
563
+ if (this.vfExec.length === 0) {
564
+ this.errstr = 'SCRIPT_ERR_UNBALANCED_CONDITIONAL';
565
+ return false;
566
+ }
567
+ this.vfExec.pop();
568
+ break;
569
+ }
570
+ case Opcode.OP_VERIFY: {
571
+ if (this.stack.length < 1) {
572
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
573
+ return false;
574
+ }
575
+ const buf = this.stacktop(-1);
576
+ const fValue = Interpreter.castToBool(buf);
577
+ if (fValue) {
578
+ this.stack.pop();
579
+ }
580
+ else {
581
+ this.errstr = 'SCRIPT_ERR_VERIFY';
582
+ return false;
583
+ }
584
+ break;
585
+ }
586
+ case Opcode.OP_RETURN:
587
+ this.errstr = 'SCRIPT_ERR_OP_RETURN';
588
+ return false;
589
+ case Opcode.OP_TOALTSTACK: {
590
+ if (this.stack.length < 1) {
591
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
592
+ return false;
593
+ }
594
+ this.altstack.push(this.stack.pop());
595
+ break;
596
+ }
597
+ case Opcode.OP_FROMALTSTACK: {
598
+ if (this.altstack.length < 1) {
599
+ this.errstr = 'SCRIPT_ERR_INVALID_ALTSTACK_OPERATION';
600
+ return false;
601
+ }
602
+ this.stack.push(this.altstack.pop());
603
+ break;
604
+ }
605
+ case Opcode.OP_2DROP: {
606
+ if (this.stack.length < 2) {
607
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
608
+ return false;
609
+ }
610
+ this.stack.pop();
611
+ this.stack.pop();
612
+ break;
613
+ }
614
+ case Opcode.OP_2DUP: {
615
+ if (this.stack.length < 2) {
616
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
617
+ return false;
618
+ }
619
+ const x1 = this.stack[this.stack.length - 2];
620
+ const x2 = this.stack[this.stack.length - 1];
621
+ this.stack.push(x1);
622
+ this.stack.push(x2);
623
+ break;
624
+ }
625
+ case Opcode.OP_3DUP: {
626
+ if (this.stack.length < 3) {
627
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
628
+ return false;
629
+ }
630
+ const x1 = this.stack[this.stack.length - 3];
631
+ const x2 = this.stack[this.stack.length - 2];
632
+ const x3 = this.stack[this.stack.length - 1];
633
+ this.stack.push(x1);
634
+ this.stack.push(x2);
635
+ this.stack.push(x3);
636
+ break;
637
+ }
638
+ case Opcode.OP_2OVER: {
639
+ if (this.stack.length < 4) {
640
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
641
+ return false;
642
+ }
643
+ const x1 = this.stack[this.stack.length - 4];
644
+ const x2 = this.stack[this.stack.length - 3];
645
+ this.stack.push(x1);
646
+ this.stack.push(x2);
647
+ break;
648
+ }
649
+ case Opcode.OP_2ROT: {
650
+ if (this.stack.length < 6) {
651
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
652
+ return false;
653
+ }
654
+ const x1 = this.stack.splice(this.stack.length - 6, 1)[0];
655
+ const x2 = this.stack.splice(this.stack.length - 5, 1)[0];
656
+ this.stack.push(x1);
657
+ this.stack.push(x2);
658
+ break;
659
+ }
660
+ case Opcode.OP_2SWAP: {
661
+ if (this.stack.length < 4) {
662
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
663
+ return false;
664
+ }
665
+ const x1 = this.stack[this.stack.length - 4];
666
+ const x2 = this.stack[this.stack.length - 3];
667
+ const x3 = this.stack[this.stack.length - 2];
668
+ const x4 = this.stack[this.stack.length - 1];
669
+ this.stack[this.stack.length - 4] = x3;
670
+ this.stack[this.stack.length - 3] = x4;
671
+ this.stack[this.stack.length - 2] = x1;
672
+ this.stack[this.stack.length - 1] = x2;
673
+ break;
674
+ }
675
+ case Opcode.OP_DEPTH: {
676
+ this.stack.push(this.toScriptNumBuffer(this.stack.length));
677
+ break;
678
+ }
679
+ case Opcode.OP_DROP: {
680
+ if (this.stack.length < 1) {
681
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
682
+ return false;
683
+ }
684
+ this.stack.pop();
685
+ break;
686
+ }
687
+ case Opcode.OP_DUP: {
688
+ if (this.stack.length < 1) {
689
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
690
+ return false;
691
+ }
692
+ this.stack.push(this.stack[this.stack.length - 1]);
693
+ break;
694
+ }
695
+ case Opcode.OP_NIP: {
696
+ if (this.stack.length < 2) {
697
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
698
+ return false;
699
+ }
700
+ this.stack.splice(this.stack.length - 2, 1);
701
+ break;
702
+ }
703
+ case Opcode.OP_OVER: {
704
+ if (this.stack.length < 2) {
705
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
706
+ return false;
707
+ }
708
+ this.stack.push(this.stack[this.stack.length - 2]);
709
+ break;
710
+ }
711
+ case Opcode.OP_PICK:
712
+ case Opcode.OP_ROLL: {
713
+ if (this.stack.length < 1) {
714
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
715
+ return false;
716
+ }
717
+ const n = this.fromScriptNumBuffer(this.stack[this.stack.length - 1]);
718
+ this.stack.pop();
719
+ if (n < 0n || n >= BigInt(this.stack.length)) {
720
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
721
+ return false;
722
+ }
723
+ const val = this.stack[this.stack.length - 1 - Number(n)];
724
+ if (opcodenum === Opcode.OP_ROLL) {
725
+ this.stack.splice(this.stack.length - 1 - Number(n), 1);
726
+ }
727
+ this.stack.push(val);
728
+ break;
729
+ }
730
+ case Opcode.OP_ROT: {
731
+ if (this.stack.length < 3) {
732
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
733
+ return false;
734
+ }
735
+ const x1 = this.stack[this.stack.length - 3];
736
+ const x2 = this.stack[this.stack.length - 2];
737
+ const x3 = this.stack[this.stack.length - 1];
738
+ this.stack[this.stack.length - 3] = x2;
739
+ this.stack[this.stack.length - 2] = x3;
740
+ this.stack[this.stack.length - 1] = x1;
741
+ break;
742
+ }
743
+ case Opcode.OP_SWAP: {
744
+ if (this.stack.length < 2) {
745
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
746
+ return false;
747
+ }
748
+ const x1 = this.stack[this.stack.length - 2];
749
+ const x2 = this.stack[this.stack.length - 1];
750
+ this.stack[this.stack.length - 2] = x2;
751
+ this.stack[this.stack.length - 1] = x1;
752
+ break;
753
+ }
754
+ case Opcode.OP_TUCK: {
755
+ if (this.stack.length < 2) {
756
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
757
+ return false;
758
+ }
759
+ const x1 = this.stack[this.stack.length - 2];
760
+ const x2 = this.stack[this.stack.length - 1];
761
+ this.stack.splice(this.stack.length - 2, 0, x2);
762
+ break;
763
+ }
764
+ case Opcode.OP_SIZE: {
765
+ if (this.stack.length < 1) {
766
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
767
+ return false;
768
+ }
769
+ const size = this.stack[this.stack.length - 1].length;
770
+ this.stack.push(this.toScriptNumBuffer(size));
771
+ break;
772
+ }
773
+ case Opcode.OP_AND:
774
+ case Opcode.OP_OR:
775
+ case Opcode.OP_XOR: {
776
+ if (this.stack.length < 2) {
777
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
778
+ return false;
779
+ }
780
+ const buf1 = this.stack.pop();
781
+ const buf2 = this.stack.pop();
782
+ if (buf1.length !== buf2.length) {
783
+ this.errstr = 'SCRIPT_ERR_INVALID_OPERAND_SIZE';
784
+ return false;
785
+ }
786
+ const result = Buffer.alloc(buf1.length);
787
+ for (let i = 0; i < buf1.length; i++) {
788
+ switch (opcodenum) {
789
+ case Opcode.OP_AND:
790
+ result[i] = buf1[i] & buf2[i];
791
+ break;
792
+ case Opcode.OP_OR:
793
+ result[i] = buf1[i] | buf2[i];
794
+ break;
795
+ case Opcode.OP_XOR:
796
+ result[i] = buf1[i] ^ buf2[i];
797
+ break;
798
+ }
799
+ }
800
+ this.stack.push(result);
801
+ break;
802
+ }
803
+ case Opcode.OP_EQUAL:
804
+ case Opcode.OP_EQUALVERIFY: {
805
+ if (this.stack.length < 2) {
806
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
807
+ return false;
808
+ }
809
+ const buf1 = this.stacktop(-2);
810
+ const buf2 = this.stacktop(-1);
811
+ const fEqual = buf1.toString('hex') === buf2.toString('hex');
812
+ this.stack.pop();
813
+ this.stack.pop();
814
+ this.stack.push(fEqual ? Interpreter.true : Interpreter.false);
815
+ if (opcodenum === Opcode.OP_EQUALVERIFY) {
816
+ if (fEqual) {
817
+ this.stack.pop();
818
+ }
819
+ else {
820
+ this.errstr = 'SCRIPT_ERR_EQUALVERIFY';
821
+ return false;
822
+ }
823
+ }
824
+ break;
825
+ }
826
+ case Opcode.OP_1ADD: {
827
+ if (this.stack.length < 1) {
828
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
829
+ return false;
830
+ }
831
+ const bn = this.fromScriptNumBuffer(this.stack[this.stack.length - 1]);
832
+ this.stack[this.stack.length - 1] = this.toScriptNumBuffer(bn + 1n);
833
+ break;
834
+ }
835
+ case Opcode.OP_1SUB: {
836
+ if (this.stack.length < 1) {
837
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
838
+ return false;
839
+ }
840
+ const bn = this.fromScriptNumBuffer(this.stack[this.stack.length - 1]);
841
+ this.stack[this.stack.length - 1] = this.toScriptNumBuffer(bn - 1n);
842
+ break;
843
+ }
844
+ case Opcode.OP_NEGATE: {
845
+ if (this.stack.length < 1) {
846
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
847
+ return false;
848
+ }
849
+ const bn = this.fromScriptNumBuffer(this.stack[this.stack.length - 1]);
850
+ this.stack[this.stack.length - 1] = this.toScriptNumBuffer(-bn);
851
+ break;
852
+ }
853
+ case Opcode.OP_ABS: {
854
+ if (this.stack.length < 1) {
855
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
856
+ return false;
857
+ }
858
+ const bn = this.fromScriptNumBuffer(this.stack[this.stack.length - 1]);
859
+ this.stack[this.stack.length - 1] = this.toScriptNumBuffer(bn < 0n ? -bn : bn);
860
+ break;
861
+ }
862
+ case Opcode.OP_NOT: {
863
+ if (this.stack.length < 1) {
864
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
865
+ return false;
866
+ }
867
+ const bn = this.fromScriptNumBuffer(this.stack[this.stack.length - 1]);
868
+ this.stack[this.stack.length - 1] = this.toScriptNumBuffer(bn === 0n ? 1n : 0n);
869
+ break;
870
+ }
871
+ case Opcode.OP_0NOTEQUAL: {
872
+ if (this.stack.length < 1) {
873
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
874
+ return false;
875
+ }
876
+ const bn = this.fromScriptNumBuffer(this.stack[this.stack.length - 1]);
877
+ this.stack[this.stack.length - 1] = this.toScriptNumBuffer(bn !== 0n ? 1n : 0n);
878
+ break;
879
+ }
880
+ case Opcode.OP_ADD: {
881
+ if (this.stack.length < 2) {
882
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
883
+ return false;
884
+ }
885
+ const bn1 = this.fromScriptNumBuffer(this.stack.pop());
886
+ const bn2 = this.fromScriptNumBuffer(this.stack.pop());
887
+ this.stack.push(this.toScriptNumBuffer(bn1 + bn2));
888
+ break;
889
+ }
890
+ case Opcode.OP_SUB: {
891
+ if (this.stack.length < 2) {
892
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
893
+ return false;
894
+ }
895
+ const bn1 = this.fromScriptNumBuffer(this.stack.pop());
896
+ const bn2 = this.fromScriptNumBuffer(this.stack.pop());
897
+ this.stack.push(this.toScriptNumBuffer(bn2 - bn1));
898
+ break;
899
+ }
900
+ case Opcode.OP_BOOLAND: {
901
+ if (this.stack.length < 2) {
902
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
903
+ return false;
904
+ }
905
+ const bn1 = this.fromScriptNumBuffer(this.stack.pop());
906
+ const bn2 = this.fromScriptNumBuffer(this.stack.pop());
907
+ const result = bn1 !== 0n && bn2 !== 0n ? 1n : 0n;
908
+ this.stack.push(this.toScriptNumBuffer(result));
909
+ break;
910
+ }
911
+ case Opcode.OP_BOOLOR: {
912
+ if (this.stack.length < 2) {
913
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
914
+ return false;
915
+ }
916
+ const bn1 = this.fromScriptNumBuffer(this.stack.pop());
917
+ const bn2 = this.fromScriptNumBuffer(this.stack.pop());
918
+ const result = bn1 !== 0n || bn2 !== 0n ? 1n : 0n;
919
+ this.stack.push(this.toScriptNumBuffer(result));
920
+ break;
921
+ }
922
+ case Opcode.OP_LESSTHAN: {
923
+ if (this.stack.length < 2) {
924
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
925
+ return false;
926
+ }
927
+ const bn1 = this.fromScriptNumBuffer(this.stack.pop());
928
+ const bn2 = this.fromScriptNumBuffer(this.stack.pop());
929
+ const result = bn2 < bn1 ? 1n : 0n;
930
+ this.stack.push(this.toScriptNumBuffer(result));
931
+ break;
932
+ }
933
+ case Opcode.OP_GREATERTHAN: {
934
+ if (this.stack.length < 2) {
935
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
936
+ return false;
937
+ }
938
+ const bn1 = this.fromScriptNumBuffer(this.stack.pop());
939
+ const bn2 = this.fromScriptNumBuffer(this.stack.pop());
940
+ const result = bn2 > bn1 ? 1n : 0n;
941
+ this.stack.push(this.toScriptNumBuffer(result));
942
+ break;
943
+ }
944
+ case Opcode.OP_LESSTHANOREQUAL: {
945
+ if (this.stack.length < 2) {
946
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
947
+ return false;
948
+ }
949
+ const bn1 = this.fromScriptNumBuffer(this.stack.pop());
950
+ const bn2 = this.fromScriptNumBuffer(this.stack.pop());
951
+ const result = bn2 <= bn1 ? 1n : 0n;
952
+ this.stack.push(this.toScriptNumBuffer(result));
953
+ break;
954
+ }
955
+ case Opcode.OP_GREATERTHANOREQUAL: {
956
+ if (this.stack.length < 2) {
957
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
958
+ return false;
959
+ }
960
+ const bn1 = this.fromScriptNumBuffer(this.stack.pop());
961
+ const bn2 = this.fromScriptNumBuffer(this.stack.pop());
962
+ const result = bn2 >= bn1 ? 1n : 0n;
963
+ this.stack.push(this.toScriptNumBuffer(result));
964
+ break;
965
+ }
966
+ case Opcode.OP_MIN: {
967
+ if (this.stack.length < 2) {
968
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
969
+ return false;
970
+ }
971
+ const bn1 = this.fromScriptNumBuffer(this.stack.pop());
972
+ const bn2 = this.fromScriptNumBuffer(this.stack.pop());
973
+ const result = bn1 < bn2 ? bn1 : bn2;
974
+ this.stack.push(this.toScriptNumBuffer(result));
975
+ break;
976
+ }
977
+ case Opcode.OP_MAX: {
978
+ if (this.stack.length < 2) {
979
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
980
+ return false;
981
+ }
982
+ const bn1 = this.fromScriptNumBuffer(this.stack.pop());
983
+ const bn2 = this.fromScriptNumBuffer(this.stack.pop());
984
+ const result = bn1 > bn2 ? bn1 : bn2;
985
+ this.stack.push(this.toScriptNumBuffer(result));
986
+ break;
987
+ }
988
+ case Opcode.OP_WITHIN: {
989
+ if (this.stack.length < 3) {
990
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
991
+ return false;
992
+ }
993
+ const bn1 = this.fromScriptNumBuffer(this.stack.pop());
994
+ const bn2 = this.fromScriptNumBuffer(this.stack.pop());
995
+ const bn3 = this.fromScriptNumBuffer(this.stack.pop());
996
+ const result = bn3 >= bn2 && bn3 < bn1 ? 1n : 0n;
997
+ this.stack.push(this.toScriptNumBuffer(result));
998
+ break;
999
+ }
1000
+ case Opcode.OP_RIPEMD160: {
1001
+ if (this.stack.length < 1) {
1002
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
1003
+ return false;
1004
+ }
1005
+ const buf = this.stack.pop();
1006
+ this.stack.push(Hash.ripemd160(buf));
1007
+ break;
1008
+ }
1009
+ case Opcode.OP_SHA256: {
1010
+ if (this.stack.length < 1) {
1011
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
1012
+ return false;
1013
+ }
1014
+ const buf = this.stack.pop();
1015
+ this.stack.push(Hash.sha256(buf));
1016
+ break;
1017
+ }
1018
+ case Opcode.OP_HASH160: {
1019
+ if (this.stack.length < 1) {
1020
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
1021
+ return false;
1022
+ }
1023
+ const buf = this.stack.pop();
1024
+ this.stack.push(Hash.sha256ripemd160(buf));
1025
+ break;
1026
+ }
1027
+ case Opcode.OP_HASH256: {
1028
+ if (this.stack.length < 1) {
1029
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
1030
+ return false;
1031
+ }
1032
+ const buf = this.stack.pop();
1033
+ this.stack.push(Hash.sha256sha256(buf));
1034
+ break;
1035
+ }
1036
+ case Opcode.OP_CODESEPARATOR: {
1037
+ this.pbegincodehash = this.pc;
1038
+ break;
1039
+ }
1040
+ case Opcode.OP_CHECKDATASIG:
1041
+ case Opcode.OP_CHECKDATASIGVERIFY: {
1042
+ if (this.stack.length < 3) {
1043
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
1044
+ return false;
1045
+ }
1046
+ const bufSig = this.stacktop(-3);
1047
+ const bufMessage = this.stacktop(-2);
1048
+ const bufPubkey = this.stacktop(-1);
1049
+ if (!this.checkDataSignatureEncoding(bufSig) ||
1050
+ !this.checkPubkeyEncoding(bufPubkey)) {
1051
+ return false;
1052
+ }
1053
+ let fSuccess = false;
1054
+ try {
1055
+ const sig = Signature.fromDataFormat(bufSig);
1056
+ const pubkey = new PublicKey(bufPubkey);
1057
+ const bufHash = Hash.sha256(bufMessage);
1058
+ if (!sig.isSchnorr) {
1059
+ fSuccess = ECDSA.verify(bufHash, sig, pubkey, 'big');
1060
+ }
1061
+ else {
1062
+ fSuccess = Schnorr.verify(bufHash, sig, pubkey, 'big');
1063
+ }
1064
+ }
1065
+ catch (e) {
1066
+ fSuccess = false;
1067
+ }
1068
+ if (!fSuccess &&
1069
+ this.flags & Interpreter.SCRIPT_VERIFY_NULLFAIL &&
1070
+ bufSig.length) {
1071
+ this.errstr = 'SCRIPT_ERR_NULLFAIL';
1072
+ return false;
1073
+ }
1074
+ this.stack.pop();
1075
+ this.stack.pop();
1076
+ this.stack.pop();
1077
+ this.stack.push(fSuccess ? Interpreter.true : Interpreter.false);
1078
+ if (opcodenum === Opcode.OP_CHECKDATASIGVERIFY) {
1079
+ if (fSuccess) {
1080
+ this.stack.pop();
1081
+ }
1082
+ else {
1083
+ this.errstr = 'SCRIPT_ERR_CHECKDATASIGVERIFY';
1084
+ return false;
1085
+ }
1086
+ }
1087
+ break;
1088
+ }
1089
+ case Opcode.OP_REVERSEBYTES: {
1090
+ if (this.stack.length < 1) {
1091
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
1092
+ return false;
1093
+ }
1094
+ const buf = this.stacktop(-1);
1095
+ const reversedBuf = Buffer.from(buf).reverse();
1096
+ this.stack.pop();
1097
+ this.stack.push(reversedBuf);
1098
+ break;
1099
+ }
1100
+ case Opcode.OP_CHECKSIG: {
1101
+ if (this.stack.length < 2) {
1102
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
1103
+ return false;
1104
+ }
1105
+ const sigBuf = this.stack[this.stack.length - 2];
1106
+ const pubkeyBuf = this.stack[this.stack.length - 1];
1107
+ if (!this.checkTxSignatureEncoding(sigBuf) ||
1108
+ !this.checkPubkeyEncoding(pubkeyBuf)) {
1109
+ return false;
1110
+ }
1111
+ const subscript = new Script();
1112
+ subscript.chunks = this.script.chunks.slice(this.pbegincodehash);
1113
+ const tmpScript = new Script().add(sigBuf);
1114
+ subscript.findAndDelete(tmpScript);
1115
+ let fSuccess = false;
1116
+ try {
1117
+ const signature = Signature.fromTxFormat(sigBuf);
1118
+ const pubkey = new PublicKey(pubkeyBuf);
1119
+ if (this.tx &&
1120
+ this.nin !== undefined &&
1121
+ this.satoshisBN !== undefined) {
1122
+ if (!signature.isSchnorr) {
1123
+ fSuccess = this.tx.verifySignature(signature, pubkey, this.nin, subscript, new BN(this.satoshisBN.toString()), this.flags);
1124
+ }
1125
+ else {
1126
+ fSuccess = this.tx.verifySignature(signature, pubkey, this.nin, subscript, new BN(this.satoshisBN.toString()), this.flags, 'schnorr');
1127
+ }
1128
+ }
1129
+ }
1130
+ catch (e) {
1131
+ fSuccess = false;
1132
+ }
1133
+ if (!fSuccess &&
1134
+ this.flags & Interpreter.SCRIPT_VERIFY_NULLFAIL &&
1135
+ sigBuf.length) {
1136
+ this.errstr = 'SCRIPT_ERR_NULLFAIL';
1137
+ return false;
1138
+ }
1139
+ this.stack.pop();
1140
+ this.stack.pop();
1141
+ this.stack.push(fSuccess ? Interpreter.true : Interpreter.false);
1142
+ break;
1143
+ }
1144
+ case Opcode.OP_CHECKSIGVERIFY: {
1145
+ if (this.stack.length < 2) {
1146
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
1147
+ return false;
1148
+ }
1149
+ const sigBuf2 = this.stack[this.stack.length - 2];
1150
+ const pubkeyBuf2 = this.stack[this.stack.length - 1];
1151
+ if (!this.checkTxSignatureEncoding(sigBuf2) ||
1152
+ !this.checkPubkeyEncoding(pubkeyBuf2)) {
1153
+ return false;
1154
+ }
1155
+ const subscript2 = new Script();
1156
+ subscript2.chunks = this.script.chunks.slice(this.pbegincodehash);
1157
+ const tmpScript2 = new Script().add(sigBuf2);
1158
+ subscript2.findAndDelete(tmpScript2);
1159
+ let fSuccess2 = false;
1160
+ try {
1161
+ const signature = Signature.fromTxFormat(sigBuf2);
1162
+ const pubkey = new PublicKey(pubkeyBuf2);
1163
+ if (this.tx &&
1164
+ this.nin !== undefined &&
1165
+ this.satoshisBN !== undefined) {
1166
+ if (!signature.isSchnorr) {
1167
+ fSuccess2 = this.tx.verifySignature(signature, pubkey, this.nin, subscript2, new BN(this.satoshisBN.toString()), this.flags);
1168
+ }
1169
+ else {
1170
+ fSuccess2 = this.tx.verifySignature(signature, pubkey, this.nin, subscript2, new BN(this.satoshisBN.toString()), this.flags, 'schnorr');
1171
+ }
1172
+ }
1173
+ }
1174
+ catch (e) {
1175
+ fSuccess2 = false;
1176
+ }
1177
+ if (!fSuccess2 &&
1178
+ this.flags & Interpreter.SCRIPT_VERIFY_NULLFAIL &&
1179
+ sigBuf2.length) {
1180
+ this.errstr = 'SCRIPT_ERR_NULLFAIL';
1181
+ return false;
1182
+ }
1183
+ this.stack.pop();
1184
+ this.stack.pop();
1185
+ if (fSuccess2) {
1186
+ }
1187
+ else {
1188
+ this.errstr = 'SCRIPT_ERR_CHECKSIGVERIFY';
1189
+ return false;
1190
+ }
1191
+ break;
1192
+ }
1193
+ case Opcode.OP_CHECKMULTISIG:
1194
+ case Opcode.OP_CHECKMULTISIGVERIFY: {
1195
+ const fRequireMinimal = (this.flags & Interpreter.SCRIPT_VERIFY_MINIMALDATA) !== 0;
1196
+ let i = 1;
1197
+ const idxTopKey = i + 1;
1198
+ if (this.stack.length < i) {
1199
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
1200
+ return false;
1201
+ }
1202
+ const nKeysCountBN = BN.fromScriptNumBuffer(this.stacktop(-i), fRequireMinimal);
1203
+ let nKeysCount = nKeysCountBN.toNumber();
1204
+ const idxSigCount = idxTopKey + nKeysCount;
1205
+ if (nKeysCount < 0 || nKeysCount > 20) {
1206
+ this.errstr = 'SCRIPT_ERR_PUBKEY_COUNT';
1207
+ return false;
1208
+ }
1209
+ this.nOpCount += nKeysCount;
1210
+ if (this.nOpCount > 201) {
1211
+ this.errstr = 'SCRIPT_ERR_OP_COUNT';
1212
+ return false;
1213
+ }
1214
+ let ikey = ++i;
1215
+ const idxTopSig = idxSigCount + 1;
1216
+ i += nKeysCount;
1217
+ let ikey2 = nKeysCount + 2;
1218
+ if (this.stack.length < i) {
1219
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
1220
+ return false;
1221
+ }
1222
+ const nSigsCountBN = BN.fromScriptNumBuffer(this.stacktop(-idxSigCount), fRequireMinimal);
1223
+ let nSigsCount = nSigsCountBN.toNumber();
1224
+ const idxDummy = idxTopSig + nSigsCount;
1225
+ if (nSigsCount < 0 || nSigsCount > nKeysCount) {
1226
+ this.errstr = 'SCRIPT_ERR_SIG_COUNT';
1227
+ return false;
1228
+ }
1229
+ let isig = ++i;
1230
+ i += nSigsCount;
1231
+ if (this.stack.length < idxDummy) {
1232
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
1233
+ return false;
1234
+ }
1235
+ const subscript = new Script();
1236
+ subscript.chunks = this.script.chunks.slice(this.pbegincodehash);
1237
+ let fSuccess = true;
1238
+ if (this.flags & Interpreter.SCRIPT_ENABLE_SCHNORR_MULTISIG &&
1239
+ this.stacktop(-idxDummy).length !== 0) {
1240
+ const dummy = this.stacktop(-idxDummy);
1241
+ const bitfieldObj = this.decodeBitfield(dummy, nKeysCount);
1242
+ if (!bitfieldObj.result) {
1243
+ fSuccess = false;
1244
+ }
1245
+ const nSigs8bit = new Uint8Array([nSigsCount]);
1246
+ const nSigs32 = Uint32Array.from(nSigs8bit);
1247
+ if (this.countBits(bitfieldObj.bitfield) !== nSigs32[0]) {
1248
+ this.errstr = 'INVALID_BIT_COUNT';
1249
+ fSuccess = false;
1250
+ }
1251
+ const bottomKey = idxTopKey + nKeysCount - 1;
1252
+ const bottomSig = idxTopSig + nSigsCount - 1;
1253
+ let iKey = 0;
1254
+ for (let iSig = 0; iSig < nSigsCount; iSig++, iKey++) {
1255
+ if (bitfieldObj.bitfield >> iKey === 0) {
1256
+ this.errstr = 'INVALID_BIT_RANGE';
1257
+ fSuccess = false;
1258
+ }
1259
+ while (((bitfieldObj.bitfield >> iKey) & 0x01) == 0) {
1260
+ if (iKey >= nKeysCount) {
1261
+ this.errstr = 'wrong';
1262
+ fSuccess = false;
1263
+ break;
1264
+ }
1265
+ iKey++;
1266
+ }
1267
+ if (iKey >= nKeysCount) {
1268
+ this.errstr = 'PUBKEY_COUNT';
1269
+ fSuccess = false;
1270
+ }
1271
+ const bufsig = this.stacktop(-bottomSig + iSig);
1272
+ const bufPubkey = this.stacktop(-bottomKey + iKey);
1273
+ if (!this.checkRawSignatureEncoding(bufsig) ||
1274
+ !this.checkPubkeyEncoding(bufPubkey)) {
1275
+ fSuccess = false;
1276
+ }
1277
+ try {
1278
+ const sig = Signature.fromTxFormat(bufsig);
1279
+ const pubkey = new PublicKey(bufPubkey);
1280
+ const fOk = this.tx?.verifySignature(sig, pubkey, this.nin, subscript, new BN(this.satoshisBN.toString()), this.flags, 'schnorr') || false;
1281
+ if (!fOk) {
1282
+ this.errstr = 'SIG_NULLFAIL';
1283
+ fSuccess = false;
1284
+ }
1285
+ }
1286
+ catch (e) {
1287
+ fSuccess = false;
1288
+ }
1289
+ }
1290
+ if (bitfieldObj.bitfield >> iKey != 0) {
1291
+ this.errstr = 'INVALID_BIT_COUNT';
1292
+ fSuccess = false;
1293
+ }
1294
+ }
1295
+ else {
1296
+ for (let k = 0; k < nSigsCount; k++) {
1297
+ const bufSig = this.stacktop(-isig - k);
1298
+ subscript.findAndDelete(new Script().add(bufSig));
1299
+ }
1300
+ while (fSuccess && nSigsCount > 0) {
1301
+ const bufSig = this.stacktop(-isig);
1302
+ const bufPubkey = this.stacktop(-ikey);
1303
+ if (!this.checkTxSignatureEncoding(bufSig) ||
1304
+ !this.checkPubkeyEncoding(bufPubkey)) {
1305
+ return false;
1306
+ }
1307
+ let fOk = false;
1308
+ try {
1309
+ const sig = Signature.fromTxFormat(bufSig);
1310
+ const pubkey = new PublicKey(bufPubkey);
1311
+ fOk =
1312
+ this.tx?.verifySignature(sig, pubkey, this.nin, subscript, new BN(this.satoshisBN.toString()), this.flags) || false;
1313
+ }
1314
+ catch (e) {
1315
+ fOk = false;
1316
+ }
1317
+ if (fOk) {
1318
+ isig++;
1319
+ nSigsCount--;
1320
+ }
1321
+ ikey++;
1322
+ nKeysCount--;
1323
+ if (nSigsCount > nKeysCount) {
1324
+ fSuccess = false;
1325
+ }
1326
+ }
1327
+ }
1328
+ while (i-- > 1) {
1329
+ if (!fSuccess &&
1330
+ this.flags & Interpreter.SCRIPT_VERIFY_NULLFAIL &&
1331
+ !ikey2 &&
1332
+ this.stacktop(-1).length) {
1333
+ this.errstr = 'SCRIPT_ERR_NULLFAIL';
1334
+ return false;
1335
+ }
1336
+ if (ikey2 > 0) {
1337
+ ikey2--;
1338
+ }
1339
+ this.stack.pop();
1340
+ }
1341
+ if (this.stack.length < 1) {
1342
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
1343
+ return false;
1344
+ }
1345
+ if (this.flags & Interpreter.SCRIPT_VERIFY_NULLDUMMY &&
1346
+ this.stacktop(-1).length) {
1347
+ this.errstr = 'SCRIPT_ERR_SIG_NULLDUMMY';
1348
+ return false;
1349
+ }
1350
+ this.stack.pop();
1351
+ this.stack.push(fSuccess ? Interpreter.true : Interpreter.false);
1352
+ if (opcodenum === Opcode.OP_CHECKMULTISIGVERIFY) {
1353
+ if (fSuccess) {
1354
+ this.stack.pop();
1355
+ }
1356
+ else {
1357
+ this.errstr = 'SCRIPT_ERR_CHECKMULTISIGVERIFY';
1358
+ return false;
1359
+ }
1360
+ }
1361
+ break;
1362
+ }
1363
+ case Opcode.OP_CAT: {
1364
+ if (this.stack.length < 2) {
1365
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
1366
+ return false;
1367
+ }
1368
+ const buf1 = this.stacktop(-2);
1369
+ const buf2 = this.stacktop(-1);
1370
+ if (buf1.length + buf2.length > Interpreter.MAX_SCRIPT_ELEMENT_SIZE) {
1371
+ this.errstr = 'SCRIPT_ERR_PUSH_SIZE';
1372
+ return false;
1373
+ }
1374
+ this.stack[this.stack.length - 2] = Buffer.concat([buf1, buf2]);
1375
+ this.stack.pop();
1376
+ break;
1377
+ }
1378
+ case Opcode.OP_SPLIT: {
1379
+ if (this.stack.length < 2) {
1380
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
1381
+ return false;
1382
+ }
1383
+ const fRequireMinimal = (this.flags & Interpreter.SCRIPT_VERIFY_MINIMALDATA) !== 0;
1384
+ const buf1 = this.stacktop(-2);
1385
+ const position = BN.fromScriptNumBuffer(this.stacktop(-1), fRequireMinimal).toNumber();
1386
+ if (position < 0 || position > buf1.length) {
1387
+ this.errstr = 'SCRIPT_ERR_INVALID_SPLIT_RANGE';
1388
+ return false;
1389
+ }
1390
+ const n1 = Buffer.from(buf1);
1391
+ this.stack[this.stack.length - 2] = n1.subarray(0, position);
1392
+ this.stack[this.stack.length - 1] = n1.subarray(position);
1393
+ break;
1394
+ }
1395
+ case Opcode.OP_NUM2BIN: {
1396
+ if (this.stack.length < 2) {
1397
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
1398
+ return false;
1399
+ }
1400
+ const fRequireMinimal = (this.flags & Interpreter.SCRIPT_VERIFY_MINIMALDATA) !== 0;
1401
+ const size = BN.fromScriptNumBuffer(this.stacktop(-1), fRequireMinimal).toNumber();
1402
+ if (size > Interpreter.MAX_SCRIPT_ELEMENT_SIZE) {
1403
+ this.errstr = 'SCRIPT_ERR_PUSH_SIZE';
1404
+ return false;
1405
+ }
1406
+ this.stack.pop();
1407
+ let rawnum = this.stacktop(-1);
1408
+ rawnum = Interpreter._minimallyEncode(rawnum);
1409
+ if (rawnum.length > size) {
1410
+ this.errstr = 'SCRIPT_ERR_IMPOSSIBLE_ENCODING';
1411
+ return false;
1412
+ }
1413
+ if (rawnum.length == size) {
1414
+ this.stack[this.stack.length - 1] = rawnum;
1415
+ break;
1416
+ }
1417
+ let signbit = 0x00;
1418
+ if (rawnum.length > 0) {
1419
+ signbit = rawnum[rawnum.length - 1] & 0x80;
1420
+ rawnum[rawnum.length - 1] &= 0x7f;
1421
+ }
1422
+ const num = Buffer.alloc(size);
1423
+ rawnum.copy(num, 0);
1424
+ let l = rawnum.length - 1;
1425
+ while (l++ < size - 2) {
1426
+ num[l] = 0x00;
1427
+ }
1428
+ num[l] = signbit;
1429
+ this.stack[this.stack.length - 1] = num;
1430
+ break;
1431
+ }
1432
+ case Opcode.OP_BIN2NUM: {
1433
+ if (this.stack.length < 1) {
1434
+ this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
1435
+ return false;
1436
+ }
1437
+ const buf1 = this.stacktop(-1);
1438
+ const buf2 = Interpreter._minimallyEncode(buf1);
1439
+ this.stack[this.stack.length - 1] = buf2;
1440
+ if (!Interpreter._isMinimallyEncoded(buf2)) {
1441
+ this.errstr = 'SCRIPT_ERR_INVALID_NUMBER_RANGE';
1442
+ return false;
1443
+ }
1444
+ break;
1445
+ }
1446
+ default:
1447
+ this.errstr = 'SCRIPT_ERR_BAD_OPCODE';
1448
+ return false;
1449
+ }
1450
+ }
1451
+ return true;
1452
+ }
1453
+ decodeBitfield(dummy, size) {
1454
+ if (size > 32) {
1455
+ this.errstr = 'INVALID_BITFIELD_SIZE';
1456
+ return { result: false };
1457
+ }
1458
+ const bitfieldSize = Math.floor((size + 7) / 8);
1459
+ const dummyBitlength = dummy.length;
1460
+ if (dummyBitlength !== bitfieldSize) {
1461
+ this.errstr = 'INVALID_BITFIELD_SIZE';
1462
+ return { result: false };
1463
+ }
1464
+ let bitfield = 0;
1465
+ const dummyAs32Bit = Uint32Array.from(dummy);
1466
+ for (let i = 0; i < bitfieldSize; i++) {
1467
+ bitfield = bitfield | (dummyAs32Bit[i] << (8 * i));
1468
+ }
1469
+ const mask = (0x01 << size) - 1;
1470
+ if ((bitfield & mask) != bitfield) {
1471
+ this.errstr = 'INVALID_BIT_RANGE';
1472
+ return { result: false };
1473
+ }
1474
+ return { result: true, bitfield: bitfield };
1475
+ }
1476
+ countBits(v) {
1477
+ v = v - ((v >> 1) & 0x55555555);
1478
+ v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
1479
+ return (((v + (v >> 4)) & 0xf0f0f0f) * 0x1010101) >> 24;
1480
+ }
1481
+ stacktop(i) {
1482
+ return this.stack[this.stack.length + i];
1483
+ }
1484
+ isOpcodeDisabled(opcode) {
1485
+ switch (opcode) {
1486
+ case 80:
1487
+ case 101:
1488
+ case 102:
1489
+ case 115:
1490
+ case Opcode.OP_INVERT:
1491
+ case 137:
1492
+ case 138:
1493
+ case Opcode.OP_2MUL:
1494
+ case Opcode.OP_2DIV:
1495
+ case Opcode.OP_MUL:
1496
+ case 156:
1497
+ case 157:
1498
+ case 158:
1499
+ case 167:
1500
+ case Opcode.OP_LSHIFT:
1501
+ case Opcode.OP_RSHIFT:
1502
+ return true;
1503
+ case Opcode.OP_DIV:
1504
+ case Opcode.OP_MOD:
1505
+ case Opcode.OP_SPLIT:
1506
+ case Opcode.OP_CAT:
1507
+ case Opcode.OP_AND:
1508
+ case Opcode.OP_OR:
1509
+ case Opcode.OP_XOR:
1510
+ case Opcode.OP_BIN2NUM:
1511
+ case Opcode.OP_NUM2BIN:
1512
+ return false;
1513
+ default:
1514
+ if (opcode >= 189) {
1515
+ return true;
1516
+ }
1517
+ return false;
1518
+ }
1519
+ }
1520
+ checkLockTime(nLockTime) {
1521
+ if (!this.tx || this.nin === undefined) {
1522
+ return false;
1523
+ }
1524
+ if (!((this.tx.nLockTime < Interpreter.LOCKTIME_THRESHOLD &&
1525
+ nLockTime.lt(Interpreter.LOCKTIME_THRESHOLD_BN)) ||
1526
+ (this.tx.nLockTime >= Interpreter.LOCKTIME_THRESHOLD &&
1527
+ nLockTime.gte(Interpreter.LOCKTIME_THRESHOLD_BN)))) {
1528
+ return false;
1529
+ }
1530
+ if (nLockTime.gt(new BN(this.tx.nLockTime))) {
1531
+ return false;
1532
+ }
1533
+ if (!this.tx.inputs[this.nin].isFinal()) {
1534
+ return false;
1535
+ }
1536
+ return true;
1537
+ }
1538
+ checkSequence(nSequence) {
1539
+ if (!this.tx || this.nin === undefined) {
1540
+ return false;
1541
+ }
1542
+ const txToSequence = this.tx.inputs[this.nin].sequenceNumber;
1543
+ if (this.tx.version < 2) {
1544
+ return false;
1545
+ }
1546
+ if (txToSequence & Interpreter.SEQUENCE_LOCKTIME_DISABLE_FLAG) {
1547
+ return false;
1548
+ }
1549
+ const nLockTimeMask = Interpreter.SEQUENCE_LOCKTIME_TYPE_FLAG |
1550
+ Interpreter.SEQUENCE_LOCKTIME_MASK;
1551
+ const txToSequenceMasked = new BN(txToSequence & nLockTimeMask);
1552
+ const nSequenceMasked = nSequence.and(nLockTimeMask);
1553
+ const SEQUENCE_LOCKTIME_TYPE_FLAG_BN = new BN(Interpreter.SEQUENCE_LOCKTIME_TYPE_FLAG);
1554
+ if (!((txToSequenceMasked.lt(SEQUENCE_LOCKTIME_TYPE_FLAG_BN) &&
1555
+ nSequenceMasked.lt(SEQUENCE_LOCKTIME_TYPE_FLAG_BN)) ||
1556
+ (txToSequenceMasked.gte(SEQUENCE_LOCKTIME_TYPE_FLAG_BN) &&
1557
+ nSequenceMasked.gte(SEQUENCE_LOCKTIME_TYPE_FLAG_BN)))) {
1558
+ return false;
1559
+ }
1560
+ if (nSequenceMasked.gt(txToSequenceMasked)) {
1561
+ return false;
1562
+ }
1563
+ return true;
1564
+ }
1565
+ static castToBool(buf) {
1566
+ for (let i = 0; i < buf.length; i++) {
1567
+ if (buf[i] !== 0) {
1568
+ if (i === buf.length - 1 && buf[i] === 0x80) {
1569
+ return false;
1570
+ }
1571
+ return true;
1572
+ }
1573
+ }
1574
+ return false;
1575
+ }
1576
+ static isSchnorrSig(buf) {
1577
+ return (buf.length === 64 || buf.length === 65) && buf[0] !== 0x30;
1578
+ }
1579
+ _verifyScriptType(scriptPubkey) {
1580
+ const buf = scriptPubkey.toBuffer();
1581
+ if (buf.length < 2) {
1582
+ this.errstr = 'SCRIPT_ERR_SCRIPTTYPE_MALFORMED_SCRIPT';
1583
+ return false;
1584
+ }
1585
+ const scriptType = buf[1];
1586
+ switch (scriptType) {
1587
+ case TAPROOT_SCRIPTTYPE: {
1588
+ const result = verifyTaprootSpend(scriptPubkey, this.stack, this.flags);
1589
+ if (!result.success) {
1590
+ this.errstr = result.error || 'SCRIPT_ERR_UNKNOWN';
1591
+ return false;
1592
+ }
1593
+ if (result.stack) {
1594
+ this.stack = result.stack;
1595
+ }
1596
+ if (result.scriptToExecute) {
1597
+ const prevScript = this.script;
1598
+ const prevPc = this.pc;
1599
+ const prevPbegincodehash = this.pbegincodehash;
1600
+ this.script = result.scriptToExecute;
1601
+ this.pc = 0;
1602
+ this.pbegincodehash = 0;
1603
+ const evalResult = this.evaluate();
1604
+ this.script = prevScript;
1605
+ this.pc = prevPc;
1606
+ this.pbegincodehash = prevPbegincodehash;
1607
+ if (!evalResult) {
1608
+ return false;
1609
+ }
1610
+ if (this.stack.length === 0) {
1611
+ this.errstr = 'SCRIPT_ERR_EVAL_FALSE_NO_RESULT';
1612
+ return false;
1613
+ }
1614
+ const finalBuf = this.stack[this.stack.length - 1];
1615
+ if (!Interpreter.castToBool(finalBuf)) {
1616
+ this.errstr = 'SCRIPT_ERR_EVAL_FALSE_IN_STACK';
1617
+ return false;
1618
+ }
1619
+ }
1620
+ else {
1621
+ const scriptBuf = scriptPubkey.toBuffer();
1622
+ const vchPubkey = scriptBuf.subarray(TAPROOT_INTRO_SIZE, TAPROOT_SIZE_WITHOUT_STATE);
1623
+ const vchSig = this.stack[this.stack.length - 1];
1624
+ const sigFlags = this.flags | Interpreter.SCRIPT_TAPROOT_KEY_SPEND_PATH;
1625
+ if (!this.checkTxSignatureEncoding(vchSig) ||
1626
+ !this.checkPubkeyEncoding(vchPubkey)) {
1627
+ return false;
1628
+ }
1629
+ if (vchSig.length === 0) {
1630
+ this.errstr = 'SCRIPT_ERR_TAPROOT_VERIFY_SIGNATURE_FAILED';
1631
+ return false;
1632
+ }
1633
+ const sig = Signature.fromTxFormat(vchSig);
1634
+ const pubkey = new PublicKey(vchPubkey);
1635
+ if (!sig.isSchnorr) {
1636
+ this.errstr = 'SCRIPT_ERR_TAPROOT_KEY_SPEND_SIGNATURE_NOT_SCHNORR';
1637
+ return false;
1638
+ }
1639
+ try {
1640
+ const isValid = this.tx?.verifySignature(sig, pubkey, this.nin, scriptPubkey, new BN(this.satoshisBN.toString()), sigFlags, 'schnorr');
1641
+ if (!isValid) {
1642
+ this.errstr = 'SCRIPT_ERR_TAPROOT_VERIFY_SIGNATURE_FAILED';
1643
+ return false;
1644
+ }
1645
+ }
1646
+ catch (e) {
1647
+ this.errstr = 'SCRIPT_ERR_TAPROOT_VERIFY_SIGNATURE_FAILED';
1648
+ return false;
1649
+ }
1650
+ }
1651
+ return true;
1652
+ }
1653
+ default:
1654
+ this.errstr = 'SCRIPT_ERR_SCRIPTTYPE_INVALID_TYPE';
1655
+ return false;
1656
+ }
1657
+ }
1658
+ static _isMinimallyEncoded(buf, nMaxNumSize) {
1659
+ nMaxNumSize = nMaxNumSize || Interpreter.MAXIMUM_ELEMENT_SIZE;
1660
+ if (buf.length > nMaxNumSize) {
1661
+ return false;
1662
+ }
1663
+ if (buf.length > 0) {
1664
+ if ((buf[buf.length - 1] & 0x7f) === 0) {
1665
+ if (buf.length <= 1 || (buf[buf.length - 2] & 0x80) === 0) {
1666
+ return false;
1667
+ }
1668
+ }
1669
+ }
1670
+ return true;
1671
+ }
1672
+ static _minimallyEncode(buf) {
1673
+ if (buf.length === 0) {
1674
+ return buf;
1675
+ }
1676
+ const last = buf[buf.length - 1];
1677
+ if (last & 0x7f) {
1678
+ return buf;
1679
+ }
1680
+ if (buf.length === 1) {
1681
+ return Buffer.from('');
1682
+ }
1683
+ if (buf[buf.length - 2] & 0x80) {
1684
+ return buf;
1685
+ }
1686
+ for (let i = buf.length - 1; i > 0; i--) {
1687
+ if (buf[i - 1] !== 0) {
1688
+ if (buf[i - 1] & 0x80) {
1689
+ const result = Buffer.alloc(i + 1);
1690
+ buf.copy(result, 0, 0, i);
1691
+ result[i] = last;
1692
+ return result;
1693
+ }
1694
+ else {
1695
+ const result = Buffer.alloc(i);
1696
+ buf.copy(result, 0, 0, i);
1697
+ result[i - 1] |= last;
1698
+ return result;
1699
+ }
1700
+ }
1701
+ }
1702
+ return Buffer.from('');
1703
+ }
1704
+ }