Browse Source

Replace script type strings with constants

hk-custom-address
Thomas Kerin 8 years ago
committed by Daniel Cousens
parent
commit
b5e46c2931
  1. 1
      src/script.js
  2. 46
      src/templates/index.js
  3. 37
      src/transaction_builder.js

1
src/script.js

@ -11,7 +11,6 @@ var REVERSE_OPS = (function () {
} }
return result return result
})() })()
var OP_INT_BASE = OPS.OP_RESERVED // OP_1 - 1 var OP_INT_BASE = OPS.OP_RESERVED // OP_1 - 1
function compile (chunks) { function compile (chunks) {

46
src/templates/index.js

@ -6,41 +6,52 @@ var pubKeyHash = require('./pubkeyhash')
var scriptHash = require('./scripthash') var scriptHash = require('./scripthash')
var witnessPubKeyHash = require('./witnesspubkeyhash') var witnessPubKeyHash = require('./witnesspubkeyhash')
var witnessScriptHash = require('./witnessscripthash') var witnessScriptHash = require('./witnessscripthash')
var types = {
MULTISIG: 'multisig',
NONSTANDARD: 'nonstandard',
NULLDATA: 'nulldata',
P2PK: 'pubkey',
P2PKH: 'pubkeyhash',
P2SH: 'scripthash',
P2WPKH: 'witnesspubkeyhash',
P2WSH: 'witnessscripthash'
}
function classifyOutput (script) { function classifyOutput (script) {
if (witnessPubKeyHash.output.check(script)) return 'witnesspubkeyhash' if (witnessPubKeyHash.output.check(script)) return types.P2WPKH
if (witnessScriptHash.output.check(script)) return 'witnessscripthash' if (witnessScriptHash.output.check(script)) return types.P2WSH
if (pubKeyHash.output.check(script)) return 'pubkeyhash' if (pubKeyHash.output.check(script)) return types.P2PKH
if (scriptHash.output.check(script)) return 'scripthash' if (scriptHash.output.check(script)) return types.P2SH
// XXX: optimization, below functions .decompile before use // XXX: optimization, below functions .decompile before use
var chunks = decompile(script) var chunks = decompile(script)
if (multisig.output.check(chunks)) return 'multisig' if (multisig.output.check(chunks)) return types.MULTISIG
if (pubKey.output.check(chunks)) return 'pubkey' if (pubKey.output.check(chunks)) return types.P2PK
if (nullData.output.check(chunks)) return 'nulldata' if (nullData.output.check(chunks)) return types.NULLDATA
return 'nonstandard' return types.NONSTANDARD
} }
function classifyInput (script, allowIncomplete) { function classifyInput (script, allowIncomplete) {
// XXX: optimization, below functions .decompile before use // XXX: optimization, below functions .decompile before use
var chunks = decompile(script) var chunks = decompile(script)
if (pubKeyHash.input.check(chunks)) return 'pubkeyhash' if (pubKeyHash.input.check(chunks)) return types.P2PKH
if (scriptHash.input.check(chunks, allowIncomplete)) return 'scripthash' if (scriptHash.input.check(chunks, allowIncomplete)) return types.P2SH
if (multisig.input.check(chunks, allowIncomplete)) return 'multisig' if (multisig.input.check(chunks, allowIncomplete)) return types.MULTISIG
if (pubKey.input.check(chunks)) return 'pubkey' if (pubKey.input.check(chunks)) return types.P2PK
return 'nonstandard' return types.NONSTANDARD
} }
function classifyWitness (script, allowIncomplete) { function classifyWitness (script, allowIncomplete) {
// XXX: optimization, below functions .decompile before use // XXX: optimization, below functions .decompile before use
var chunks = decompile(script) var chunks = decompile(script)
if (pubKeyHash.input.check(chunks)) return 'witnesspubkeyhash' if (pubKeyHash.input.check(chunks)) return types.P2WPKH
if (scriptHash.input.check(chunks)) return 'witnessscripthash' if (scriptHash.input.check(chunks)) return types.P2WSH
return 'nonstandard'
return types.NONSTANDARD
} }
module.exports = { module.exports = {
@ -53,5 +64,6 @@ module.exports = {
pubKeyHash: pubKeyHash, pubKeyHash: pubKeyHash,
scriptHash: scriptHash, scriptHash: scriptHash,
witnessPubKeyHash: witnessPubKeyHash, witnessPubKeyHash: witnessPubKeyHash,
witnessScriptHash: witnessScriptHash witnessScriptHash: witnessScriptHash,
types: types
} }

37
src/transaction_builder.js

@ -6,6 +6,7 @@ var networks = require('./networks')
var ops = require('./opcodes.json') var ops = require('./opcodes.json')
var typeforce = require('typeforce') var typeforce = require('typeforce')
var types = require('./types') var types = require('./types')
var scriptTypes = bscript.types
var ECPair = require('./ecpair') var ECPair = require('./ecpair')
var ECSignature = require('./ecsignature') var ECSignature = require('./ecsignature')
@ -19,7 +20,7 @@ function expandInput (scriptSig, redeemScript) {
var pubKeys, signatures, prevOutScript var pubKeys, signatures, prevOutScript
switch (prevOutType) { switch (prevOutType) {
case 'scripthash': case scriptTypes.P2SH:
// FIXME: maybe depth limit instead, how possible is this anyway? // FIXME: maybe depth limit instead, how possible is this anyway?
if (redeemScript) throw new Error('Recursive P2SH script') if (redeemScript) throw new Error('Recursive P2SH script')
@ -30,10 +31,10 @@ function expandInput (scriptSig, redeemScript) {
result.redeemScript = redeemScript result.redeemScript = redeemScript
result.redeemScriptType = result.prevOutType result.redeemScriptType = result.prevOutType
result.prevOutScript = bscript.scriptHash.output.encode(bcrypto.hash160(redeemScript)) result.prevOutScript = bscript.scriptHash.output.encode(bcrypto.hash160(redeemScript))
result.prevOutType = 'scripthash' result.prevOutType = scriptTypes.P2SH
return result return result
case 'pubkeyhash': case scriptTypes.P2PKH:
// if (redeemScript) throw new Error('Nonstandard... P2SH(P2PKH)') // if (redeemScript) throw new Error('Nonstandard... P2SH(P2PKH)')
pubKeys = scriptSigChunks.slice(1) pubKeys = scriptSigChunks.slice(1)
signatures = scriptSigChunks.slice(0, 1) signatures = scriptSigChunks.slice(0, 1)
@ -42,7 +43,7 @@ function expandInput (scriptSig, redeemScript) {
prevOutScript = bscript.pubKeyHash.output.encode(bcrypto.hash160(pubKeys[0])) prevOutScript = bscript.pubKeyHash.output.encode(bcrypto.hash160(pubKeys[0]))
break break
case 'pubkey': case scriptTypes.P2PK:
if (redeemScript) { if (redeemScript) {
pubKeys = bscript.decompile(redeemScript).slice(0, 1) pubKeys = bscript.decompile(redeemScript).slice(0, 1)
} }
@ -50,7 +51,7 @@ function expandInput (scriptSig, redeemScript) {
signatures = scriptSigChunks.slice(0, 1) signatures = scriptSigChunks.slice(0, 1)
break break
case 'multisig': case scriptTypes.MULTISIG:
if (redeemScript) { if (redeemScript) {
pubKeys = bscript.decompile(redeemScript).slice(1, -2) pubKeys = bscript.decompile(redeemScript).slice(1, -2)
} }
@ -71,7 +72,7 @@ function expandInput (scriptSig, redeemScript) {
// could be done in expandInput, but requires the original Transaction for hashForSignature // could be done in expandInput, but requires the original Transaction for hashForSignature
function fixMultisigOrder (input, transaction, vin) { function fixMultisigOrder (input, transaction, vin) {
if (input.redeemScriptType !== 'multisig' || !input.redeemScript) return if (input.redeemScriptType !== scriptTypes.MULTISIG || !input.redeemScript) return
if (input.pubKeys.length === input.signatures.length) return if (input.pubKeys.length === input.signatures.length) return
var unmatched = input.signatures.concat() var unmatched = input.signatures.concat()
@ -115,7 +116,7 @@ function expandOutput (script, scriptType, ourPubKey) {
switch (scriptType) { switch (scriptType) {
// does our hash160(pubKey) match the output scripts? // does our hash160(pubKey) match the output scripts?
case 'pubkeyhash': case scriptTypes.P2PKH:
if (!ourPubKey) break if (!ourPubKey) break
var pkh1 = scriptChunks[2] var pkh1 = scriptChunks[2]
@ -123,11 +124,11 @@ function expandOutput (script, scriptType, ourPubKey) {
if (pkh1.equals(pkh2)) pubKeys = [ourPubKey] if (pkh1.equals(pkh2)) pubKeys = [ourPubKey]
break break
case 'pubkey': case scriptTypes.P2PK:
pubKeys = scriptChunks.slice(0, 1) pubKeys = scriptChunks.slice(0, 1)
break break
case 'multisig': case scriptTypes.MULTISIG:
pubKeys = scriptChunks.slice(1, -2) pubKeys = scriptChunks.slice(1, -2)
break break
@ -148,7 +149,7 @@ function prepareInput (input, kpPubKey, redeemScript) {
// if redeemScript exists, it is pay-to-scriptHash // if redeemScript exists, it is pay-to-scriptHash
// if we have a prevOutScript, enforce hash160(redeemScriptequality) to the redeemScript // if we have a prevOutScript, enforce hash160(redeemScriptequality) to the redeemScript
if (input.prevOutType) { if (input.prevOutType) {
if (input.prevOutType !== 'scripthash') throw new Error('PrevOutScript must be P2SH') if (input.prevOutType !== scriptTypes.P2SH) throw new Error('PrevOutScript must be P2SH')
var prevOutScriptScriptHash = bscript.decompile(input.prevOutScript)[1] var prevOutScriptScriptHash = bscript.decompile(input.prevOutScript)[1]
if (!prevOutScriptScriptHash.equals(redeemScriptHash)) throw new Error('Inconsistent hash160(RedeemScript)') if (!prevOutScriptScriptHash.equals(redeemScriptHash)) throw new Error('Inconsistent hash160(RedeemScript)')
@ -162,12 +163,12 @@ function prepareInput (input, kpPubKey, redeemScript) {
input.redeemScript = redeemScript input.redeemScript = redeemScript
input.redeemScriptType = expanded.scriptType input.redeemScriptType = expanded.scriptType
input.prevOutScript = input.prevOutScript || bscript.scriptHash.output.encode(redeemScriptHash) input.prevOutScript = input.prevOutScript || bscript.scriptHash.output.encode(redeemScriptHash)
input.prevOutType = 'scripthash' input.prevOutType = scriptTypes.P2SH
// maybe we have some prevOut knowledge // maybe we have some prevOut knowledge
} else if (input.prevOutType) { } else if (input.prevOutType) {
// pay-to-scriptHash is not possible without a redeemScript // pay-to-scriptHash is not possible without a redeemScript
if (input.prevOutType === 'scripthash') throw new Error('PrevOutScript is P2SH, missing redeemScript') if (input.prevOutType === scriptTypes.P2SH) throw new Error('PrevOutScript is P2SH, missing redeemScript')
// try to derive missing information using our kpPubKey // try to derive missing information using our kpPubKey
expanded = expandOutput(input.prevOutScript, input.prevOutType, kpPubKey) expanded = expandOutput(input.prevOutScript, input.prevOutType, kpPubKey)
@ -179,7 +180,7 @@ function prepareInput (input, kpPubKey, redeemScript) {
// no prior knowledge, assume pubKeyHash // no prior knowledge, assume pubKeyHash
} else { } else {
input.prevOutScript = bscript.pubKeyHash.output.encode(bcrypto.hash160(kpPubKey)) input.prevOutScript = bscript.pubKeyHash.output.encode(bcrypto.hash160(kpPubKey))
input.prevOutType = 'pubkeyhash' input.prevOutType = scriptTypes.P2PKH
input.pubKeys = [kpPubKey] input.pubKeys = [kpPubKey]
input.signatures = [undefined] input.signatures = [undefined]
} }
@ -191,10 +192,10 @@ function buildInput (input, allowIncomplete) {
var scriptSig var scriptSig
switch (scriptType) { switch (scriptType) {
case 'pubkeyhash': case scriptTypes.P2PKH:
case 'pubkey': case scriptTypes.P2PK:
if (signatures.length < 1 || !signatures[0]) throw new Error('Not enough signatures provided') if (signatures.length < 1 || !signatures[0]) throw new Error('Not enough signatures provided')
if (scriptType === 'pubkeyhash') { if (scriptType === scriptTypes.P2PKH) {
scriptSig = bscript.pubKeyHash.input.encode(signatures[0], input.pubKeys[0]) scriptSig = bscript.pubKeyHash.input.encode(signatures[0], input.pubKeys[0])
} else { } else {
scriptSig = bscript.pubKey.input.encode(signatures[0]) scriptSig = bscript.pubKey.input.encode(signatures[0])
@ -203,7 +204,7 @@ function buildInput (input, allowIncomplete) {
break break
// ref https://github.com/bitcoin/bitcoin/blob/d612837814020ae832499d18e6ee5eb919a87907/src/script/sign.cpp#L232 // ref https://github.com/bitcoin/bitcoin/blob/d612837814020ae832499d18e6ee5eb919a87907/src/script/sign.cpp#L232
case 'multisig': case scriptTypes.MULTISIG:
signatures = signatures.map(function (signature) { signatures = signatures.map(function (signature) {
return signature || ops.OP_0 return signature || ops.OP_0
}) })
@ -220,7 +221,7 @@ function buildInput (input, allowIncomplete) {
} }
// wrap as scriptHash if necessary // wrap as scriptHash if necessary
if (input.prevOutType === 'scripthash') { if (input.prevOutType === scriptTypes.P2SH) {
scriptSig = bscript.scriptHash.input.encode(scriptSig, input.redeemScript) scriptSig = bscript.scriptHash.input.encode(scriptSig, input.redeemScript)
} }

Loading…
Cancel
Save