@opcat-labs/opcat 1.0.0 → 1.0.2

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 (293) hide show
  1. package/.cjs2esm.json +18 -0
  2. package/.mocharc.yaml +1 -1
  3. package/CHANGELOG.md +13 -0
  4. package/README.md +6 -0
  5. package/{lib/address.js → cjs/address.cjs} +77 -72
  6. package/cjs/block/block.cjs +332 -0
  7. package/{lib/block/blockheader.js → cjs/block/blockheader.cjs} +8 -7
  8. package/cjs/block/index.cjs +2 -0
  9. package/{lib/block/merkleblock.js → cjs/block/merkleblock.cjs} +23 -15
  10. package/cjs/bn.cjs +3411 -0
  11. package/{lib/crypto/bn.js → cjs/crypto/bn.cjs} +3 -3
  12. package/{lib/crypto/ecdsa.js → cjs/crypto/ecdsa.cjs} +150 -14
  13. package/{lib/crypto/hash.node.js → cjs/crypto/hash.cjs} +13 -2
  14. package/cjs/crypto/index.cjs +16 -0
  15. package/{lib/crypto/point.js → cjs/crypto/point.cjs} +11 -4
  16. package/cjs/crypto/random.cjs +18 -0
  17. package/{lib/crypto/signature.js → cjs/crypto/signature.cjs} +158 -8
  18. package/{lib/encoding/base58.js → cjs/encoding/base58.cjs} +58 -2
  19. package/cjs/encoding/base58check.cjs +192 -0
  20. package/cjs/encoding/bufferreader.cjs +333 -0
  21. package/cjs/encoding/bufferwriter.cjs +244 -0
  22. package/{lib/encoding/decode-asm.js → cjs/encoding/decode-asm.cjs} +4 -4
  23. package/{lib/encoding/decode-hex.js → cjs/encoding/decode-hex.cjs} +1 -1
  24. package/cjs/encoding/index.cjs +14 -0
  25. package/cjs/encoding/varint.cjs +116 -0
  26. package/{lib/errors/index.js → cjs/errors/index.cjs} +9 -9
  27. package/{lib/errors/spec.js → cjs/errors/spec.cjs} +2 -2
  28. package/cjs/hash-cache.cjs +98 -0
  29. package/{lib/hdprivatekey.js → cjs/hdprivatekey.cjs} +232 -140
  30. package/{lib/hdpublickey.js → cjs/hdpublickey.cjs} +120 -93
  31. package/cjs/index.cjs +94 -0
  32. package/cjs/interpreter/index.cjs +2 -0
  33. package/cjs/interpreter/interpreter.cjs +1988 -0
  34. package/{lib/script/stack.js → cjs/interpreter/stack.cjs} +9 -2
  35. package/{lib/message/message.js → cjs/message/message.cjs} +62 -25
  36. package/cjs/mnemonic/index.cjs +3 -0
  37. package/{lib/mnemonic/mnemonic.js → cjs/mnemonic/mnemonic.cjs} +44 -13
  38. package/{lib/mnemonic/pbkdf2.node.js → cjs/mnemonic/pbkdf2.cjs} +9 -2
  39. package/cjs/mnemonic/words/index.cjs +66 -0
  40. package/cjs/network.cjs +13 -0
  41. package/cjs/networks.cjs +321 -0
  42. package/{lib/opcode.js → cjs/opcode.cjs} +69 -5
  43. package/cjs/privatekey.cjs +422 -0
  44. package/{lib/publickey.js → cjs/publickey.cjs} +14 -16
  45. package/cjs/script/index.cjs +2 -0
  46. package/{lib/script/script.js → cjs/script/script.cjs} +322 -67
  47. package/cjs/transaction/index.cjs +5 -0
  48. package/cjs/transaction/input/index.cjs +34 -0
  49. package/cjs/transaction/input/input.cjs +396 -0
  50. package/{lib/transaction/input/multisig.js → cjs/transaction/input/multisig.cjs} +112 -18
  51. package/{lib/transaction/input/publickey.js → cjs/transaction/input/publickey.cjs} +29 -19
  52. package/{lib/transaction/input/publickeyhash.js → cjs/transaction/input/publickeyhash.cjs} +25 -17
  53. package/{lib/transaction/output.js → cjs/transaction/output.cjs} +100 -15
  54. package/cjs/transaction/sighash.cjs +187 -0
  55. package/{lib/transaction/signature.js → cjs/transaction/signature.cjs} +30 -6
  56. package/cjs/transaction/transaction.cjs +2000 -0
  57. package/{lib/transaction/unspentoutput.js → cjs/transaction/unspentoutput.cjs} +5 -5
  58. package/cjs/util/derivation.cjs +53 -0
  59. package/cjs/util/index.cjs +11 -0
  60. package/cjs/util/js.cjs +95 -0
  61. package/{lib/util/preconditions.js → cjs/util/preconditions.cjs} +2 -2
  62. package/esm/address.js +483 -0
  63. package/{lib → esm}/block/block.js +82 -27
  64. package/esm/block/blockheader.js +296 -0
  65. package/esm/block/index.js +2 -0
  66. package/esm/block/merkleblock.js +331 -0
  67. package/esm/bn.js +3411 -0
  68. package/esm/crypto/bn.js +278 -0
  69. package/esm/crypto/ecdsa.js +475 -0
  70. package/{lib/crypto/hash.browser.js → esm/crypto/hash.js} +18 -7
  71. package/esm/crypto/index.js +16 -0
  72. package/esm/crypto/point.js +228 -0
  73. package/esm/crypto/random.js +18 -0
  74. package/esm/crypto/signature.js +475 -0
  75. package/esm/encoding/base58.js +167 -0
  76. package/esm/encoding/base58check.js +192 -0
  77. package/esm/encoding/bufferreader.js +333 -0
  78. package/esm/encoding/bufferwriter.js +243 -0
  79. package/esm/encoding/decode-asm.js +24 -0
  80. package/esm/encoding/decode-hex.js +32 -0
  81. package/esm/encoding/decode-script-chunks.js +43 -0
  82. package/esm/encoding/encode-hex.js +284 -0
  83. package/esm/encoding/index.js +14 -0
  84. package/esm/encoding/is-hex.js +7 -0
  85. package/esm/encoding/varint.js +116 -0
  86. package/esm/errors/index.js +54 -0
  87. package/esm/errors/spec.js +314 -0
  88. package/esm/hash-cache.js +98 -0
  89. package/esm/hdprivatekey.js +768 -0
  90. package/esm/hdpublickey.js +549 -0
  91. package/esm/index.js +66 -0
  92. package/esm/interpreter/index.js +2 -0
  93. package/{lib/script → esm/interpreter}/interpreter.js +219 -66
  94. package/esm/interpreter/stack.js +116 -0
  95. package/esm/message/message.js +228 -0
  96. package/esm/mnemonic/index.js +3 -0
  97. package/esm/mnemonic/mnemonic.js +332 -0
  98. package/{lib/mnemonic/pbkdf2.browser.js → esm/mnemonic/pbkdf2.js} +13 -6
  99. package/esm/mnemonic/words/chinese.js +2054 -0
  100. package/esm/mnemonic/words/english.js +2054 -0
  101. package/esm/mnemonic/words/french.js +2054 -0
  102. package/esm/mnemonic/words/index.js +66 -0
  103. package/esm/mnemonic/words/italian.js +2054 -0
  104. package/esm/mnemonic/words/japanese.js +2054 -0
  105. package/esm/mnemonic/words/spanish.js +2054 -0
  106. package/esm/network.js +13 -0
  107. package/{lib → esm}/networks.js +61 -120
  108. package/esm/opcode.js +319 -0
  109. package/{lib → esm}/privatekey.js +76 -28
  110. package/esm/publickey.js +384 -0
  111. package/esm/script/index.js +2 -0
  112. package/esm/script/script.js +1329 -0
  113. package/esm/script/write-i32-le.js +17 -0
  114. package/esm/script/write-push-data.js +35 -0
  115. package/esm/script/write-u16-le.js +12 -0
  116. package/esm/script/write-u32-le.js +16 -0
  117. package/esm/script/write-u64-le.js +24 -0
  118. package/esm/script/write-u8-le.js +8 -0
  119. package/esm/script/write-varint.js +46 -0
  120. package/esm/transaction/index.js +5 -0
  121. package/esm/transaction/input/index.js +33 -0
  122. package/{lib → esm}/transaction/input/input.js +132 -90
  123. package/esm/transaction/input/multisig.js +335 -0
  124. package/esm/transaction/input/publickey.js +108 -0
  125. package/esm/transaction/input/publickeyhash.js +124 -0
  126. package/esm/transaction/output.js +316 -0
  127. package/{lib → esm}/transaction/sighash.js +42 -22
  128. package/esm/transaction/signature.js +120 -0
  129. package/{lib → esm}/transaction/transaction.js +522 -163
  130. package/esm/transaction/unspentoutput.js +112 -0
  131. package/esm/util/_.js +47 -0
  132. package/esm/util/derivation.js +53 -0
  133. package/esm/util/index.js +12 -0
  134. package/esm/util/js.js +95 -0
  135. package/esm/util/preconditions.js +33 -0
  136. package/fixup.cjs +17 -0
  137. package/package.json +40 -26
  138. package/test/{address.js → address.cjs} +14 -43
  139. package/test/block/{block.js → block.cjs} +3 -5
  140. package/test/block/{blockheader.js → blockheader.cjs} +2 -2
  141. package/test/block/{merklebloack.js → merklebloack.cjs} +2 -2
  142. package/test/crypto/{ecdsa.js → ecdsa.cjs} +9 -9
  143. package/test/crypto/{hash.browser.js → hash.browser.cjs} +2 -1
  144. package/test/crypto/{signature.js → signature.cjs} +2 -2
  145. package/test/data/bitcoind/script_tests.json +5 -5
  146. package/test/{hashCache.js → hashCache.cjs} +2 -1
  147. package/test/{hdkeys.js → hdkeys.cjs} +4 -2
  148. package/test/{hdprivatekey.js → hdprivatekey.cjs} +7 -6
  149. package/test/{hdpublickey.js → hdpublickey.cjs} +2 -7
  150. package/test/mnemonic/{pbkdf2.test.js → pbkdf2.test.cjs} +2 -2
  151. package/test/{networks.js → networks.cjs} +12 -31
  152. package/test/{publickey.js → publickey.cjs} +2 -2
  153. package/test/script/{interpreter.js → interpreter.cjs} +5 -5
  154. package/test/script/{script.js → script.cjs} +8 -2
  155. package/test/transaction/{deserialize.js → deserialize.cjs} +2 -2
  156. package/test/transaction/input/{input.js → input.cjs} +1 -1
  157. package/test/transaction/input/{multisig.js → multisig.cjs} +2 -1
  158. package/test/transaction/input/{publickeyhash.js → publickeyhash.cjs} +1 -1
  159. package/test/transaction/{sighash.js → sighash.cjs} +1 -1
  160. package/test/transaction/{transaction.js → transaction.cjs} +2 -2
  161. package/tsconfig.json +13 -0
  162. package/types/address.d.cts +252 -0
  163. package/types/block/block.d.cts +139 -0
  164. package/types/block/blockheader.d.cts +125 -0
  165. package/types/block/index.d.cts +2 -0
  166. package/types/block/merkleblock.d.cts +95 -0
  167. package/types/bn.d.cts +202 -0
  168. package/types/crypto/bn.d.cts +2 -0
  169. package/types/crypto/ecdsa.d.cts +187 -0
  170. package/types/crypto/hash.d.cts +118 -0
  171. package/types/crypto/index.d.cts +7 -0
  172. package/types/crypto/point.d.cts +134 -0
  173. package/types/crypto/random.d.cts +13 -0
  174. package/types/crypto/signature.d.cts +160 -0
  175. package/types/encoding/base58.d.cts +106 -0
  176. package/types/encoding/base58check.d.cts +107 -0
  177. package/types/encoding/bufferreader.d.cts +164 -0
  178. package/types/encoding/bufferwriter.d.cts +126 -0
  179. package/types/encoding/decode-asm.d.cts +2 -0
  180. package/types/encoding/decode-hex.d.cts +2 -0
  181. package/types/encoding/decode-script-chunks.d.cts +14 -0
  182. package/types/encoding/encode-hex.d.cts +2 -0
  183. package/types/encoding/index.d.cts +6 -0
  184. package/types/encoding/is-hex.d.cts +2 -0
  185. package/types/encoding/varint.d.cts +66 -0
  186. package/types/errors/index.d.cts +4 -0
  187. package/types/errors/spec.d.cts +22 -0
  188. package/types/hash-cache.d.cts +65 -0
  189. package/types/hdprivatekey.d.cts +281 -0
  190. package/types/hdpublickey.d.cts +240 -0
  191. package/types/index.d.cts +26 -0
  192. package/types/interpreter/index.d.cts +2 -0
  193. package/types/interpreter/interpreter.d.cts +228 -0
  194. package/types/interpreter/stack.d.cts +35 -0
  195. package/types/message/message.d.cts +110 -0
  196. package/types/mnemonic/index.d.cts +2 -0
  197. package/types/mnemonic/mnemonic.d.cts +171 -0
  198. package/types/mnemonic/pbkdf2.d.cts +14 -0
  199. package/types/mnemonic/words/chinese.d.cts +2 -0
  200. package/types/mnemonic/words/english.d.cts +2 -0
  201. package/types/mnemonic/words/french.d.cts +2 -0
  202. package/types/mnemonic/words/index.d.cts +22 -0
  203. package/types/mnemonic/words/italian.d.cts +2 -0
  204. package/types/mnemonic/words/japanese.d.cts +2 -0
  205. package/types/mnemonic/words/spanish.d.cts +2 -0
  206. package/types/network.d.cts +11 -0
  207. package/types/networks.d.cts +76 -0
  208. package/types/opcode.d.cts +93 -0
  209. package/types/privatekey.d.cts +169 -0
  210. package/types/publickey.d.cts +202 -0
  211. package/types/script/index.d.cts +2 -0
  212. package/types/script/script.d.cts +449 -0
  213. package/types/script/write-i32-le.d.cts +2 -0
  214. package/types/script/write-push-data.d.cts +2 -0
  215. package/types/script/write-u16-le.d.cts +2 -0
  216. package/types/script/write-u32-le.d.cts +2 -0
  217. package/types/script/write-u64-le.d.cts +2 -0
  218. package/types/script/write-u8-le.d.cts +2 -0
  219. package/types/script/write-varint.d.cts +2 -0
  220. package/types/transaction/index.d.cts +2 -0
  221. package/types/transaction/input/index.d.cts +2 -0
  222. package/types/transaction/input/input.d.cts +178 -0
  223. package/types/transaction/input/multisig.d.cts +127 -0
  224. package/types/transaction/input/publickey.d.cts +44 -0
  225. package/types/transaction/input/publickeyhash.d.cts +45 -0
  226. package/types/transaction/output.d.cts +118 -0
  227. package/types/transaction/sighash.d.cts +61 -0
  228. package/types/transaction/signature.d.cts +43 -0
  229. package/types/transaction/transaction.d.cts +716 -0
  230. package/types/transaction/unspentoutput.d.cts +83 -0
  231. package/types/util/_.d.cts +26 -0
  232. package/types/util/derivation.d.cts +21 -0
  233. package/types/util/index.d.cts +5 -0
  234. package/types/util/js.d.cts +50 -0
  235. package/types/util/preconditions.d.cts +3 -0
  236. package/index.d.ts +0 -1541
  237. package/index.js +0 -74
  238. package/lib/block/index.js +0 -4
  239. package/lib/bn.js +0 -3423
  240. package/lib/crypto/hash.js +0 -2
  241. package/lib/crypto/random.browser.js +0 -28
  242. package/lib/crypto/random.js +0 -2
  243. package/lib/crypto/random.node.js +0 -11
  244. package/lib/encoding/base58check.js +0 -121
  245. package/lib/encoding/bufferreader.js +0 -212
  246. package/lib/encoding/bufferwriter.js +0 -140
  247. package/lib/encoding/varint.js +0 -75
  248. package/lib/hash-cache.js +0 -50
  249. package/lib/mnemonic/pbkdf2.js +0 -2
  250. package/lib/mnemonic/words/index.js +0 -8
  251. package/lib/script/index.js +0 -5
  252. package/lib/transaction/index.js +0 -7
  253. package/lib/transaction/input/index.js +0 -5
  254. package/lib/util/js.js +0 -90
  255. /package/{lib/encoding/decode-script-chunks.js → cjs/encoding/decode-script-chunks.cjs} +0 -0
  256. /package/{lib/encoding/encode-hex.js → cjs/encoding/encode-hex.cjs} +0 -0
  257. /package/{lib/encoding/is-hex.js → cjs/encoding/is-hex.cjs} +0 -0
  258. /package/{lib/mnemonic/words/chinese.js → cjs/mnemonic/words/chinese.cjs} +0 -0
  259. /package/{lib/mnemonic/words/english.js → cjs/mnemonic/words/english.cjs} +0 -0
  260. /package/{lib/mnemonic/words/french.js → cjs/mnemonic/words/french.cjs} +0 -0
  261. /package/{lib/mnemonic/words/italian.js → cjs/mnemonic/words/italian.cjs} +0 -0
  262. /package/{lib/mnemonic/words/japanese.js → cjs/mnemonic/words/japanese.cjs} +0 -0
  263. /package/{lib/mnemonic/words/spanish.js → cjs/mnemonic/words/spanish.cjs} +0 -0
  264. /package/{lib/script/write-i32-le.js → cjs/script/write-i32-le.cjs} +0 -0
  265. /package/{lib/script/write-push-data.js → cjs/script/write-push-data.cjs} +0 -0
  266. /package/{lib/script/write-u16-le.js → cjs/script/write-u16-le.cjs} +0 -0
  267. /package/{lib/script/write-u32-le.js → cjs/script/write-u32-le.cjs} +0 -0
  268. /package/{lib/script/write-u64-le.js → cjs/script/write-u64-le.cjs} +0 -0
  269. /package/{lib/script/write-u8-le.js → cjs/script/write-u8-le.cjs} +0 -0
  270. /package/{lib/script/write-varint.js → cjs/script/write-varint.cjs} +0 -0
  271. /package/{lib/util/_.js → cjs/util/_.cjs} +0 -0
  272. /package/test/crypto/{bn.js → bn.cjs} +0 -0
  273. /package/test/crypto/{hash.js → hash.cjs} +0 -0
  274. /package/test/crypto/{point.js → point.cjs} +0 -0
  275. /package/test/crypto/{random.js → random.cjs} +0 -0
  276. /package/test/data/{blk86756-testnet.js → blk86756-testnet.cjs} +0 -0
  277. /package/test/data/{merkleblocks.js → merkleblocks.cjs} +0 -0
  278. /package/test/encoding/{base58.js → base58.cjs} +0 -0
  279. /package/test/encoding/{base58check.js → base58check.cjs} +0 -0
  280. /package/test/encoding/{bufferreader.js → bufferreader.cjs} +0 -0
  281. /package/test/encoding/{bufferwriter.js → bufferwriter.cjs} +0 -0
  282. /package/test/encoding/{varint.js → varint.cjs} +0 -0
  283. /package/test/{index.js → index.cjs} +0 -0
  284. /package/test/message/{message.js → message.cjs} +0 -0
  285. /package/test/mnemonic/{mnemonic.js → mnemonic.cjs} +0 -0
  286. /package/test/{opcode.js → opcode.cjs} +0 -0
  287. /package/test/{privatekey.js → privatekey.cjs} +0 -0
  288. /package/test/transaction/input/{publickey.js → publickey.cjs} +0 -0
  289. /package/test/transaction/{output.js → output.cjs} +0 -0
  290. /package/test/transaction/{signature.js → signature.cjs} +0 -0
  291. /package/test/transaction/{unspentoutput.js → unspentoutput.cjs} +0 -0
  292. /package/test/util/{js.js → js.cjs} +0 -0
  293. /package/test/util/{preconditions.js → preconditions.cjs} +0 -0
