Fix: P2WPKH was signing with nonWitnessUtxo
This commit is contained in:
parent
8a5104c333
commit
2f1609b918
3 changed files with 29 additions and 21 deletions
23
src/psbt.js
23
src/psbt.js
|
@ -404,6 +404,7 @@ const isP2MS = isPaymentFactory(payments.p2ms);
|
||||||
const isP2PK = isPaymentFactory(payments.p2pk);
|
const isP2PK = isPaymentFactory(payments.p2pk);
|
||||||
const isP2PKH = isPaymentFactory(payments.p2pkh);
|
const isP2PKH = isPaymentFactory(payments.p2pkh);
|
||||||
const isP2WPKH = isPaymentFactory(payments.p2wpkh);
|
const isP2WPKH = isPaymentFactory(payments.p2wpkh);
|
||||||
|
const isP2WSHScript = isPaymentFactory(payments.p2wsh);
|
||||||
function check32Bit(num) {
|
function check32Bit(num) {
|
||||||
if (
|
if (
|
||||||
typeof num !== 'number' ||
|
typeof num !== 'number' ||
|
||||||
|
@ -611,19 +612,16 @@ function getHashForSig(inputIndex, input, cache, sighashTypes) {
|
||||||
// If a redeemScript is provided, the scriptPubKey must be for that redeemScript
|
// If a redeemScript is provided, the scriptPubKey must be for that redeemScript
|
||||||
checkRedeemScript(inputIndex, prevout.script, input.redeemScript);
|
checkRedeemScript(inputIndex, prevout.script, input.redeemScript);
|
||||||
script = input.redeemScript;
|
script = input.redeemScript;
|
||||||
hash = unsignedTx.hashForSignature(
|
|
||||||
inputIndex,
|
|
||||||
input.redeemScript,
|
|
||||||
sighashType,
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
script = prevout.script;
|
script = prevout.script;
|
||||||
hash = unsignedTx.hashForSignature(
|
}
|
||||||
inputIndex,
|
if (isP2WPKH(script) || isP2WSHScript(script)) {
|
||||||
prevout.script,
|
throw new Error(
|
||||||
sighashType,
|
`Input #${inputIndex} has nonWitnessUtxo but segwit script: ` +
|
||||||
|
`${script.toString('hex')}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
hash = unsignedTx.hashForSignature(inputIndex, script, sighashType);
|
||||||
} else if (input.witnessUtxo) {
|
} else if (input.witnessUtxo) {
|
||||||
let _script; // so we don't shadow the `let script` above
|
let _script; // so we don't shadow the `let script` above
|
||||||
if (input.redeemScript) {
|
if (input.redeemScript) {
|
||||||
|
@ -647,7 +645,7 @@ function getHashForSig(inputIndex, input, cache, sighashTypes) {
|
||||||
sighashType,
|
sighashType,
|
||||||
);
|
);
|
||||||
script = _script;
|
script = _script;
|
||||||
} else {
|
} else if (isP2WSHScript(_script)) {
|
||||||
if (!input.witnessScript)
|
if (!input.witnessScript)
|
||||||
throw new Error('Segwit input needs witnessScript if not P2WPKH');
|
throw new Error('Segwit input needs witnessScript if not P2WPKH');
|
||||||
checkWitnessScript(inputIndex, _script, input.witnessScript);
|
checkWitnessScript(inputIndex, _script, input.witnessScript);
|
||||||
|
@ -659,6 +657,11 @@ function getHashForSig(inputIndex, input, cache, sighashTypes) {
|
||||||
);
|
);
|
||||||
// want to make sure the script we return is the actual meaningful script
|
// want to make sure the script we return is the actual meaningful script
|
||||||
script = input.witnessScript;
|
script = input.witnessScript;
|
||||||
|
} else {
|
||||||
|
throw new Error(
|
||||||
|
`Input #${inputIndex} has witnessUtxo but non-segwit script: ` +
|
||||||
|
`${_script.toString('hex')}`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Need a Utxo input item for signing');
|
throw new Error('Need a Utxo input item for signing');
|
||||||
|
|
2
test/fixtures/psbt.json
vendored
2
test/fixtures/psbt.json
vendored
|
@ -121,7 +121,7 @@
|
||||||
"failSignChecks": [
|
"failSignChecks": [
|
||||||
{
|
{
|
||||||
"description": "A Witness UTXO is provided for a non-witness input",
|
"description": "A Witness UTXO is provided for a non-witness input",
|
||||||
"errorMessage": "Segwit input needs witnessScript if not P2WPKH",
|
"errorMessage": "Input #0 has witnessUtxo but non-segwit script",
|
||||||
"psbt": "cHNidP8BAKACAAAAAqsJSaCMWvfEm4IS9Bfi8Vqz9cM9zxU4IagTn4d6W3vkAAAAAAD+////qwlJoIxa98SbghL0F+LxWrP1wz3PFTghqBOfh3pbe+QBAAAAAP7///8CYDvqCwAAAAAZdqkUdopAu9dAy+gdmI5x3ipNXHE5ax2IrI4kAAAAAAAAGXapFG9GILVT+glechue4O/p+gOcykWXiKwAAAAAAAEBItPf9QUAAAAAGXapFNSO0xELlAFMsRS9Mtb00GbcdCVriKwAAQEgAOH1BQAAAAAXqRQ1RebjO4MsRwUPJNPuuTycA5SLx4cBBBYAFIXRNTfy4mVAWjTbr6nj3aAfuCMIACICAurVlmh8qAYEPtw94RbN8p1eklfBls0FXPaYyNAr8k6ZELSmumcAAACAAAAAgAIAAIAAIgIDlPYr6d8ZlSxVh3aK63aYBhrSxKJciU9H2MFitNchPQUQtKa6ZwAAAIABAACAAgAAgAA=",
|
"psbt": "cHNidP8BAKACAAAAAqsJSaCMWvfEm4IS9Bfi8Vqz9cM9zxU4IagTn4d6W3vkAAAAAAD+////qwlJoIxa98SbghL0F+LxWrP1wz3PFTghqBOfh3pbe+QBAAAAAP7///8CYDvqCwAAAAAZdqkUdopAu9dAy+gdmI5x3ipNXHE5ax2IrI4kAAAAAAAAGXapFG9GILVT+glechue4O/p+gOcykWXiKwAAAAAAAEBItPf9QUAAAAAGXapFNSO0xELlAFMsRS9Mtb00GbcdCVriKwAAQEgAOH1BQAAAAAXqRQ1RebjO4MsRwUPJNPuuTycA5SLx4cBBBYAFIXRNTfy4mVAWjTbr6nj3aAfuCMIACICAurVlmh8qAYEPtw94RbN8p1eklfBls0FXPaYyNAr8k6ZELSmumcAAACAAAAAgAIAAIAAIgIDlPYr6d8ZlSxVh3aK63aYBhrSxKJciU9H2MFitNchPQUQtKa6ZwAAAIABAACAAgAAgAA=",
|
||||||
"inputToCheck": 0
|
"inputToCheck": 0
|
||||||
},
|
},
|
||||||
|
|
|
@ -509,6 +509,7 @@ const isP2MS = isPaymentFactory(payments.p2ms);
|
||||||
const isP2PK = isPaymentFactory(payments.p2pk);
|
const isP2PK = isPaymentFactory(payments.p2pk);
|
||||||
const isP2PKH = isPaymentFactory(payments.p2pkh);
|
const isP2PKH = isPaymentFactory(payments.p2pkh);
|
||||||
const isP2WPKH = isPaymentFactory(payments.p2wpkh);
|
const isP2WPKH = isPaymentFactory(payments.p2wpkh);
|
||||||
|
const isP2WSHScript = isPaymentFactory(payments.p2wsh);
|
||||||
|
|
||||||
function check32Bit(num: number): void {
|
function check32Bit(num: number): void {
|
||||||
if (
|
if (
|
||||||
|
@ -764,19 +765,18 @@ function getHashForSig(
|
||||||
// If a redeemScript is provided, the scriptPubKey must be for that redeemScript
|
// If a redeemScript is provided, the scriptPubKey must be for that redeemScript
|
||||||
checkRedeemScript(inputIndex, prevout.script, input.redeemScript);
|
checkRedeemScript(inputIndex, prevout.script, input.redeemScript);
|
||||||
script = input.redeemScript;
|
script = input.redeemScript;
|
||||||
hash = unsignedTx.hashForSignature(
|
|
||||||
inputIndex,
|
|
||||||
input.redeemScript,
|
|
||||||
sighashType,
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
script = prevout.script;
|
script = prevout.script;
|
||||||
hash = unsignedTx.hashForSignature(
|
}
|
||||||
inputIndex,
|
|
||||||
prevout.script,
|
if (isP2WPKH(script) || isP2WSHScript(script)) {
|
||||||
sighashType,
|
throw new Error(
|
||||||
|
`Input #${inputIndex} has nonWitnessUtxo but segwit script: ` +
|
||||||
|
`${script.toString('hex')}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hash = unsignedTx.hashForSignature(inputIndex, script, sighashType);
|
||||||
} else if (input.witnessUtxo) {
|
} else if (input.witnessUtxo) {
|
||||||
let _script: Buffer; // so we don't shadow the `let script` above
|
let _script: Buffer; // so we don't shadow the `let script` above
|
||||||
if (input.redeemScript) {
|
if (input.redeemScript) {
|
||||||
|
@ -800,7 +800,7 @@ function getHashForSig(
|
||||||
sighashType,
|
sighashType,
|
||||||
);
|
);
|
||||||
script = _script;
|
script = _script;
|
||||||
} else {
|
} else if (isP2WSHScript(_script)) {
|
||||||
if (!input.witnessScript)
|
if (!input.witnessScript)
|
||||||
throw new Error('Segwit input needs witnessScript if not P2WPKH');
|
throw new Error('Segwit input needs witnessScript if not P2WPKH');
|
||||||
checkWitnessScript(inputIndex, _script, input.witnessScript);
|
checkWitnessScript(inputIndex, _script, input.witnessScript);
|
||||||
|
@ -812,6 +812,11 @@ function getHashForSig(
|
||||||
);
|
);
|
||||||
// want to make sure the script we return is the actual meaningful script
|
// want to make sure the script we return is the actual meaningful script
|
||||||
script = input.witnessScript;
|
script = input.witnessScript;
|
||||||
|
} else {
|
||||||
|
throw new Error(
|
||||||
|
`Input #${inputIndex} has witnessUtxo but non-segwit script: ` +
|
||||||
|
`${_script.toString('hex')}`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Need a Utxo input item for signing');
|
throw new Error('Need a Utxo input item for signing');
|
||||||
|
|
Loading…
Add table
Reference in a new issue