diff --git a/index.js b/index.js index 85dba8e..6535b58 100644 --- a/index.js +++ b/index.js @@ -3,12 +3,24 @@ const rOps = require('bitcoin-ops/map') let parseRawScriptHex = function (rawScript, parsedScript) { let opStr = rawScript.substring(0,2) - let op = parseInt(`0x${opStr}`) + let op = parseInt(opStr, 16) // Custom descriptors (not necessarily op codes) if (op > 0 && op < 76) { parsedScript += `PUSHDATA(${op})[${rawScript.substring(2, 2+(2*op))}] ` rawScript = rawScript.substring(2+(2*op)) - } else { + } else if (op === 76) { + let bytesToPush = parseInt(rawScript.substring(2, 4), 16) + parsedScript += `PUSHDATA(${bytesToPush})[${rawScript.substring(4, 4 + (2 * bytesToPush))}] ` + rawScript = rawScript.substring(4 + (2 * bytesToPush)) + } else if (op === 77) { + let bytesToPush = parseInt(rawScript.substring(2, 6), 16) + parsedScript += `PUSHDATA(${bytesToPush})[${rawScript.substring(6, 6 + (2 * bytesToPush))}] ` + rawScript = rawScript.substring(6 + (2 * bytesToPush)) + } else if (op === 78) { + let bytesToPush = parseInt(rawScript.substring(2, 8), 16) + parsedScript += `PUSHDATA(${bytesToPush})[${rawScript.substring(8, 8 + (2 * bytesToPush))}] ` + rawScript = rawScript.substring(8 + (2 * bytesToPush)) + } else { // TODO: 77 and 78 parsedScript += `${rOps[op]} ` rawScript = rawScript.substring(2) } @@ -21,7 +33,7 @@ let parseRawScriptHex = function (rawScript, parsedScript) { // TODO: Could also include a dissasembly https://defuse.ca/online-x86-assembler.htm#disassembly2 -let parseRawScript = function (rawScript, format) { +let parseRawScript = function (rawScript, format='hex') { let asm = '' switch (format) { case 'hex': diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..a5c76f8 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,254 @@ +{ + "name": "node-bitcoin-script", + "version": "1.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "bitcoin-ops": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/bitcoin-ops/-/bitcoin-ops-1.4.1.tgz", + "integrity": "sha512-pef6gxZFztEhaE9RY9HmWVmiIHqCb2OyS4HPKkpc6CIiiOa3Qmuoylxc5P2EkU3w+5eTSifI9SEZC88idAIGow==" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "chai": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", + "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.0", + "type-detect": "^4.0.5" + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "commander": { + "version": "2.15.1", + "resolved": "http://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "mocha": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", + "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", + "dev": true, + "requires": { + "browser-stdout": "1.3.1", + "commander": "2.15.1", + "debug": "3.1.0", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.5", + "he": "1.1.1", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "supports-color": "5.4.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + } + } +} diff --git a/package.json b/package.json index 0d8ed15..484e35d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "node-bitcoin-script", - "version": "1.0.1", + "version": "1.0.2", "description": "Node Bitcoin Script Parser", "main": "index.js", "scripts": { @@ -20,7 +20,6 @@ "bitcoin-ops": "^1.4.1" }, "devDependencies": { - "chai": "^4.1.2", - "mocha": "^5.2.0" + "chai": "^4.1.2" } } diff --git a/test/parseTests.js b/test/parseTests.js index ddb2da8..749e990 100644 --- a/test/parseTests.js +++ b/test/parseTests.js @@ -31,10 +31,34 @@ describe('Parse Tests', function() { // TODO: P2WSH // TODO: P2SH(P2WSH) }) + + describe('OP_RETURN scriptPubkey', function () { + it('returns expected assembly for less than 76 bytes', function() { + parsedScript = script.parseRawScript('6a13636861726c6579206c6f766573206865696469', 'hex') + expect(parsedScript).to.equal('OP_RETURN PUSHDATA(19)[636861726c6579206c6f766573206865696469]') + }) + + it('returns expected assembly for OP_PUSHDATA1', function() { + parsedScript = script.parseRawScript('6a4c4f7b6e616d653a5465737479204d63546573746572736f6e2c70686f6e653a2b3434353535353535353535352c656d61696c3a74657374796d63746573746572736f6e3538323140616f6c2e636f6d7d') + expect(parsedScript).to.equal('OP_RETURN PUSHDATA(79)[7b6e616d653a5465737479204d63546573746572736f6e2c70686f6e653a2b3434353535353535353535352c656d61696c3a74657374796d63746573746572736f6e3538323140616f6c2e636f6d7d]') + }) + + it('returns expected assembly for OP_PUSHDATA2', function() { + parsedScript = script.parseRawScript('6a4d01007b6e616d653a5465737479204d63546573746572736f6e2c70686f6e653a2b3434353535353535353535352c656d61696c3a74657374796d63746573746572736f6e3538323140616f6c2e636f6d7d7b6e616d653a5465737479204d63546573746572736f6e2c70686f6e653a2b3434353535353535353535352c656d61696c3a74657374796d63746573746572736f6e3538323140616f6c2e636f6d7d7b6e616d653a5465737479204d63546573746572736f6e2c70686f6e653a2b3434353535353535353535352c656d61696c3a74657374796d63746573746572736f6e3538323140616f6c2e636f6d7d7b6e616d653a5465737479204d635465737465') + expect(parsedScript).to.equal('OP_RETURN PUSHDATA(256)[7b6e616d653a5465737479204d63546573746572736f6e2c70686f6e653a2b3434353535353535353535352c656d61696c3a74657374796d63746573746572736f6e3538323140616f6c2e636f6d7d7b6e616d653a5465737479204d63546573746572736f6e2c70686f6e653a2b3434353535353535353535352c656d61696c3a74657374796d63746573746572736f6e3538323140616f6c2e636f6d7d7b6e616d653a5465737479204d63546573746572736f6e2c70686f6e653a2b3434353535353535353535352c656d61696c3a74657374796d63746573746572736f6e3538323140616f6c2e636f6d7d7b6e616d653a5465737479204d635465737465]') + }) + + it('TODO: returns expected assembly for OP_PUSHDATA4', function() { + // TODO: make a test fixture + //parsedScript = script.parseRawScript('6a4e') + //expect(parsedScript).to.equal('OP_RETURN PUSHDATA(65536)[]') + }) + }) + }) describe('parseAsmScript Tests', function() { - it('returns 0 * 4 = 4', function() { + it('does something', function() { // TODO }) })