@@ -1,14 +1,15 @@
1
1
  'use strict';
2
2
 
3
- var _ = require('../util/_');
4
-
5
- var Script = require('./script');
6
- var Opcode = require('../opcode');
7
- var BN = require('../crypto/bn');
8
- var Hash = require('../crypto/hash');
9
- var Signature = require('../crypto/signature');
10
- var PublicKey = require('../publickey');
11
- var Stack = require('./stack');
3
+ import _ from '../util/_.js';
4
+ import Script from '../script/index.js';
5
+ import Opcode from '../opcode.js';
6
+ import BN from '../crypto/bn.js';
7
+ import Hash from '../crypto/hash.js';
8
+ import Signature from '../crypto/signature.js';
9
+ import PublicKey from '../publickey.js';
10
+ import Stack from './stack.js';
11
+ import Transaction from '../transaction/index.js';
12
+
12
13
  /**
13
14
  * Bitcoin transactions contain scripts. Each input has a script called the
14
15
  * scriptSig, and each output has a script called the scriptPubkey. To validate
@@ -18,8 +19,11 @@ var Stack = require('./stack');
18
19
  *
19
20
  * The primary way to use this class is via the verify function.
20
21
  * e.g., Interpreter().verify( ... );
22
+ * @constructor
23
+ * @param {Object} [obj] - Optional object to initialize the interpreter with.
24
+ * @returns {Interpreter} A new Interpreter instance.
21
25
  */
