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'
|
||||
}
|
||||
|
||||
var SIGNABLE_SCRIPTS = [types.MULTISIG, types.P2PKH, types.P2PK]
|
||||
var P2SH_SCRIPTS = SIGNABLE_SCRIPTS.concat([types.P2WPKH, types.P2WSH])
|
||||
|
||||
function classifyOutput (script) {
|
||||
if (witnessPubKeyHash.output.check(script)) return types.P2WPKH
|
||||
if (witnessScriptHash.output.check(script)) return types.P2WSH
|
||||
@ -54,10 +57,61 @@ function classifyWitness (script, allowIncomplete) {
|
||||
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 = {
|
||||
classifyInput: classifyInput,
|
||||
classifyOutput: classifyOutput,
|
||||
classifyWitness: classifyWitness,
|
||||
solveOutput: solveOutput,
|
||||
multisig: multisig,
|
||||
nullData: nullData,
|
||||
pubKey: pubKey,
|
||||
@ -65,5 +119,7 @@ module.exports = {
|
||||
scriptHash: scriptHash,
|
||||
witnessPubKeyHash: witnessPubKeyHash,
|
||||
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 () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
if (f.scriptSigHex) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user