Merge pull request #224 from dcousens/classify
Script classification fixes
This commit is contained in:
commit
d9e240bbb1
7 changed files with 294 additions and 138 deletions
|
@ -1,7 +1,7 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
// push value
|
// push value
|
||||||
OP_0 : 0,
|
|
||||||
OP_FALSE : 0,
|
OP_FALSE : 0,
|
||||||
|
OP_0 : 0,
|
||||||
OP_PUSHDATA1 : 76,
|
OP_PUSHDATA1 : 76,
|
||||||
OP_PUSHDATA2 : 77,
|
OP_PUSHDATA2 : 77,
|
||||||
OP_PUSHDATA4 : 78,
|
OP_PUSHDATA4 : 78,
|
||||||
|
|
|
@ -12,6 +12,21 @@ function Script(buffer, chunks) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Import operations
|
// Import operations
|
||||||
|
Script.fromASM = function(asm) {
|
||||||
|
var strChunks = asm.split(' ')
|
||||||
|
|
||||||
|
var chunks = strChunks.map(function(strChunk) {
|
||||||
|
if (strChunk in opcodes) {
|
||||||
|
return opcodes[strChunk]
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return new Buffer(strChunk, 'hex')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return Script.fromChunks(chunks)
|
||||||
|
}
|
||||||
|
|
||||||
Script.fromBuffer = function(buffer) {
|
Script.fromBuffer = function(buffer) {
|
||||||
var chunks = []
|
var chunks = []
|
||||||
|
|
||||||
|
@ -90,6 +105,23 @@ Script.prototype.without = function(needle) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Export operations
|
// Export operations
|
||||||
|
var reverseOps = []
|
||||||
|
for (var op in opcodes) {
|
||||||
|
var code = opcodes[op]
|
||||||
|
reverseOps[code] = op
|
||||||
|
}
|
||||||
|
|
||||||
|
Script.prototype.toASM = function() {
|
||||||
|
return this.chunks.map(function(chunk) {
|
||||||
|
if (Buffer.isBuffer(chunk)) {
|
||||||
|
return chunk.toString('hex')
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return reverseOps[chunk]
|
||||||
|
}
|
||||||
|
}).join(' ')
|
||||||
|
}
|
||||||
|
|
||||||
Script.prototype.toBuffer = function() {
|
Script.prototype.toBuffer = function() {
|
||||||
return this.buffer
|
return this.buffer
|
||||||
}
|
}
|
||||||
|
|
168
src/scripts.js
168
src/scripts.js
|
@ -1,19 +1,34 @@
|
||||||
var assert = require('assert')
|
var assert = require('assert')
|
||||||
var opcodes = require('./opcodes')
|
var opcodes = require('./opcodes')
|
||||||
|
|
||||||
|
// FIXME: use ECPubKey, currently the circular dependency breaks everything.
|
||||||
|
//
|
||||||
|
// Solutions:
|
||||||
|
// * Remove ECPubKey.getAddress
|
||||||
|
// - Minimal change, but likely unpopular
|
||||||
|
// * Move all script related functionality out of Address
|
||||||
|
// - Means a lot of changes to Transaction/Wallet
|
||||||
|
// * Ignore it (existing solution)
|
||||||
|
// * Some form of hackery with commonjs
|
||||||
|
//
|
||||||
|
var ecurve = require('ecurve')
|
||||||
|
var curve = ecurve.getCurveByName('secp256k1')
|
||||||
|
|
||||||
|
var ECSignature = require('./ecsignature')
|
||||||
var Script = require('./script')
|
var Script = require('./script')
|
||||||
|
|
||||||
function classifyOutput(script) {
|
function classifyOutput(script) {
|
||||||
assert(script instanceof Script, 'Expected Script, got ', script)
|
assert(script instanceof Script, 'Expected Script, got ', script)
|
||||||
|
|
||||||
if (isPubkeyhash.call(script)) {
|
if (isPubKeyHashOutput.call(script)) {
|
||||||
return 'pubkeyhash'
|
return 'pubkeyhash'
|
||||||
} else if (isPubkey.call(script)) {
|
} else if (isScriptHashOutput.call(script)) {
|
||||||
return 'pubkey'
|
|
||||||
} else if (isScripthash.call(script)) {
|
|
||||||
return 'scripthash'
|
return 'scripthash'
|
||||||
} else if (isMultisig.call(script)) {
|
} else if (isMultisigOutput.call(script)) {
|
||||||
return 'multisig'
|
return 'multisig'
|
||||||
} else if (isNulldata.call(script)) {
|
} else if (isPubKeyOutput.call(script)) {
|
||||||
|
return 'pubkey'
|
||||||
|
} else if (isNulldataOutput.call(script)) {
|
||||||
return 'nulldata'
|
return 'nulldata'
|
||||||
} else {
|
} else {
|
||||||
return 'nonstandard'
|
return 'nonstandard'
|
||||||
|
@ -23,67 +38,128 @@ function classifyOutput(script) {
|
||||||
function classifyInput(script) {
|
function classifyInput(script) {
|
||||||
assert(script instanceof Script, 'Expected Script, got ', script)
|
assert(script instanceof Script, 'Expected Script, got ', script)
|
||||||
|
|
||||||
if (script.chunks.length == 1 && Buffer.isBuffer(script.chunks[0])) {
|
if (isPubKeyHashInput.call(script)) {
|
||||||
return 'pubkey'
|
|
||||||
} else if (script.chunks.length == 2 && Buffer.isBuffer(script.chunks[0]) && Buffer.isBuffer(script.chunks[1])) {
|
|
||||||
return 'pubkeyhash'
|
return 'pubkeyhash'
|
||||||
} else if (script.chunks[0] == opcodes.OP_0 && script.chunks.slice(1).reduce(function(t, chunk, i) {
|
} else if (isScriptHashInput.call(script)) {
|
||||||
return t && Buffer.isBuffer(chunk) && (chunk[0] == 48 || i == script.chunks.length - 1)
|
return 'scripthash'
|
||||||
}, true)) {
|
} else if (isMultisigInput.call(script)) {
|
||||||
return 'multisig'
|
return 'multisig'
|
||||||
|
} else if (isPubKeyInput.call(script)) {
|
||||||
|
return 'pubkey'
|
||||||
} else {
|
} else {
|
||||||
return 'nonstandard'
|
return 'nonstandard'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isPubkeyhash() {
|
function isCanonicalPubKey(buffer) {
|
||||||
return this.chunks.length == 5 &&
|
if (!Buffer.isBuffer(buffer)) return false
|
||||||
this.chunks[0] == opcodes.OP_DUP &&
|
|
||||||
this.chunks[1] == opcodes.OP_HASH160 &&
|
try {
|
||||||
Buffer.isBuffer(this.chunks[2]) &&
|
// FIXME: boo
|
||||||
this.chunks[2].length === 20 &&
|
ecurve.Point.decodeFrom(curve, buffer)
|
||||||
this.chunks[3] == opcodes.OP_EQUALVERIFY &&
|
} catch (e) {
|
||||||
this.chunks[4] == opcodes.OP_CHECKSIG
|
if (!(e.message.match(/Invalid sequence (length|tag)/))) throw e
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
function isPubkey() {
|
function isCanonicalSignature(buffer) {
|
||||||
|
if (!Buffer.isBuffer(buffer)) return false
|
||||||
|
|
||||||
|
try {
|
||||||
|
ECSignature.parseScriptSignature(buffer)
|
||||||
|
} catch(e) {
|
||||||
|
if (!(e.message.match(/Not a DER sequence|Invalid sequence length|Expected a DER integer|R length is zero|S length is zero|R value excessively padded|S value excessively padded|R value is negative|S value is negative|Invalid hashType/))) throw e
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
function isPubKeyHashInput() {
|
||||||
return this.chunks.length === 2 &&
|
return this.chunks.length === 2 &&
|
||||||
Buffer.isBuffer(this.chunks[0]) &&
|
isCanonicalSignature(this.chunks[0]) &&
|
||||||
|
isCanonicalPubKey(this.chunks[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
function isPubKeyHashOutput() {
|
||||||
|
return this.chunks.length === 5 &&
|
||||||
|
this.chunks[0] === opcodes.OP_DUP &&
|
||||||
|
this.chunks[1] === opcodes.OP_HASH160 &&
|
||||||
|
Buffer.isBuffer(this.chunks[2]) &&
|
||||||
|
this.chunks[2].length === 20 &&
|
||||||
|
this.chunks[3] === opcodes.OP_EQUALVERIFY &&
|
||||||
|
this.chunks[4] === opcodes.OP_CHECKSIG
|
||||||
|
}
|
||||||
|
|
||||||
|
function isPubKeyInput() {
|
||||||
|
return this.chunks.length === 1 &&
|
||||||
|
isCanonicalSignature(this.chunks[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
function isPubKeyOutput() {
|
||||||
|
return this.chunks.length === 2 &&
|
||||||
|
isCanonicalPubKey(this.chunks[0]) &&
|
||||||
this.chunks[1] === opcodes.OP_CHECKSIG
|
this.chunks[1] === opcodes.OP_CHECKSIG
|
||||||
}
|
}
|
||||||
|
|
||||||
function isScripthash() {
|
function isScriptHashInput() {
|
||||||
return this.chunks[this.chunks.length - 1] == opcodes.OP_EQUAL &&
|
if (this.chunks.length < 2) return false
|
||||||
this.chunks[0] == opcodes.OP_HASH160 &&
|
var lastChunk = this.chunks[this.chunks.length - 1]
|
||||||
|
|
||||||
|
if (!Buffer.isBuffer(lastChunk)) return false
|
||||||
|
|
||||||
|
var scriptSig = Script.fromChunks(this.chunks.slice(0, -1))
|
||||||
|
var scriptPubKey = Script.fromBuffer(lastChunk)
|
||||||
|
|
||||||
|
return classifyInput(scriptSig) === classifyOutput(scriptPubKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
function isScriptHashOutput() {
|
||||||
|
return this.chunks.length === 3 &&
|
||||||
|
this.chunks[0] === opcodes.OP_HASH160 &&
|
||||||
Buffer.isBuffer(this.chunks[1]) &&
|
Buffer.isBuffer(this.chunks[1]) &&
|
||||||
this.chunks[1].length === 20 &&
|
this.chunks[1].length === 20 &&
|
||||||
this.chunks.length == 3
|
this.chunks[2] === opcodes.OP_EQUAL
|
||||||
}
|
}
|
||||||
|
|
||||||
function isMultisig() {
|
function isMultisigInput() {
|
||||||
return this.chunks.length > 3 &&
|
return this.chunks[0] === opcodes.OP_0 &&
|
||||||
// m is a smallint
|
this.chunks.slice(1).every(isCanonicalSignature)
|
||||||
isSmallIntOp(this.chunks[0]) &&
|
|
||||||
// n is a smallint
|
|
||||||
isSmallIntOp(this.chunks[this.chunks.length - 2]) &&
|
|
||||||
// n greater or equal to m
|
|
||||||
this.chunks[0] <= this.chunks[this.chunks.length - 2] &&
|
|
||||||
// n cannot be 0
|
|
||||||
this.chunks[this.chunks.length - 2] !== opcodes.OP_0 &&
|
|
||||||
// n is the size of chunk length minus 3 (m, n, OP_CHECKMULTISIG)
|
|
||||||
this.chunks.length - 3 === this.chunks[this.chunks.length - 2] - opcodes.OP_RESERVED &&
|
|
||||||
// last chunk is OP_CHECKMULTISIG
|
|
||||||
this.chunks[this.chunks.length - 1] == opcodes.OP_CHECKMULTISIG
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function isNulldata() {
|
function isMultisigOutput() {
|
||||||
|
if (this.chunks < 4) return false
|
||||||
|
if (this.chunks[this.chunks.length - 1] !== opcodes.OP_CHECKMULTISIG) return false
|
||||||
|
|
||||||
|
var mOp = this.chunks[0]
|
||||||
|
if (mOp === opcodes.OP_0) return false
|
||||||
|
if (mOp < opcodes.OP_1) return false
|
||||||
|
if (mOp > opcodes.OP_16) return false
|
||||||
|
|
||||||
|
var nOp = this.chunks[this.chunks.length - 2]
|
||||||
|
if (nOp === opcodes.OP_0) return false
|
||||||
|
if (nOp < opcodes.OP_1) return false
|
||||||
|
if (nOp > opcodes.OP_16) return false
|
||||||
|
|
||||||
|
var m = mOp - (opcodes.OP_1 - 1)
|
||||||
|
var n = nOp - (opcodes.OP_1 - 1)
|
||||||
|
if (n < m) return false
|
||||||
|
|
||||||
|
var pubKeys = this.chunks.slice(1, -2)
|
||||||
|
if (n < pubKeys.length) return false
|
||||||
|
|
||||||
|
return pubKeys.every(isCanonicalPubKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
function isNulldataOutput() {
|
||||||
return this.chunks[0] === opcodes.OP_RETURN
|
return this.chunks[0] === opcodes.OP_RETURN
|
||||||
}
|
}
|
||||||
|
|
||||||
function isSmallIntOp(opcode) {
|
|
||||||
return ((opcode == opcodes.OP_0) || ((opcode >= opcodes.OP_1) && (opcode <= opcodes.OP_16)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Standard Script Templates
|
// Standard Script Templates
|
||||||
// {pubKey} OP_CHECKSIG
|
// {pubKey} OP_CHECKSIG
|
||||||
function pubKeyOutput(pubKey) {
|
function pubKeyOutput(pubKey) {
|
||||||
|
@ -160,7 +236,7 @@ function scriptHashInput(scriptSig, scriptPubKey) {
|
||||||
// OP_0 [signatures ...]
|
// OP_0 [signatures ...]
|
||||||
function multisigInput(signatures, scriptPubKey) {
|
function multisigInput(signatures, scriptPubKey) {
|
||||||
if (scriptPubKey) {
|
if (scriptPubKey) {
|
||||||
assert(isMultisig.call(scriptPubKey))
|
assert(isMultisigOutput.call(scriptPubKey))
|
||||||
|
|
||||||
var m = scriptPubKey.chunks[0]
|
var m = scriptPubKey.chunks[0]
|
||||||
var k = m - (opcodes.OP_1 - 1)
|
var k = m - (opcodes.OP_1 - 1)
|
||||||
|
|
22
test/fixtures/script.json
vendored
22
test/fixtures/script.json
vendored
|
@ -6,7 +6,7 @@
|
||||||
"type": "pubkey",
|
"type": "pubkey",
|
||||||
"hash": "26e645ab170255f2a0a82d29e48f35b14ae7c826",
|
"hash": "26e645ab170255f2a0a82d29e48f35b14ae7c826",
|
||||||
"pubKey": "031f1e68f82112b373f0fe980b3a89d212d2b5c01fb51eb25acb8b4c4b4299ce95",
|
"pubKey": "031f1e68f82112b373f0fe980b3a89d212d2b5c01fb51eb25acb8b4c4b4299ce95",
|
||||||
"asm": "33 031f1e68f82112b373f0fe980b3a89d212d2b5c01fb51eb25acb8b4c4b4299ce95 OP_CHECKSIG",
|
"asm": "031f1e68f82112b373f0fe980b3a89d212d2b5c01fb51eb25acb8b4c4b4299ce95 OP_CHECKSIG",
|
||||||
"scriptPubKey": true
|
"scriptPubKey": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -14,7 +14,7 @@
|
||||||
"hex": "a914e8c300c87986efa84c37c0519929019ef86eb5b487",
|
"hex": "a914e8c300c87986efa84c37c0519929019ef86eb5b487",
|
||||||
"type": "scripthash",
|
"type": "scripthash",
|
||||||
"hash": "0ba47b56a573bab4b430ad6ed3ec79270e04b066",
|
"hash": "0ba47b56a573bab4b430ad6ed3ec79270e04b066",
|
||||||
"asm": "OP_HASH160 20 e8c300c87986efa84c37c0519929019ef86eb5b4 OP_EQUAL",
|
"asm": "OP_HASH160 e8c300c87986efa84c37c0519929019ef86eb5b4 OP_EQUAL",
|
||||||
"scriptPubKey": true
|
"scriptPubKey": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -22,7 +22,7 @@
|
||||||
"hex": "76a9145a3acbc7bbcc97c5ff16f5909c9d7d3fadb293a888ac",
|
"hex": "76a9145a3acbc7bbcc97c5ff16f5909c9d7d3fadb293a888ac",
|
||||||
"type": "pubkeyhash",
|
"type": "pubkeyhash",
|
||||||
"hash": "a5313f33d5c7b81674b35f7f3febc3522ef234db",
|
"hash": "a5313f33d5c7b81674b35f7f3febc3522ef234db",
|
||||||
"asm": "OP_DUP OP_HASH160 20 5a3acbc7bbcc97c5ff16f5909c9d7d3fadb293a8 OP_EQUALVERIFY OP_CHECKSIG",
|
"asm": "OP_DUP OP_HASH160 5a3acbc7bbcc97c5ff16f5909c9d7d3fadb293a8 OP_EQUALVERIFY OP_CHECKSIG",
|
||||||
"scriptPubKey": true
|
"scriptPubKey": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
"hex": "48304502206becda98cecf7a545d1a640221438ff8912d9b505ede67e0138485111099f696022100ccd616072501310acba10feb97cecc918e21c8e92760cd35144efec7622938f30141040cd2d2ce17a1e9b2b3b2cb294d40eecf305a25b7e7bfdafae6bb2639f4ee399b3637706c3d377ec4ab781355add443ae864b134c5e523001c442186ea60f0eb8",
|
"hex": "48304502206becda98cecf7a545d1a640221438ff8912d9b505ede67e0138485111099f696022100ccd616072501310acba10feb97cecc918e21c8e92760cd35144efec7622938f30141040cd2d2ce17a1e9b2b3b2cb294d40eecf305a25b7e7bfdafae6bb2639f4ee399b3637706c3d377ec4ab781355add443ae864b134c5e523001c442186ea60f0eb8",
|
||||||
"type": "pubkeyhash",
|
"type": "pubkeyhash",
|
||||||
"hash": "b9bac2a5c5c29bb27c382d41fa3d179c646c78fd",
|
"hash": "b9bac2a5c5c29bb27c382d41fa3d179c646c78fd",
|
||||||
"asm": "72 304502206becda98cecf7a545d1a640221438ff8912d9b505ede67e0138485111099f696022100ccd616072501310acba10feb97cecc918e21c8e92760cd35144efec7622938f301 65 040cd2d2ce17a1e9b2b3b2cb294d40eecf305a25b7e7bfdafae6bb2639f4ee399b3637706c3d377ec4ab781355add443ae864b134c5e523001c442186ea60f0eb8",
|
"asm": "304502206becda98cecf7a545d1a640221438ff8912d9b505ede67e0138485111099f696022100ccd616072501310acba10feb97cecc918e21c8e92760cd35144efec7622938f301 040cd2d2ce17a1e9b2b3b2cb294d40eecf305a25b7e7bfdafae6bb2639f4ee399b3637706c3d377ec4ab781355add443ae864b134c5e523001c442186ea60f0eb8",
|
||||||
"scriptPubKey": false
|
"scriptPubKey": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -39,7 +39,7 @@
|
||||||
"type": "pubkey",
|
"type": "pubkey",
|
||||||
"hash": "44d9982c3e79452e02ef5816976a0e20a0ec1cba",
|
"hash": "44d9982c3e79452e02ef5816976a0e20a0ec1cba",
|
||||||
"signature": "304502206becda98cecf7a545d1a640221438ff8912d9b505ede67e0138485111099f696022100ccd616072501310acba10feb97cecc918e21c8e92760cd35144efec7622938f301",
|
"signature": "304502206becda98cecf7a545d1a640221438ff8912d9b505ede67e0138485111099f696022100ccd616072501310acba10feb97cecc918e21c8e92760cd35144efec7622938f301",
|
||||||
"asm": "72 304502206becda98cecf7a545d1a640221438ff8912d9b505ede67e0138485111099f696022100ccd616072501310acba10feb97cecc918e21c8e92760cd35144efec7622938f301",
|
"asm": "304502206becda98cecf7a545d1a640221438ff8912d9b505ede67e0138485111099f696022100ccd616072501310acba10feb97cecc918e21c8e92760cd35144efec7622938f301",
|
||||||
"scriptPubKey": false
|
"scriptPubKey": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -47,7 +47,7 @@
|
||||||
"hex": "5121032487c2a32f7c8d57d2a93906a6457afd00697925b0e6e145d89af6d3bca330162102308673d16987eaa010e540901cc6fe3695e758c19f46ce604e174dac315e685a52ae",
|
"hex": "5121032487c2a32f7c8d57d2a93906a6457afd00697925b0e6e145d89af6d3bca330162102308673d16987eaa010e540901cc6fe3695e758c19f46ce604e174dac315e685a52ae",
|
||||||
"type": "multisig",
|
"type": "multisig",
|
||||||
"hash": "f1c98f0b74ecabcf78ae20dfa224bb6666051fbe",
|
"hash": "f1c98f0b74ecabcf78ae20dfa224bb6666051fbe",
|
||||||
"asm": "OP_TRUE 33 032487c2a32f7c8d57d2a93906a6457afd00697925b0e6e145d89af6d3bca33016 33 02308673d16987eaa010e540901cc6fe3695e758c19f46ce604e174dac315e685a OP_2 OP_CHECKMULTISIG",
|
"asm": "OP_TRUE 032487c2a32f7c8d57d2a93906a6457afd00697925b0e6e145d89af6d3bca33016 02308673d16987eaa010e540901cc6fe3695e758c19f46ce604e174dac315e685a OP_2 OP_CHECKMULTISIG",
|
||||||
"scriptPubKey": true
|
"scriptPubKey": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -55,15 +55,15 @@
|
||||||
"hex": "0047304402202b29881db1b4cc128442d955e906d41c77365ed9a8392b584be12d980b236459022009da4bc60d09280aa26f4f981bfbed94eb7263d92920961e48a7f3f0991895b101483045022100871708a7597c1dbebff2a5527a56a1f2b49d73e35cd825a07285f5f29f5766d8022003bd7ac25334e9a6d6020cc8ba1be67a8c70dca8e7063ea0547d79c45b9bc12601",
|
"hex": "0047304402202b29881db1b4cc128442d955e906d41c77365ed9a8392b584be12d980b236459022009da4bc60d09280aa26f4f981bfbed94eb7263d92920961e48a7f3f0991895b101483045022100871708a7597c1dbebff2a5527a56a1f2b49d73e35cd825a07285f5f29f5766d8022003bd7ac25334e9a6d6020cc8ba1be67a8c70dca8e7063ea0547d79c45b9bc12601",
|
||||||
"type": "multisig",
|
"type": "multisig",
|
||||||
"hash": "b1ef3ae2c77b356eff81049aad7dfd2eeb34c6f5",
|
"hash": "b1ef3ae2c77b356eff81049aad7dfd2eeb34c6f5",
|
||||||
"asm": "00 47 304402202b29881db1b4cc128442d955e906d41c77365ed9a8392b584be12d980b236459022009da4bc60d09280aa26f4f981bfbed94eb7263d92920961e48a7f3f0991895b101 48 3045022100871708a7597c1dbebff2a5527a56a1f2b49d73e35cd825a07285f5f29f5766d8022003bd7ac25334e9a6d6020cc8ba1be67a8c70dca8e7063ea0547d79c45b9bc12601",
|
"asm": "OP_0 304402202b29881db1b4cc128442d955e906d41c77365ed9a8392b584be12d980b236459022009da4bc60d09280aa26f4f981bfbed94eb7263d92920961e48a7f3f0991895b101 3045022100871708a7597c1dbebff2a5527a56a1f2b49d73e35cd825a07285f5f29f5766d8022003bd7ac25334e9a6d6020cc8ba1be67a8c70dca8e7063ea0547d79c45b9bc12601",
|
||||||
"scriptPubKey": false
|
"scriptPubKey": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "OP_RETURN script",
|
"description": "OP_RETURN script",
|
||||||
"hex":"6a2606deadbeef03f895a2ad89fb6d696497af486cb7c644a27aa568c7a18dd06113401115185474",
|
"hex": "6a2606deadbeef03f895a2ad89fb6d696497af486cb7c644a27aa568c7a18dd06113401115185474",
|
||||||
"type": "nulldata",
|
"type": "nulldata",
|
||||||
"hash": "ec88f016655477663455fe6a8e83508c348ea145",
|
"hash": "ec88f016655477663455fe6a8e83508c348ea145",
|
||||||
"asm": "OP_RETURN 38 06deadbeef03f895a2ad89fb6d696497af486cb7c644a27aa568c7a18dd06113401115185474",
|
"asm": "OP_RETURN 06deadbeef03f895a2ad89fb6d696497af486cb7c644a27aa568c7a18dd06113401115185474",
|
||||||
"scriptPubKey": true
|
"scriptPubKey": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -71,7 +71,7 @@
|
||||||
"hex": "aa206fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d619000000000087",
|
"hex": "aa206fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d619000000000087",
|
||||||
"type": "nonstandard",
|
"type": "nonstandard",
|
||||||
"hash": "3823382e70d1930989813d3459988e0d7c2861d8",
|
"hash": "3823382e70d1930989813d3459988e0d7c2861d8",
|
||||||
"asm": "OP_HASH256 32 6fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000 OP_EQUAL",
|
"asm": "OP_HASH256 6fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000 OP_EQUAL",
|
||||||
"scriptPubKey": true
|
"scriptPubKey": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -79,7 +79,7 @@
|
||||||
"hex": "000000ae",
|
"hex": "000000ae",
|
||||||
"type": "nonstandard",
|
"type": "nonstandard",
|
||||||
"hash": "62ede8963f9387544935f168745262f703dab1fb",
|
"hash": "62ede8963f9387544935f168745262f703dab1fb",
|
||||||
"asm": "0 0 0 OP_CHECKMULTISIG",
|
"asm": "OP_0 OP_0 OP_0 OP_CHECKMULTISIG",
|
||||||
"scriptPubKey": true
|
"scriptPubKey": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
119
test/fixtures/scripts.json
vendored
119
test/fixtures/scripts.json
vendored
|
@ -1,55 +1,82 @@
|
||||||
{
|
{
|
||||||
"valid": {
|
"valid": [
|
||||||
"pubKey": [
|
{
|
||||||
|
"type": "pubkey",
|
||||||
|
"pubKey": "02359c6e3f04cefbf089cf1d6670dc47c3fb4df68e2bad1fa5a369f9ce4b42bbd1",
|
||||||
|
"signature": "304402207515cf147d201f411092e6be5a64a6006f9308fad7b2a8fdaab22cd86ce764c202200974b8aca7bf51dbf54150d3884e1ae04f675637b926ec33bf75939446f6ca2801",
|
||||||
|
"scriptPubKey": "02359c6e3f04cefbf089cf1d6670dc47c3fb4df68e2bad1fa5a369f9ce4b42bbd1 OP_CHECKSIG",
|
||||||
|
"scriptSig": "304402207515cf147d201f411092e6be5a64a6006f9308fad7b2a8fdaab22cd86ce764c202200974b8aca7bf51dbf54150d3884e1ae04f675637b926ec33bf75939446f6ca2801"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "pubkeyhash",
|
||||||
|
"pubKey": "02359c6e3f04cefbf089cf1d6670dc47c3fb4df68e2bad1fa5a369f9ce4b42bbd1",
|
||||||
|
"signature": "304402207515cf147d201f411092e6be5a64a6006f9308fad7b2a8fdaab22cd86ce764c202200974b8aca7bf51dbf54150d3884e1ae04f675637b926ec33bf75939446f6ca2801",
|
||||||
|
"scriptPubKey": "OP_DUP OP_HASH160 aa4d7985c57e011a8b3dd8e0e5a73aaef41629c5 OP_EQUALVERIFY OP_CHECKSIG",
|
||||||
|
"scriptSig": "304402207515cf147d201f411092e6be5a64a6006f9308fad7b2a8fdaab22cd86ce764c202200974b8aca7bf51dbf54150d3884e1ae04f675637b926ec33bf75939446f6ca2801 02359c6e3f04cefbf089cf1d6670dc47c3fb4df68e2bad1fa5a369f9ce4b42bbd1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "multisig",
|
||||||
|
"pubKeys": [
|
||||||
|
"02359c6e3f04cefbf089cf1d6670dc47c3fb4df68e2bad1fa5a369f9ce4b42bbd1",
|
||||||
|
"0395a9d84d47d524548f79f435758c01faec5da2b7e551d3b8c995b7e06326ae4a"
|
||||||
|
],
|
||||||
|
"signatures": [
|
||||||
|
"304402207515cf147d201f411092e6be5a64a6006f9308fad7b2a8fdaab22cd86ce764c202200974b8aca7bf51dbf54150d3884e1ae04f675637b926ec33bf75939446f6ca2801",
|
||||||
|
"3045022100ef253c1faa39e65115872519e5f0a33bbecf430c0f35cf562beabbad4da24d8d02201742be8ee49812a73adea3007c9641ce6725c32cd44ddb8e3a3af460015d140501"
|
||||||
|
],
|
||||||
|
"scriptPubKey": "OP_2 02359c6e3f04cefbf089cf1d6670dc47c3fb4df68e2bad1fa5a369f9ce4b42bbd1 0395a9d84d47d524548f79f435758c01faec5da2b7e551d3b8c995b7e06326ae4a OP_2 OP_CHECKMULTISIG",
|
||||||
|
"scriptSig": "OP_0 304402207515cf147d201f411092e6be5a64a6006f9308fad7b2a8fdaab22cd86ce764c202200974b8aca7bf51dbf54150d3884e1ae04f675637b926ec33bf75939446f6ca2801 3045022100ef253c1faa39e65115872519e5f0a33bbecf430c0f35cf562beabbad4da24d8d02201742be8ee49812a73adea3007c9641ce6725c32cd44ddb8e3a3af460015d140501"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "multisig",
|
||||||
|
"pubKeys": [
|
||||||
|
"0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
|
||||||
|
"02b80011a883a0fd621ad46dfc405df1e74bf075cbaf700fd4aebef6e96f848340",
|
||||||
|
"024289801366bcee6172b771cf5a7f13aaecd237a0b9a1ff9d769cabc2e6b70a34"
|
||||||
|
],
|
||||||
|
"signatures": [
|
||||||
|
"3045022100fe324541215798b2df68cbd44039615e23c506d4ec1a05572064392a98196b82022068c849fa6699206da2fc6d7848efc1d3804a5816d6293615fe34c1a7f34e1c2f01",
|
||||||
|
"3044022001ab168e80b863fdec694350b587339bb72a37108ac3c989849251444d13ebba02201811272023e3c1038478eb972a82d3ad431bfc2408e88e4da990f1a7ecbb263901",
|
||||||
|
"3045022100aaeb7204c17eee2f2c4ff1c9f8b39b79e75e7fbf33e92cc67ac51be8f15b75f90220659eee314a4943a6384d2b154fa5821ef7a084814d7ee2c6f9f7f0ffb53be34b01"
|
||||||
|
],
|
||||||
|
"scriptPubKey": "OP_3 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 02b80011a883a0fd621ad46dfc405df1e74bf075cbaf700fd4aebef6e96f848340 024289801366bcee6172b771cf5a7f13aaecd237a0b9a1ff9d769cabc2e6b70a34 OP_3 OP_CHECKMULTISIG",
|
||||||
|
"scriptSig": "OP_0 3045022100fe324541215798b2df68cbd44039615e23c506d4ec1a05572064392a98196b82022068c849fa6699206da2fc6d7848efc1d3804a5816d6293615fe34c1a7f34e1c2f01 3044022001ab168e80b863fdec694350b587339bb72a37108ac3c989849251444d13ebba02201811272023e3c1038478eb972a82d3ad431bfc2408e88e4da990f1a7ecbb263901 3045022100aaeb7204c17eee2f2c4ff1c9f8b39b79e75e7fbf33e92cc67ac51be8f15b75f90220659eee314a4943a6384d2b154fa5821ef7a084814d7ee2c6f9f7f0ffb53be34b01"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "scripthash",
|
||||||
|
"redeemScript": "OP_2 02359c6e3f04cefbf089cf1d6670dc47c3fb4df68e2bad1fa5a369f9ce4b42bbd1 0395a9d84d47d524548f79f435758c01faec5da2b7e551d3b8c995b7e06326ae4a OP_2 OP_CHECKMULTISIG",
|
||||||
|
"redeemScriptSig": "OP_0 304402207515cf147d201f411092e6be5a64a6006f9308fad7b2a8fdaab22cd86ce764c202200974b8aca7bf51dbf54150d3884e1ae04f675637b926ec33bf75939446f6ca2801 3045022100ef253c1faa39e65115872519e5f0a33bbecf430c0f35cf562beabbad4da24d8d02201742be8ee49812a73adea3007c9641ce6725c32cd44ddb8e3a3af460015d140501",
|
||||||
|
"scriptSig": "OP_0 304402207515cf147d201f411092e6be5a64a6006f9308fad7b2a8fdaab22cd86ce764c202200974b8aca7bf51dbf54150d3884e1ae04f675637b926ec33bf75939446f6ca2801 3045022100ef253c1faa39e65115872519e5f0a33bbecf430c0f35cf562beabbad4da24d8d02201742be8ee49812a73adea3007c9641ce6725c32cd44ddb8e3a3af460015d140501 522102359c6e3f04cefbf089cf1d6670dc47c3fb4df68e2bad1fa5a369f9ce4b42bbd1210395a9d84d47d524548f79f435758c01faec5da2b7e551d3b8c995b7e06326ae4a52ae",
|
||||||
|
"scriptPubKey": "OP_HASH160 722ff0bc2c3f47b35c20df646c395594da24e90e OP_EQUAL"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"invalid": {
|
||||||
|
"classify": [
|
||||||
{
|
{
|
||||||
"pubKey": "02359c6e3f04cefbf089cf1d6670dc47c3fb4df68e2bad1fa5a369f9ce4b42bbd1",
|
"description": "multisig output : m > n",
|
||||||
"signature": "304402207515cf147d201f411092e6be5a64a6006f9308fad7b2a8fdaab22cd86ce764c202200974b8aca7bf51dbf54150d3884e1ae04f675637b926ec33bf75939446f6ca2801",
|
"scriptPubKey": "OP_2 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 02b80011a883a0fd621ad46dfc405df1e74bf075cbaf700fd4aebef6e96f848340 OP_1 OP_CHECKMULTISIG"
|
||||||
"scriptPubKey": "2102359c6e3f04cefbf089cf1d6670dc47c3fb4df68e2bad1fa5a369f9ce4b42bbd1ac",
|
|
||||||
"scriptSig": "47304402207515cf147d201f411092e6be5a64a6006f9308fad7b2a8fdaab22cd86ce764c202200974b8aca7bf51dbf54150d3884e1ae04f675637b926ec33bf75939446f6ca2801"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"pubKeyHash": [
|
|
||||||
{
|
|
||||||
"pubKey": "02359c6e3f04cefbf089cf1d6670dc47c3fb4df68e2bad1fa5a369f9ce4b42bbd1",
|
|
||||||
"signature": "304402207515cf147d201f411092e6be5a64a6006f9308fad7b2a8fdaab22cd86ce764c202200974b8aca7bf51dbf54150d3884e1ae04f675637b926ec33bf75939446f6ca2801",
|
|
||||||
"scriptPubKey": "76a914aa4d7985c57e011a8b3dd8e0e5a73aaef41629c588ac",
|
|
||||||
"scriptSig": "47304402207515cf147d201f411092e6be5a64a6006f9308fad7b2a8fdaab22cd86ce764c202200974b8aca7bf51dbf54150d3884e1ae04f675637b926ec33bf75939446f6ca28012102359c6e3f04cefbf089cf1d6670dc47c3fb4df68e2bad1fa5a369f9ce4b42bbd1"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"multisig": [
|
|
||||||
{
|
|
||||||
"pubKeys": [
|
|
||||||
"02359c6e3f04cefbf089cf1d6670dc47c3fb4df68e2bad1fa5a369f9ce4b42bbd1",
|
|
||||||
"0395a9d84d47d524548f79f435758c01faec5da2b7e551d3b8c995b7e06326ae4a"
|
|
||||||
],
|
|
||||||
"signatures": [
|
|
||||||
"304402207515cf147d201f411092e6be5a64a6006f9308fad7b2a8fdaab22cd86ce764c202200974b8aca7bf51dbf54150d3884e1ae04f675637b926ec33bf75939446f6ca2801",
|
|
||||||
"3045022100ef253c1faa39e65115872519e5f0a33bbecf430c0f35cf562beabbad4da24d8d02201742be8ee49812a73adea3007c9641ce6725c32cd44ddb8e3a3af460015d140501"
|
|
||||||
],
|
|
||||||
"scriptPubKey": "522102359c6e3f04cefbf089cf1d6670dc47c3fb4df68e2bad1fa5a369f9ce4b42bbd1210395a9d84d47d524548f79f435758c01faec5da2b7e551d3b8c995b7e06326ae4a52ae",
|
|
||||||
"scriptSig": "0047304402207515cf147d201f411092e6be5a64a6006f9308fad7b2a8fdaab22cd86ce764c202200974b8aca7bf51dbf54150d3884e1ae04f675637b926ec33bf75939446f6ca2801483045022100ef253c1faa39e65115872519e5f0a33bbecf430c0f35cf562beabbad4da24d8d02201742be8ee49812a73adea3007c9641ce6725c32cd44ddb8e3a3af460015d140501"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"pubKeys": [
|
"description": "multisig output : n === 0",
|
||||||
"02ea1297665dd733d444f31ec2581020004892cdaaf3dd6c0107c615afb839785f",
|
"scriptPubKey": "OP_0 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 02b80011a883a0fd621ad46dfc405df1e74bf075cbaf700fd4aebef6e96f848340 OP_0 OP_CHECKMULTISIG"
|
||||||
"02fab2dea1458990793f56f42e4a47dbf35a12a351f26fa5d7e0cc7447eaafa21f",
|
},
|
||||||
"036c6802ce7e8113723dd92cdb852e492ebb157a871ca532c3cb9ed08248ff0e19"
|
{
|
||||||
],
|
"description": "multisig output : not (m <= len(pubKeys) <= n)",
|
||||||
"signatures": [],
|
"scriptPubKey": "OP_2 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 02b80011a883a0fd621ad46dfc405df1e74bf075cbaf700fd4aebef6e96f848340 024289801366bcee6172b771cf5a7f13aaecd237a0b9a1ff9d769cabc2e6b70a34 OP_2 OP_CHECKMULTISIG"
|
||||||
"scriptPubKey": "532102ea1297665dd733d444f31ec2581020004892cdaaf3dd6c0107c615afb839785f2102fab2dea1458990793f56f42e4a47dbf35a12a351f26fa5d7e0cc7447eaafa21f21036c6802ce7e8113723dd92cdb852e492ebb157a871ca532c3cb9ed08248ff0e1953ae",
|
},
|
||||||
"scriptSig": ""
|
{
|
||||||
|
"description": "multisig output : m not a small int",
|
||||||
|
"scriptPubKey": "OP_HASH160 024289801366bcee6172b771cf5a7f13aaecd237a0b9a1ff9d769cabc2e6b70a34 OP_1 OP_CHECKMULTISIG"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "multisig output : n not a small int",
|
||||||
|
"scriptPubKey": "OP_1 024289801366bcee6172b771cf5a7f13aaecd237a0b9a1ff9d769cabc2e6b70a34 OP_HASH160 OP_CHECKMULTISIG"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "multisig output : non-canonical pubKey (bad length)",
|
||||||
|
"scriptPubKey": "OP_1 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ffff OP_1 OP_CHECKMULTISIG"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"scripthash": [
|
|
||||||
{
|
|
||||||
"redeemScript": "522102359c6e3f04cefbf089cf1d6670dc47c3fb4df68e2bad1fa5a369f9ce4b42bbd1210395a9d84d47d524548f79f435758c01faec5da2b7e551d3b8c995b7e06326ae4a52ae",
|
|
||||||
"redeemScriptSig": "0047304402207515cf147d201f411092e6be5a64a6006f9308fad7b2a8fdaab22cd86ce764c202200974b8aca7bf51dbf54150d3884e1ae04f675637b926ec33bf75939446f6ca2801483045022100ef253c1faa39e65115872519e5f0a33bbecf430c0f35cf562beabbad4da24d8d02201742be8ee49812a73adea3007c9641ce6725c32cd44ddb8e3a3af460015d140501",
|
|
||||||
"scriptSig": "0047304402207515cf147d201f411092e6be5a64a6006f9308fad7b2a8fdaab22cd86ce764c202200974b8aca7bf51dbf54150d3884e1ae04f675637b926ec33bf75939446f6ca2801483045022100ef253c1faa39e65115872519e5f0a33bbecf430c0f35cf562beabbad4da24d8d02201742be8ee49812a73adea3007c9641ce6725c32cd44ddb8e3a3af460015d14050147522102359c6e3f04cefbf089cf1d6670dc47c3fb4df68e2bad1fa5a369f9ce4b42bbd1210395a9d84d47d524548f79f435758c01faec5da2b7e551d3b8c995b7e06326ae4a52ae",
|
|
||||||
"scriptPubKey": "a914722ff0bc2c3f47b35c20df646c395594da24e90e87"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"invalid": {
|
|
||||||
"multisig": [
|
"multisig": [
|
||||||
{
|
{
|
||||||
"exception": "Not enough pubKeys provided",
|
"exception": "Not enough pubKeys provided",
|
||||||
|
|
|
@ -21,6 +21,14 @@ describe('Script', function() {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('fromASM/toASM', function() {
|
||||||
|
fixtures.valid.forEach(function(f) {
|
||||||
|
it('decodes/encodes ' + f.description, function() {
|
||||||
|
assert.equal(Script.fromASM(f.asm).toASM(), f.asm)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe('fromHex/toHex', function() {
|
describe('fromHex/toHex', function() {
|
||||||
fixtures.valid.forEach(function(f) {
|
fixtures.valid.forEach(function(f) {
|
||||||
it('decodes/encodes ' + f.description, function() {
|
it('decodes/encodes ' + f.description, function() {
|
||||||
|
|
|
@ -5,16 +5,15 @@ var Address = require('../src/address')
|
||||||
var ECPubKey = require('../src/ecpubkey')
|
var ECPubKey = require('../src/ecpubkey')
|
||||||
var Script = require('../src/script')
|
var Script = require('../src/script')
|
||||||
|
|
||||||
var fixtures = require('./fixtures/script.json')
|
var fixtures = require('./fixtures/scripts.json')
|
||||||
var fixtures2 = require('./fixtures/scripts.json')
|
|
||||||
|
|
||||||
describe('Scripts', function() {
|
describe('Scripts', function() {
|
||||||
describe('classifyInput', function() {
|
describe('classifyInput', function() {
|
||||||
fixtures.valid.forEach(function(f) {
|
fixtures.valid.forEach(function(f) {
|
||||||
if (f.scriptPubKey) return
|
if (!f.scriptSig) return
|
||||||
|
|
||||||
it('supports ' + f.type, function() {
|
it('classifies ' + f.scriptSig + ' as ' + f.type, function() {
|
||||||
var script = Script.fromHex(f.hex)
|
var script = Script.fromASM(f.scriptSig)
|
||||||
var type = scripts.classifyInput(script)
|
var type = scripts.classifyInput(script)
|
||||||
|
|
||||||
assert.equal(type, f.type)
|
assert.equal(type, f.type)
|
||||||
|
@ -26,23 +25,34 @@ describe('Scripts', function() {
|
||||||
fixtures.valid.forEach(function(f) {
|
fixtures.valid.forEach(function(f) {
|
||||||
if (!f.scriptPubKey) return
|
if (!f.scriptPubKey) return
|
||||||
|
|
||||||
it('supports ' + f.type, function() {
|
it('classifies ' + f.scriptPubKey + ' as ' + f.type, function() {
|
||||||
var script = Script.fromHex(f.hex)
|
var script = Script.fromASM(f.scriptPubKey)
|
||||||
var type = scripts.classifyOutput(script)
|
var type = scripts.classifyOutput(script)
|
||||||
|
|
||||||
assert.equal(type, f.type)
|
assert.equal(type, f.type)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
fixtures.invalid.classify.forEach(function(f) {
|
||||||
|
it('returns nonstandard for ' + f.description, function() {
|
||||||
|
var script = Script.fromASM(f.scriptPubKey)
|
||||||
|
var type = scripts.classifyOutput(script)
|
||||||
|
|
||||||
|
assert.equal(type, 'nonstandard')
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('pubKey', function() {
|
describe('pubKey', function() {
|
||||||
fixtures2.valid.pubKey.forEach(function(f) {
|
fixtures.valid.forEach(function(f) {
|
||||||
|
if (f.type !== 'pubkey') return
|
||||||
|
|
||||||
describe('input script', function() {
|
describe('input script', function() {
|
||||||
it('is generated correctly for ' + f.pubKey, function() {
|
it('is generated correctly for ' + f.pubKey, function() {
|
||||||
var signature = new Buffer(f.signature, 'hex')
|
var signature = new Buffer(f.signature, 'hex')
|
||||||
|
|
||||||
var scriptSig = scripts.pubKeyInput(signature)
|
var scriptSig = scripts.pubKeyInput(signature)
|
||||||
assert.equal(scriptSig.toHex(), f.scriptSig)
|
assert.equal(scriptSig.toASM(), f.scriptSig)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -51,14 +61,16 @@ describe('Scripts', function() {
|
||||||
var pubKey = ECPubKey.fromHex(f.pubKey)
|
var pubKey = ECPubKey.fromHex(f.pubKey)
|
||||||
|
|
||||||
var scriptPubKey = scripts.pubKeyOutput(pubKey)
|
var scriptPubKey = scripts.pubKeyOutput(pubKey)
|
||||||
assert.equal(scriptPubKey.toHex(), f.scriptPubKey)
|
assert.equal(scriptPubKey.toASM(), f.scriptPubKey)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('pubKeyHash', function() {
|
describe('pubKeyHash', function() {
|
||||||
fixtures2.valid.pubKeyHash.forEach(function(f) {
|
fixtures.valid.forEach(function(f) {
|
||||||
|
if (f.type !== 'pubkeyhash') return
|
||||||
|
|
||||||
var pubKey = ECPubKey.fromHex(f.pubKey)
|
var pubKey = ECPubKey.fromHex(f.pubKey)
|
||||||
var address = pubKey.getAddress()
|
var address = pubKey.getAddress()
|
||||||
|
|
||||||
|
@ -67,46 +79,45 @@ describe('Scripts', function() {
|
||||||
var signature = new Buffer(f.signature, 'hex')
|
var signature = new Buffer(f.signature, 'hex')
|
||||||
|
|
||||||
var scriptSig = scripts.pubKeyHashInput(signature, pubKey)
|
var scriptSig = scripts.pubKeyHashInput(signature, pubKey)
|
||||||
assert.equal(scriptSig.toHex(), f.scriptSig)
|
assert.equal(scriptSig.toASM(), f.scriptSig)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('output script', function() {
|
describe('output script', function() {
|
||||||
it('is generated correctly for ' + address, function() {
|
it('is generated correctly for ' + address, function() {
|
||||||
var scriptPubKey = scripts.pubKeyHashOutput(address.hash)
|
var scriptPubKey = scripts.pubKeyHashOutput(address.hash)
|
||||||
assert.equal(scriptPubKey.toHex(), f.scriptPubKey)
|
assert.equal(scriptPubKey.toASM(), f.scriptPubKey)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('multisig', function() {
|
describe('multisig', function() {
|
||||||
fixtures2.valid.multisig.forEach(function(f) {
|
fixtures.valid.forEach(function(f) {
|
||||||
|
if (f.type !== 'multisig') return
|
||||||
|
|
||||||
var pubKeys = f.pubKeys.map(ECPubKey.fromHex)
|
var pubKeys = f.pubKeys.map(ECPubKey.fromHex)
|
||||||
var scriptPubKey = scripts.multisigOutput(pubKeys.length, pubKeys)
|
var scriptPubKey = scripts.multisigOutput(pubKeys.length, pubKeys)
|
||||||
|
|
||||||
// FIXME: some missing test data for now
|
describe('input script', function() {
|
||||||
if (f.scriptSig) {
|
it('is generated correctly for ' + f.scriptPubKey, function() {
|
||||||
describe('input script', function() {
|
var signatures = f.signatures.map(function(signature) {
|
||||||
it('is generated correctly for ' + scriptPubKey.toHex(), function() {
|
return new Buffer(signature, 'hex')
|
||||||
var signatures = f.signatures.map(function(signature) {
|
|
||||||
return new Buffer(signature, 'hex')
|
|
||||||
})
|
|
||||||
|
|
||||||
var scriptSig = scripts.multisigInput(signatures)
|
|
||||||
assert.equal(scriptSig.toHex(), f.scriptSig)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
var scriptSig = scripts.multisigInput(signatures)
|
||||||
|
assert.equal(scriptSig.toASM(), f.scriptSig)
|
||||||
})
|
})
|
||||||
}
|
})
|
||||||
|
|
||||||
describe('output script', function() {
|
describe('output script', function() {
|
||||||
it('is generated correctly for ' + scriptPubKey.toHex(), function() {
|
it('is generated correctly for ' + f.scriptPubKey, function() {
|
||||||
assert.equal(scriptPubKey.toHex(), f.scriptPubKey)
|
assert.equal(scriptPubKey.toASM(), f.scriptPubKey)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
fixtures2.invalid.multisig.forEach(function(f) {
|
fixtures.invalid.multisig.forEach(function(f) {
|
||||||
var pubKeys = f.pubKeys.map(ECPubKey.fromHex)
|
var pubKeys = f.pubKeys.map(ECPubKey.fromHex)
|
||||||
var scriptPubKey = scripts.multisigOutput(pubKeys.length, pubKeys)
|
var scriptPubKey = scripts.multisigOutput(pubKeys.length, pubKeys)
|
||||||
|
|
||||||
|
@ -135,17 +146,19 @@ describe('Scripts', function() {
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('scripthash', function() {
|
describe('scripthash', function() {
|
||||||
fixtures2.valid.scripthash.forEach(function(f) {
|
fixtures.valid.forEach(function(f) {
|
||||||
var redeemScript = Script.fromHex(f.redeemScript)
|
if (f.type !== 'scripthash') return
|
||||||
var redeemScriptSig = Script.fromHex(f.redeemScriptSig)
|
|
||||||
|
|
||||||
var address = Address.fromOutputScript(Script.fromHex(f.scriptPubKey))
|
var redeemScript = Script.fromASM(f.redeemScript)
|
||||||
|
var redeemScriptSig = Script.fromASM(f.redeemScriptSig)
|
||||||
|
|
||||||
|
var address = Address.fromOutputScript(Script.fromASM(f.scriptPubKey))
|
||||||
|
|
||||||
describe('input script', function() {
|
describe('input script', function() {
|
||||||
it('is generated correctly for ' + address, function() {
|
it('is generated correctly for ' + address, function() {
|
||||||
var scriptSig = scripts.scriptHashInput(redeemScriptSig, redeemScript)
|
var scriptSig = scripts.scriptHashInput(redeemScriptSig, redeemScript)
|
||||||
|
|
||||||
assert.equal(scriptSig.toHex(), f.scriptSig)
|
assert.equal(scriptSig.toASM(), f.scriptSig)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -153,7 +166,7 @@ describe('Scripts', function() {
|
||||||
it('is generated correctly for ' + address, function() {
|
it('is generated correctly for ' + address, function() {
|
||||||
var scriptPubKey = scripts.scriptHashOutput(redeemScript.getHash())
|
var scriptPubKey = scripts.scriptHashOutput(redeemScript.getHash())
|
||||||
|
|
||||||
assert.equal(scriptPubKey.toHex(), f.scriptPubKey)
|
assert.equal(scriptPubKey.toASM(), f.scriptPubKey)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
Loading…
Add table
Reference in a new issue