22
- var Interpreter = function Interpreter(obj) {
26
+ function Interpreter(obj) {
23
27
  if (!(this instanceof Interpreter)) {
24
28
  return new Interpreter(obj);
25
29
  }
@@ -29,7 +33,7 @@ var Interpreter = function Interpreter(obj) {
29
33
  } else {
30
34
  this.initialize();
31
35
  }
32
- };
36
+ }
33
37
 
34
38
  /**
35
39
  * Verifies a Script by executing it and returns true if it is valid.
@@ -53,7 +57,6 @@ Interpreter.prototype.verify = function (
53
57
  flags,
54
58
  satoshisBN,
55
59
  ) {
56
- var Transaction = require('../transaction');
57
60
 
58
61
  if (_.isUndefined(tx)) {
59
62
  tx = new Transaction();
@@ -113,9 +116,13 @@ Interpreter.prototype.verify = function (
113
116
  return true;
114
117
  };
115
118
 
116
- module.exports = Interpreter;
117
119
 
118
- Interpreter.prototype.initialize = function (obj) {
120
+ /**
121
+ * Initializes the interpreter instance with default values.
122
+ * Sets up empty stacks, resets program counter and execution flags,
123
+ * and initializes state tracking variables for script execution.
124
+ */
125
+ Interpreter.prototype.initialize = function () {
119
126
  this.stack = new Stack([]);
120
127
  this.altstack = new Stack([]);
121
128
  this.pc = 0;
@@ -131,6 +138,23 @@ Interpreter.prototype.initialize = function (obj) {
131
138
  this.returned = false;
132
139
  };
133
140
 
141
+ /**
142
+ * Updates the interpreter's state with provided values.
143
+ * @param {Object} obj - Object containing properties to update
144
+ * @param {Buffer} [obj.script] - Script buffer
145
+ * @param {Object} [obj.tx] - Transaction object
146
+ * @param {boolean} [obj.nin] - Non-input flag
147
+ * @param {BN} [obj.satoshisBN] - Satoshis as BN.js instance
148
+ * @param {Array} [obj.stack] - Main stack
149
+ * @param {Array} [obj.altstack] - Alternate stack
150
+ * @param {number} [obj.pc] - Program counter
151
+ * @param {number} [obj.pbegincodehash] - Begin code hash position
152
+ * @param {number} [obj.nOpCount] - Operation count
153
+ * @param {Array} [obj.vfExec] - Execution flags
154
+ * @param {Array} [obj.vfElse] - Else flags
155
+ * @param {string} [obj.errstr] - Error string
156
+ * @param {number} [obj.flags] - Interpreter flags
157
+ */
134
158
  Interpreter.prototype.set = function (obj) {
135
159
  this.script = obj.script || this.script;
136
160
  this.tx = obj.tx || this.tx;
@@ -148,8 +172,12 @@ Interpreter.prototype.set = function (obj) {
148
172
  this.flags = typeof obj.flags !== 'undefined' ? obj.flags : this.flags;
149
173
  };
150
174
 
175
+ /**
176
+ * Returns a subset of the script starting from the most recent OP_CODESEPARATOR.
177
+ * @returns {Script} A new Script instance containing the sliced chunks.
178
+ */
151
179
  Interpreter.prototype.subscript = function () {
152
- // Subset of script starting at the most recent codeseparator
180
+ // Subset of script starting at the most recent codeseparator
153
181
  // CScript scriptCode(pbegincodehash, pend);
154
182
  return Script.fromChunks(this.script.chunks.slice(this.pbegincodehash));
155
183
  };
@@ -157,79 +185,133 @@ Interpreter.prototype.subscript = function () {
157
185
  Interpreter.getTrue = () => Buffer.from([1]);
158
186
  Interpreter.getFalse = () => Buffer.from([]);
159
187
 
160
- Interpreter.MAX_SCRIPT_ELEMENT_SIZE = 520;
188
+ /**
189
+ * Maximum allowed size for script elements in the interpreter.
190
+ * Set to the maximum safe integer value by default.
191
+ */
192
+ Interpreter.MAX_SCRIPT_ELEMENT_SIZE = Number.MAX_SAFE_INTEGER;
193
+ /**
194
+ * The maximum allowed size for an element in the interpreter.
195
+ * @type {number}
196
+ */
161
197
  Interpreter.MAXIMUM_ELEMENT_SIZE = Number.MAX_SAFE_INTEGER;
162
198
 
199
+ /**
200
+ * The threshold value used to distinguish between block height and timestamp in locktime.
201
+ * Values below this threshold are interpreted as block numbers, while values equal or above are treated as timestamps.
202
+ */
163
203
  Interpreter.LOCKTIME_THRESHOLD = 500000000;
204
+ /**
205
+ * The locktime threshold value as a BN.js BigNumber instance.
206
+ * @type {BN}
207
+ */
164
208
  Interpreter.LOCKTIME_THRESHOLD_BN = new BN(Interpreter.LOCKTIME_THRESHOLD);
165
209
 
166
- // flags taken from bitcoind
167
- // bitcoind commit: b5d1b1092998bc95313856d535c632ea5a8f9104
210
+ /**
211
+ * Flag indicating no script verification rules should be enforced.
212
+ * flags taken from bitcoind
213
+ * bitcoind commit: b5d1b1092998bc95313856d535c632ea5a8f9104
214
+ * @constant {number}
215
+ */
168
216
  Interpreter.SCRIPT_VERIFY_NONE = 0;
169
217
 
170
- // Passing a non-strict-DER signature or one with undefined hashtype to a checksig operation causes script failure.
171
- // Passing a pubkey that is not (0x04 + 64 bytes) or (0x02 or 0x03 + 32 bytes) to checksig causes that pubkey to be
172
- // skipped (not softfork safe: this flag can widen the validity of OP_CHECKSIG OP_NOT).
218
+ /**
219
+ * Passing a non-strict-DER signature or one with undefined hashtype to a checksig operation causes script failure.
220
+ * Passing a pubkey that is not (0x04 + 64 bytes) or (0x02 or 0x03 + 32 bytes) to checksig causes that pubkey to be
221
+ * skipped (not softfork safe: this flag can widen the validity of OP_CHECKSIG OP_NOT).
222
+ */
173
223
  Interpreter.SCRIPT_VERIFY_STRICTENC = 1 << 1;
174
224
 
175
- // Passing a non-strict-DER signature to a checksig operation causes script failure (softfork safe, BIP62 rule 1)
225
+
226
+ /**
227
+ * Passing a non-strict-DER signature to a checksig operation causes script failure (softfork safe, BIP62 rule 1)
228
+ */
176
229
  Interpreter.SCRIPT_VERIFY_DERSIG = 1 << 2;
177
230
 
178
- // Passing a non-strict-DER signature or one with S > order/2 to a checksig operation causes script failure
179
- // (softfork safe, BIP62 rule 5).
231
+ /**
232
+ * Passing a non-strict-DER signature or one with S > order/2 to a checksig operation causes script failure
233
+ * (softfork safe, BIP62 rule 5).
234
+ */
180
235
  Interpreter.SCRIPT_VERIFY_LOW_S = 1 << 3;
181
236
 
182
- // verify dummy stack item consumed by CHECKMULTISIG is of zero-length (softfork safe, BIP62 rule 7).
237
+ /**
238
+ * verify dummy stack item consumed by CHECKMULTISIG is of zero-length (softfork safe, BIP62 rule 7).
239
+ */
183
240
  Interpreter.SCRIPT_VERIFY_NULLDUMMY = 1 << 4;
184
241
 
185
- // Using a non-push operator in the scriptSig causes script failure (softfork safe, BIP62 rule 2).
242
+ /**
243
+ * Using a non-push operator in the scriptSig causes script failure (softfork safe, BIP62 rule 2).
244
+ */
186
245
  Interpreter.SCRIPT_VERIFY_SIGPUSHONLY = 1 << 5;
187
246
 
188
- // Require minimal encodings for all push operations (OP_0... OP_16, OP_1NEGATE where possible, direct
189
- // pushes up to 75 bytes, OP_PUSHDATA up to 255 bytes, OP_PUSHDATA2 for anything larger). Evaluating
190
- // any other push causes the script to fail (BIP62 rule 3).
191
- // In addition, whenever a stack element is interpreted as a number, it must be of minimal length (BIP62 rule 4).
192
- // (softfork safe)
247
+ /**
248
+ * Require minimal encodings for all push operations (OP_0... OP_16, OP_1NEGATE where possible, direct
249
+ * pushes up to 75 bytes, OP_PUSHDATA up to 255 bytes, OP_PUSHDATA2 for anything larger). Evaluating
250
+ * any other push causes the script to fail (BIP62 rule 3).
251
+ * In addition, whenever a stack element is interpreted as a number, it must be of minimal length (BIP62 rule 4).
252
+ * (softfork safe)
253
+ *
254
+ */
193
255
  Interpreter.SCRIPT_VERIFY_MINIMALDATA = 1 << 6;
194
256
 
195
- // Discourage use of NOPs reserved for upgrades (NOP1-10)
196
- //
197
- // Provided so that nodes can avoid accepting or mining transactions
198
- // containing executed NOP's whose meaning may change after a soft-fork,
199
- // thus rendering the script invalid; with this flag set executing
200
- // discouraged NOPs fails the script. This verification flag will never be
201
- // a mandatory flag applied to scripts in a block. NOPs that are not
202
- // executed, e.g. within an unexecuted IF ENDIF block, are *not* rejected.
257
+ /**
258
+ * Discourage use of NOPs reserved for upgrades (NOP1-10)
259
+ *
260
+ * Provided so that nodes can avoid accepting or mining transactions
261
+ * containing executed NOP's whose meaning may change after a soft-fork,
262
+ * thus rendering the script invalid; with this flag set executing
263
+ * discouraged NOPs fails the script. This verification flag will never be
264
+ * a mandatory flag applied to scripts in a block. NOPs that are not
265
+ * executed, e.g. within an unexecuted IF ENDIF block, are *not* rejected.
266
+ */
203
267
  Interpreter.SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS = 1 << 7;
204
268
 
205
269
 
206
- // CLTV See BIP65 for details.
270
+
271
+ /**
272
+ * CLTV See BIP65 for details.
273
+ */
207
274
  Interpreter.SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY = 1 << 9;
208
275
 
209
- // support CHECKSEQUENCEVERIFY opcode
210
- //
211
- // See BIP112 for details
276
+ /**
277
+ * support CHECKSEQUENCEVERIFY opcode
278
+ * See BIP112 for details
279
+ */
212
280
  Interpreter.SCRIPT_VERIFY_CHECKSEQUENCEVERIFY = 1 << 10;
213
281
 
214
- // Signature(s) must be empty vector if an CHECK(MULTI)SIG operation failed
215
- //
282
+
283
+ /**
284
+ * Flag indicating that script verification should fail if a null input is encountered.
285
+ * This is a bitmask value (1 << 14) used in script verification rules.
286
+ */
216
287
  Interpreter.SCRIPT_VERIFY_NULLFAIL = 1 << 14;
217
288
 
218
- // Public keys in scripts must be compressed
289
+ /**
290
+ * Flag indicating that compressed public key type should be verified in scripts.
291
+ * This is a bit flag used in script verification (1 << 15).
292
+ * @type {number}
293
+ */
219
294
  Interpreter.SCRIPT_VERIFY_COMPRESSED_PUBKEYTYPE = 1 << 15;
220
295
 
221
- // Enable new opcodes.
222
- //
296
+
297
+ /**
298
+ * Enable new opcodes.
299
+ * @type {number}
300
+ */
223
301
  Interpreter.SCRIPT_ENABLE_MONOLITH_OPCODES = 1 << 18;
224
302
 
225
- // Are the Magnetic upgrade opcodes enabled?
226
- //
303
+
304
+ /**
305
+ * Are the Magnetic upgrade opcodes enabled?
306
+ * @type {number}
307
+ */
227
308
  Interpreter.SCRIPT_ENABLE_MAGNETIC_OPCODES = 1 << 19;
228
309
 
229
310
  /* Below flags apply in the context of BIP 68 */
230
311
  /**
231
312
  * If this flag set, CTxIn::nSequence is NOT interpreted as a relative
232
313
  * lock-time.
314
+ * @type {number}
233
315
  */
234
316
  Interpreter.SEQUENCE_LOCKTIME_DISABLE_FLAG = 1 << 31;
235
317
 
@@ -237,19 +319,34 @@ Interpreter.SEQUENCE_LOCKTIME_DISABLE_FLAG = 1 << 31;
237
319
  * If CTxIn::nSequence encodes a relative lock-time and this flag is set,
238
320
  * the relative lock-time has units of 512 seconds, otherwise it specifies
239
321
  * blocks with a granularity of 1.
322
+ * @type {number}
240
323
  */
241
324
  Interpreter.SEQUENCE_LOCKTIME_TYPE_FLAG = 1 << 22;
242
325
 
243
326
  /**
244
327
  * If CTxIn::nSequence encodes a relative lock-time, this mask is applied to
245
328
  * extract that lock-time from the sequence field.
329
+ * @type {number}
246
330
  */
247
331
  Interpreter.SEQUENCE_LOCKTIME_MASK = 0x0000ffff;
248
332
 
333
+ /**
334
+ * Maximum allowed script size for the interpreter, set to the largest safe integer in JavaScript.
335
+ * @type {number}
336
+ */
249
337
  Interpreter.MAX_SCRIPT_SIZE = Number.MAX_SAFE_INTEGER;
250
338
 
339
+ /**
340
+ * Maximum number of opcodes that can be executed before stopping the interpreter.
341
+ * Defaults to Number.MAX_SAFE_INTEGER (effectively unlimited).
342
+ * @type {number}
343
+ */
251
344
  Interpreter.MAX_OPCODE_COUNT = Number.MAX_SAFE_INTEGER;
252
345
 
346
+ /**
347
+ * Default flags used by the interpreter.
348
+ * @type {number}
349
+ */
253
350
  Interpreter.DEFAULT_FLAGS =
254
351
  Interpreter.SCRIPT_ENABLE_MAGNETIC_OPCODES |
255
352
  Interpreter.SCRIPT_ENABLE_MONOLITH_OPCODES |
@@ -263,6 +360,14 @@ Interpreter.DEFAULT_FLAGS =
263
360
  Interpreter.SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY |
264
361
  Interpreter.SCRIPT_VERIFY_CHECKSEQUENCEVERIFY;
265
362
 
363
+
364
+ /**
365
+ * Casts a buffer to a boolean value.
366
+ * Returns true if any byte in the buffer is non-zero (except for the special case of negative zero).
367
+ * Returns false if all bytes are zero or if the last byte is 0x80 (negative zero case).
368
+ * @param {Buffer} buf - The input buffer to check
369
+ * @returns {boolean} The boolean representation of the buffer
370
+ */
266
371
  Interpreter.castToBool = function (buf) {
267
372
  for (var i = 0; i < buf.length; i++) {
268
373
  if (buf[i] !== 0) {
@@ -276,8 +381,15 @@ Interpreter.castToBool = function (buf) {
276
381
  return false;
277
382
  };
278
383
 
384
+
279
385
  /**
280
- * Translated from bitcoind's CheckSignatureEncoding
386
+ * Checks if a signature encoding is valid according to the interpreter's flags.
387
+ * - For empty signatures: always valid (used for compact invalid signatures in CHECK(MULTI)SIG)
388
+ * - With DERSIG/STRICTENC flags: validates DER encoding and strict encoding rules
389
+ * - With LOW_S flag: ensures signature uses low S value
390
+ * - With STRICTENC flag: validates defined hash type
391
+ * @param {Buffer} buf - The signature buffer to validate
392
+ * @returns {boolean} True if valid, false otherwise (sets errstr on failure)
281
393
  */
282
394
  Interpreter.prototype.checkSignatureEncoding = function (buf) {
283
395
  var sig;
@@ -315,8 +427,12 @@ Interpreter.prototype.checkSignatureEncoding = function (buf) {
315
427
  return true;
316
428
  };
317
429
 
430
+
318
431
  /**
319
- * Translated from bitcoind's CheckPubKeyEncoding
432
+ * Checks if the provided public key buffer is valid according to strict encoding rules.
433
+ * Sets an error message if validation fails under SCRIPT_VERIFY_STRICTENC flag.
434
+ * @param {Buffer} buf - The public key buffer to validate.
435
+ * @returns {boolean} True if valid, false otherwise (with error string set).
320
436
  */
321
437
  Interpreter.prototype.checkPubkeyEncoding = function (buf) {
322
438
  if ((this.flags & Interpreter.SCRIPT_VERIFY_STRICTENC) !== 0 && !PublicKey.isValid(buf)) {
@@ -327,12 +443,12 @@ Interpreter.prototype.checkPubkeyEncoding = function (buf) {
327
443
  };
328
444
 
329
445
  /**
330
- *
331
- * Check the buffer is minimally encoded (see https://github.com/bitcoincashorg/spec/blob/master/may-2018-reenabled-opcodes.md#op_bin2num)
332
- *
333
- *
446
+ * Checks if a buffer is minimally encoded (see https://github.com/bitcoincashorg/spec/blob/master/may-2018-reenabled-opcodes.md#op_bin2num) as a number.
447
+ * @param {Buffer} buf - The buffer to check.
448
+ * @param {number} [nMaxNumSize=Interpreter.MAXIMUM_ELEMENT_SIZE] - Maximum allowed size for the buffer.
449
+ * @returns {boolean} True if the buffer is minimally encoded, false otherwise.
450
+ * @private
334
451
  */
335
-
336
452
  Interpreter._isMinimallyEncoded = function (buf, nMaxNumSize) {
337
453
  nMaxNumSize = nMaxNumSize || Interpreter.MAXIMUM_ELEMENT_SIZE;
338
454
  if (buf.length > nMaxNumSize) {
@@ -360,11 +476,18 @@ Interpreter._isMinimallyEncoded = function (buf, nMaxNumSize) {
360
476
  return true;
361
477
  };
362
478
 
479
+
363
480
  /**
364
- *
365
- * minimally encode the buffer content
366
- *
367
- * @param {number} nMaxNumSize (max allowed size)
481
+ * Minimally encodes a buffer by removing unnecessary trailing zeros.
482
+ *
483
+ * This function implements minimal encoding rules for script numbers:
484
+ * - Empty buffer remains empty
485
+ * - Last byte must not be 0x00 or 0x80 unless necessary
486
+ * - Single zero byte encodes as empty buffer
487
+ * - Preserves sign bit when trimming
488
+ *
489
+ * @param {Buffer} buf - The input buffer to encode
490
+ * @returns {Buffer} Minimally encoded buffer (may be empty)
368
491
  */
369
492
  Interpreter._minimallyEncode = function (buf) {
370
493
  if (buf.length === 0) {
@@ -409,13 +532,19 @@ Interpreter._minimallyEncode = function (buf) {
409
532
  return Buffer.from('');
410
533
  };
411
534
 
535
+
412
536
  /**
413
- * Based on bitcoind's EvalScript function, with the inner loop moved to
414
- * Interpreter.prototype.step()
537
+ * Evaluates a script by executing each opcode step-by-step.
538
+ * Performs size checks on the script and stacks before execution.
539
+ *
540
+ * Based on bitcoind's EvalScript function, with the inner loop moved to `Interpreter.prototype.step()`
415
541
  * bitcoind commit: b5d1b1092998bc95313856d535c632ea5a8f9104
542
+ * @param {string} scriptType - The type of script being evaluated
543
+ * @returns {boolean} True if evaluation succeeds, false if any error occurs
544
+ * @throws {Error} If an unknown error occurs during evaluation
416
545
  */
417
546
  Interpreter.prototype.evaluate = function (scriptType) {
418
- // TODO: script size should be configurable. no magic numbers
547
+ // TODO: script size should be configurable. no magic numbers
419
548
  if (this.script.toBuffer().length > Interpreter.MAX_SCRIPT_SIZE) {
420
549
  this.errstr = 'SCRIPT_ERR_SCRIPT_SIZE';
421
550
  return false;
@@ -457,6 +586,12 @@ Interpreter.prototype.evaluate = function (scriptType) {
457
586
  return true;
458
587
  };
459
588
 
589
+ /**
590
+ * Handles step callback execution for the interpreter.
591
+ * @private
592
+ * @param {Object} thisStep - The current step object to pass to the listener
593
+ * @throws {Error} Logs any errors that occur during callback execution
594
+ */
460
595
  Interpreter.prototype._callbackStep = function (thisStep) {
461
596
  if (typeof this.stepListener === 'function') {
462
597
  try {
@@ -467,9 +602,14 @@ Interpreter.prototype._callbackStep = function (thisStep) {
467
602
  }
468
603
  };
469
604
 
605
+
470
606
  /**
471
- * call to update stackvar
472
- * @param {*} stack
607
+ * Handles stack callbacks by invoking the registered stack listener function.
608
+ * If an error occurs during callback execution, logs the error along with PC and opcode details.
609
+ * @param {Stack} stack - The current execution stack
610
+ * @param {number} pc - Program counter value
611
+ * @param {string} scriptType - Type of script being executed
612
+ * @private
473
613
  */
474
614
  Interpreter.prototype._callbackStack = function (stack, pc, scriptType) {
475
615
  if (typeof this.stackListener === 'function') {
@@ -603,9 +743,19 @@ function padBufferToSize(buf, len) {
603
743
  return b;
604
744
  }
605
745
 
746
+
606
747
  /**
748
+ * Executes a single step in the script interpreter.
749
+ *
750
+ * This method processes the current opcode in the script, performs the corresponding operation,
751
+ * and updates the stack or interpreter state accordingly. It handles various opcode types including
752
+ * stack operations, arithmetic, bitwise logic, cryptographic operations, and control flow.
753
+ *
607
754
  * Based on the inner loop of bitcoind's EvalScript function
608
755
  * bitcoind commit: b5d1b1092998bc95313856d535c632ea5a8f9104
756
+ * @param {string} scriptType - The type of script being executed (e.g., scriptPubkey, scriptSig).
757
+ * @returns {boolean} Returns `true` if the step executed successfully, or `false` if an error occurred.
758
+ * Errors are stored in `this.errstr`.
609
759
  */
610
760
  Interpreter.prototype.step = function (scriptType) {
611
761
  var self = this;
@@ -1832,3 +1982,6 @@ Interpreter.prototype.step = function (scriptType) {
1832
1982
 
1833
1983
  return true;
1834
1984
  };
1985
+
1986
+
1987
+ export default Interpreter;
@@ -0,0 +1,116 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Represents a stack structure with optional variable stack support.
5
+ * @constructor
6
+ * @param {Array} rawstack - The initial stack array
7
+ * @param {Array} [varStack] - Optional variable stack array
8
+ */
9
+ function Stack(rawstack, varStack) {
10
+ this.stack = rawstack;
11
+ this.varStack = varStack || [];
12
+ }
13
+
14
+
15
+ Stack.prototype.pushVar = function (varName) {
16
+ this.varStack.push(varName || '$tmp');
17
+ };
18
+
19
+ Stack.prototype.popVar = function () {
20
+ this.varStack.pop();
21
+ };
22
+
23
+ Stack.prototype.push = function (n, varName) {
24
+ this.pushVar(varName);
25
+ this.stack.push(n);
26
+ this.checkConsistency();
27
+ };
28
+
29
+ Stack.prototype.pop = function () {
30
+ this.popVar();
31
+ let top = this.stack.pop();
32
+ this.checkConsistency();
33
+ return top;
34
+ };
35
+
36
+ Stack.prototype.updateTopVars = function (vars) {
37
+ if (vars.length > this.varStack.length) {
38
+ throw new Error(
39
+ `updateTopVars fail, stack: ${this.stack.length}, varStack: ${this.varStack.length}, vars:${vars.length}`,
40
+ );
41
+ }
42
+ vars = vars.reverse();
43
+ this.varStack.splice(this.varStack.length - vars.length, vars.length, ...vars);
44
+ };
45
+
46
+ Stack.prototype.stacktop = function (i) {
47
+ return this.stack[this.stack.length + i];
48
+ };
49
+
50
+ Stack.prototype.vartop = function (i) {
51
+ return this.varStack[this.varStack.length + i];
52
+ };
53
+
54
+ Stack.prototype.slice = function (start, end) {
55
+ return this.stack.slice(start, end);
56
+ };
57
+
58
+ Stack.prototype.splice = function (start, deleteCount, ...items) {
59
+ this.varStack.splice(start, deleteCount, ...items);
60
+ return this.stack.splice(start, deleteCount, ...items);
61
+ };
62
+
63
+ Stack.prototype.write = function (i, value) {
64
+ this.stack[this.stack.length + i] = value;
65
+ };
66
+
67
+ Stack.prototype.copy = function () {
68
+ return new Stack(this.stack.slice() || [], this.varStack.slice() || []);
69
+ };
70
+
71
+ function bytesToHexString(bytearray) {
72
+ return bytearray.reduce(function (o, c) {
73
+ o += ('0' + (c & 0xff).toString(16)).slice(-2);
74
+ return o;
75
+ }, '');
76
+ }
77
+
78
+ Stack.prototype.printVarStack = function () {
79
+ let array = this.varStack.map((v, i) => ({
80
+ name: v,
81
+ value: bytesToHexString(this.rawstack[i].data),
82
+ }));
83
+ console.log(JSON.stringify(array, null, 4));
84
+ };
85
+
86
+ Stack.prototype.checkConsistency = function () {
87
+ if (this.stack.length !== this.varStack.length) {
88
+ this.printVarStack();
89
+ throw new Error(
90
+ `checkConsistency fail, stack: ${this.stack.length}, varStack:${this.varStack.length}`,
91
+ );
92
+ }
93
+ };
94
+
95
+ Stack.prototype.checkConsistencyWithVars = function (varStack) {
96
+ if (this.stack.length < varStack.length) {
97
+ this.printVarStack();
98
+ throw new Error(
99
+ `checkConsistencyWithVars fail, stack: ${this.stack.length}, varStack:${varStack.length}`,
100
+ );
101
+ }
102
+ };
103
+
104
+ Object.defineProperty(Stack.prototype, 'length', {
105
+ get: function () {
106
+ return this.stack.length;
107
+ },
108
+ });
109
+
110
+ Object.defineProperty(Stack.prototype, 'rawstack', {
111
+ get: function () {
112
+ return this.stack;
113
+ },
114
+ });
115
+
116
+ export default Stack;