Browse Source

P2WSH initial commit, tests pass with new logic

hk-custom-address
Thomas Kerin 8 years ago
committed by Daniel Cousens
parent
commit
3ad31571b6
  1. 118
      src/transaction_builder.js

118
src/transaction_builder.js

@ -176,54 +176,108 @@ function expandOutput (script, scriptType, ourPubKey) {
} }
} }
function prepareInput (input, kpPubKey, redeemScript) { function checkP2shInput (input, redeemScriptHash) {
if (redeemScript) { if (input.prevOutType) {
var redeemScriptHash = bcrypto.hash160(redeemScript) if (input.prevOutType !== scriptTypes.P2SH) throw new Error('PrevOutScript must be P2SH')
// if redeemScript exists, it is pay-to-scriptHash var prevOutScriptScriptHash = bscript.decompile(input.prevOutScript)[1]
// if we have a prevOutScript, enforce hash160(redeemScriptequality) to the redeemScript if (!prevOutScriptScriptHash.equals(redeemScriptHash)) throw new Error('Inconsistent hash160(RedeemScript)')
if (input.prevOutType) { }
if (input.prevOutType !== scriptTypes.P2SH) throw new Error('PrevOutScript must be P2SH') }
var prevOutScriptScriptHash = bscript.decompile(input.prevOutScript)[1] function checkP2WSHInput (input, witnessScriptHash) {
if (!prevOutScriptScriptHash.equals(redeemScriptHash)) throw new Error('Inconsistent hash160(RedeemScript)') if (input.prevOutType) {
} if (input.prevOutType !== scriptTypes.P2WSH) throw new Error('PrevOutScript must be P2WSH')
var expanded = expandOutput(redeemScript, undefined, kpPubKey) var scriptHash = bscript.decompile(input.prevOutScript)[1]
if (!expanded.pubKeys) throw new Error('RedeemScript not supported "' + bscript.toASM(redeemScript) + '"') if (!scriptHash.equals(witnessScriptHash)) throw new Error('Inconsistent hash160(WitnessScript)')
}
}
input.pubKeys = expanded.pubKeys function prepareInput (input, kpPubKey, redeemScript, witnessScript) {
input.signatures = expanded.signatures var expanded
input.redeemScript = redeemScript var prevOutType
input.redeemScriptType = expanded.scriptType var prevOutScript
input.prevOutScript = input.prevOutScript || bscript.scriptHash.output.encode(redeemScriptHash)
input.prevOutType = scriptTypes.P2SH var p2sh = false
input.witness = false var p2shType
var redeemScriptHash
// maybe we have some prevOut knowledge var witness = false
var witnessType
var witnessScriptHash
if (redeemScript && witnessScript) {
redeemScriptHash = bcrypto.hash160(redeemScript)
witnessScriptHash = bcrypto.hash256(witnessScript)
checkP2shInput(input, redeemScriptHash)
if (!redeemScript.equals(bscript.witnessScriptHash.output.encode(witnessScriptHash))) throw new Error('Witness script inconsistent with redeem script')
expanded = expandOutput(witnessScript, undefined, kpPubKey)
if (!expanded.pubKeys) throw new Error('WitnessScript not supported "' + bscript.toASM(redeemScript) + '"')
prevOutType = bscript.types.P2SH
prevOutScript = bscript.scriptHash.output.encode(redeemScriptHash)
p2sh = witness = true
p2shType = bscript.types.P2WSH
witnessType = expanded.scriptType
} else if (redeemScript) {
redeemScriptHash = bcrypto.hash160(redeemScript)
checkP2shInput(input, redeemScriptHash)
expanded = expandOutput(redeemScript, undefined, kpPubKey)
if (!expanded.pubKeys) throw new Error('RedeemScript not supported "' + bscript.toASM(redeemScript) + '"')
prevOutType = bscript.types.P2SH
prevOutScript = bscript.scriptHash.output.encode(redeemScriptHash)
p2sh = true
p2shType = expanded.scriptType
} else if (witnessScript) {
witnessScriptHash = bcrypto.hash256(witnessScript)
checkP2WSHInput(input, witnessScriptHash)
expanded = expandOutput(witnessScript, undefined, kpPubKey)
if (!expanded.pubKeys) throw new Error('WitnessScript not supported "' + bscript.toASM(redeemScript) + '"')
prevOutType = bscript.types.P2WSH
prevOutScript = bscript.witnessScriptHash.output.encode(witnessScriptHash)
witness = true
witnessType = expanded.scriptType
} else if (input.prevOutType) { } else if (input.prevOutType) {
// embedded scripts are not possible without a redeemScript // embedded scripts are not possible without a redeemScript
if (input.prevOutType === scriptTypes.P2SH || if (input.prevOutType === scriptTypes.P2SH ||
input.prevOutType === scriptTypes.P2WSH) { input.prevOutType === scriptTypes.P2WSH) {
throw new Error('PrevOutScript is ' + input.prevOutType + ', requires redeemScript') throw new Error('PrevOutScript is ' + input.prevOutType + ', requires redeemScript')
} }
// try to derive missing information using our kpPubKey prevOutType = input.prevOutType
prevOutScript = input.prevOutScript
expanded = expandOutput(input.prevOutScript, input.prevOutType, kpPubKey) expanded = expandOutput(input.prevOutScript, input.prevOutType, kpPubKey)
if (!expanded.pubKeys) return if (!expanded.pubKeys) return
input.pubKeys = expanded.pubKeys witness = (input.prevOutScript === scriptTypes.P2WPKH)
input.signatures = expanded.signatures
input.witness = (input.prevOutScript === scriptTypes.P2WPKH)
// no prior knowledge, assume pubKeyHash
} else { } else {
input.prevOutScript = bscript.pubKeyHash.output.encode(bcrypto.hash160(kpPubKey)) prevOutScript = bscript.pubKeyHash.output.encode(bcrypto.hash160(kpPubKey))
input.prevOutType = scriptTypes.P2PKH expanded = expandOutput(prevOutScript, scriptTypes.P2PKH, kpPubKey)
input.pubKeys = [kpPubKey] prevOutType = scriptTypes.P2PKH
input.signatures = [undefined] witness = false
input.witness = false }
if (p2sh) {
input.redeemScript = redeemScript
input.redeemScriptType = p2shType
} }
if (witness && witnessType === bscript.types.P2WSH) {
input.witnessScript = witnessScript
input.witnessScriptType = witnessType
}
input.pubKeys = expanded.pubKeys
input.signatures = expanded.signatures
input.prevOutScript = prevOutScript
input.prevOutType = prevOutType
input.witness = witness
} }
function buildStack (type, signatures, pubKeys, allowIncomplete) { function buildStack (type, signatures, pubKeys, allowIncomplete) {

Loading…
Cancel
Save