Solve Output: take an output script, returns {type, script, solvedBy, requiredSigs, canSign}
This commit is contained in:
parent
dd649867f6
commit
ffca5afcff
@ -17,6 +17,9 @@ var types = {
|
|||||||
P2WSH: 'witnessscripthash'
|
P2WSH: 'witnessscripthash'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var SIGNABLE_SCRIPTS = [types.MULTISIG, types.P2PKH, types.P2PK]
|
||||||
|
var P2SH_SCRIPTS = SIGNABLE_SCRIPTS.concat([types.P2WPKH, types.P2WSH])
|
||||||
|
|
||||||
function classifyOutput (script) {
|
function classifyOutput (script) {
|
||||||
if (witnessPubKeyHash.output.check(script)) return types.P2WPKH
|
if (witnessPubKeyHash.output.check(script)) return types.P2WPKH
|
||||||
if (witnessScriptHash.output.check(script)) return types.P2WSH
|
if (witnessScriptHash.output.check(script)) return types.P2WSH
|
||||||
@ -54,10 +57,61 @@ function classifyWitness (script, allowIncomplete) {
|
|||||||
return types.NONSTANDARD
|
return types.NONSTANDARD
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function solveOutput (scriptCode) {
|
||||||
|
if (!(scriptCode instanceof Buffer)) {
|
||||||
|
throw new Error('Argument 0 for solveScript must be a Buffer')
|
||||||
|
}
|
||||||
|
|
||||||
|
var outputType = classifyOutput(scriptCode)
|
||||||
|
var solvedBy = null
|
||||||
|
var requiredSigs = null
|
||||||
|
|
||||||
|
switch (outputType) {
|
||||||
|
// We can only determine the relevant hash from these, not if it's signable
|
||||||
|
case types.P2SH:
|
||||||
|
solvedBy = scriptHash.output.decode(scriptCode)
|
||||||
|
break
|
||||||
|
case types.P2WSH:
|
||||||
|
solvedBy = witnessScriptHash.output.decode(scriptCode)
|
||||||
|
break
|
||||||
|
|
||||||
|
// P2WPKH is separate from other signable types, it's best viewed as a special case for P2PKH
|
||||||
|
// Not included in canSign.
|
||||||
|
case types.P2WPKH:
|
||||||
|
solvedBy = witnessPubKeyHash.output.decode(scriptCode)
|
||||||
|
requiredSigs = 1
|
||||||
|
break
|
||||||
|
|
||||||
|
// We can immediately solve signatures for these
|
||||||
|
// When adding a new script type, edit here
|
||||||
|
case types.P2PK:
|
||||||
|
solvedBy = pubKey.output.decode(scriptCode)
|
||||||
|
requiredSigs = 1
|
||||||
|
break
|
||||||
|
case types.P2PKH:
|
||||||
|
solvedBy = pubKeyHash.output.decode(scriptCode)
|
||||||
|
requiredSigs = 1
|
||||||
|
break
|
||||||
|
case types.MULTISIG:
|
||||||
|
solvedBy = multisig.output.decode(scriptCode)
|
||||||
|
requiredSigs = solvedBy.m
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: outputType,
|
||||||
|
script: scriptCode,
|
||||||
|
solvedBy: solvedBy,
|
||||||
|
canSign: SIGNABLE_SCRIPTS.indexOf(outputType) !== -1,
|
||||||
|
requiredSigs: requiredSigs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
classifyInput: classifyInput,
|
classifyInput: classifyInput,
|
||||||
classifyOutput: classifyOutput,
|
classifyOutput: classifyOutput,
|
||||||
classifyWitness: classifyWitness,
|
classifyWitness: classifyWitness,
|
||||||
|
solveOutput: solveOutput,
|
||||||
multisig: multisig,
|
multisig: multisig,
|
||||||
nullData: nullData,
|
nullData: nullData,
|
||||||
pubKey: pubKey,
|
pubKey: pubKey,
|
||||||
@ -65,5 +119,7 @@ module.exports = {
|
|||||||
scriptHash: scriptHash,
|
scriptHash: scriptHash,
|
||||||
witnessPubKeyHash: witnessPubKeyHash,
|
witnessPubKeyHash: witnessPubKeyHash,
|
||||||
witnessScriptHash: witnessScriptHash,
|
witnessScriptHash: witnessScriptHash,
|
||||||
types: types
|
types: types,
|
||||||
|
SIGNABLE_SCRIPTS: SIGNABLE_SCRIPTS,
|
||||||
|
P2SH_SCRIPTS: P2SH_SCRIPTS
|
||||||
}
|
}
|
||||||
|
|||||||
@ -105,6 +105,30 @@ describe('script', function () {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('solveOutput', function () {
|
||||||
|
fixtures.valid.forEach(function (f) {
|
||||||
|
var script
|
||||||
|
if (f.scriptPubKeyHex) {
|
||||||
|
script = new Buffer(f.scriptPubKeyHex, 'hex')
|
||||||
|
} else if (f.scriptPubKey) {
|
||||||
|
script = bscript.fromASM(f.scriptPubKey)
|
||||||
|
} else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
it('solves ' + bscript.toASM(script) + ' as ' + f.type, function () {
|
||||||
|
var solution = bscript.solveOutput(script)
|
||||||
|
assert.equal(solution.type, f.type)
|
||||||
|
if ([bscript.types.P2SH].concat(bscript.P2SH_SCRIPTS).indexOf(f.type) === -1) {
|
||||||
|
assert.equal(solution.solvedBy, null)
|
||||||
|
}
|
||||||
|
if (solution.canSign) {
|
||||||
|
assert.notEqual(solution.requiredSigs, null)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe('SCRIPT_VERIFY_MINIMALDATA policy', function () {
|
describe('SCRIPT_VERIFY_MINIMALDATA policy', function () {
|
||||||
fixtures.valid.forEach(function (f) {
|
fixtures.valid.forEach(function (f) {
|
||||||
if (f.scriptSigHex) {
|
if (f.scriptSigHex) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user