Refactor Psbt logic
This commit is contained in:
parent
97074f8a64
commit
7d09fe5dcb
2 changed files with 143 additions and 190 deletions
164
src/psbt.js
164
src/psbt.js
|
@ -764,13 +764,13 @@ function checkTxInputCache(cache, input) {
|
||||||
cache.__TX_IN_CACHE[key] = 1;
|
cache.__TX_IN_CACHE[key] = 1;
|
||||||
}
|
}
|
||||||
function scriptCheckerFactory(payment, paymentScriptName) {
|
function scriptCheckerFactory(payment, paymentScriptName) {
|
||||||
return (inputIndex, scriptPubKey, redeemScript) => {
|
return (inputIndex, scriptPubKey, redeemScript, ioType) => {
|
||||||
const redeemScriptOutput = payment({
|
const redeemScriptOutput = payment({
|
||||||
redeem: { output: redeemScript },
|
redeem: { output: redeemScript },
|
||||||
}).output;
|
}).output;
|
||||||
if (!scriptPubKey.equals(redeemScriptOutput)) {
|
if (!scriptPubKey.equals(redeemScriptOutput)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`${paymentScriptName} for input #${inputIndex} doesn't match the scriptPubKey in the prevout`,
|
`${paymentScriptName} for ${ioType} #${inputIndex} doesn't match the scriptPubKey in the prevout`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -877,7 +877,7 @@ function getHashForSig(inputIndex, input, cache, sighashTypes) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
let hash;
|
let hash;
|
||||||
let script;
|
let prevout;
|
||||||
if (input.nonWitnessUtxo) {
|
if (input.nonWitnessUtxo) {
|
||||||
const nonWitnessUtxoTx = nonWitnessUtxoTxFromCache(
|
const nonWitnessUtxoTx = nonWitnessUtxoTxFromCache(
|
||||||
cache,
|
cache,
|
||||||
|
@ -893,83 +893,51 @@ function getHashForSig(inputIndex, input, cache, sighashTypes) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const prevoutIndex = unsignedTx.ins[inputIndex].index;
|
const prevoutIndex = unsignedTx.ins[inputIndex].index;
|
||||||
const prevout = nonWitnessUtxoTx.outs[prevoutIndex];
|
prevout = nonWitnessUtxoTx.outs[prevoutIndex];
|
||||||
if (input.redeemScript) {
|
|
||||||
// If a redeemScript is provided, the scriptPubKey must be for that redeemScript
|
|
||||||
checkRedeemScript(inputIndex, prevout.script, input.redeemScript);
|
|
||||||
script = input.redeemScript;
|
|
||||||
} else {
|
|
||||||
script = prevout.script;
|
|
||||||
}
|
|
||||||
if (isP2WSHScript(script)) {
|
|
||||||
if (!input.witnessScript)
|
|
||||||
throw new Error('Segwit input needs witnessScript if not P2WPKH');
|
|
||||||
checkWitnessScript(inputIndex, script, input.witnessScript);
|
|
||||||
hash = unsignedTx.hashForWitnessV0(
|
|
||||||
inputIndex,
|
|
||||||
input.witnessScript,
|
|
||||||
prevout.value,
|
|
||||||
sighashType,
|
|
||||||
);
|
|
||||||
script = input.witnessScript;
|
|
||||||
} else if (isP2WPKH(script)) {
|
|
||||||
// P2WPKH uses the P2PKH template for prevoutScript when signing
|
|
||||||
const signingScript = payments.p2pkh({ hash: script.slice(2) }).output;
|
|
||||||
hash = unsignedTx.hashForWitnessV0(
|
|
||||||
inputIndex,
|
|
||||||
signingScript,
|
|
||||||
prevout.value,
|
|
||||||
sighashType,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
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
|
prevout = input.witnessUtxo;
|
||||||
if (input.redeemScript) {
|
|
||||||
// If a redeemScript is provided, the scriptPubKey must be for that redeemScript
|
|
||||||
checkRedeemScript(
|
|
||||||
inputIndex,
|
|
||||||
input.witnessUtxo.script,
|
|
||||||
input.redeemScript,
|
|
||||||
);
|
|
||||||
_script = input.redeemScript;
|
|
||||||
} else {
|
|
||||||
_script = input.witnessUtxo.script;
|
|
||||||
}
|
|
||||||
if (isP2WPKH(_script)) {
|
|
||||||
// P2WPKH uses the P2PKH template for prevoutScript when signing
|
|
||||||
const signingScript = payments.p2pkh({ hash: _script.slice(2) }).output;
|
|
||||||
hash = unsignedTx.hashForWitnessV0(
|
|
||||||
inputIndex,
|
|
||||||
signingScript,
|
|
||||||
input.witnessUtxo.value,
|
|
||||||
sighashType,
|
|
||||||
);
|
|
||||||
script = _script;
|
|
||||||
} else if (isP2WSHScript(_script)) {
|
|
||||||
if (!input.witnessScript)
|
|
||||||
throw new Error('Segwit input needs witnessScript if not P2WPKH');
|
|
||||||
checkWitnessScript(inputIndex, _script, input.witnessScript);
|
|
||||||
hash = unsignedTx.hashForWitnessV0(
|
|
||||||
inputIndex,
|
|
||||||
input.witnessScript,
|
|
||||||
input.witnessUtxo.value,
|
|
||||||
sighashType,
|
|
||||||
);
|
|
||||||
// want to make sure the script we return is the actual meaningful script
|
|
||||||
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');
|
||||||
}
|
}
|
||||||
|
const { meaningfulScript, type } = getMeaningfulScript(
|
||||||
|
prevout.script,
|
||||||
|
inputIndex,
|
||||||
|
'input',
|
||||||
|
input.redeemScript,
|
||||||
|
input.witnessScript,
|
||||||
|
);
|
||||||
|
if (['p2shp2wsh', 'p2wsh'].indexOf(type) >= 0) {
|
||||||
|
hash = unsignedTx.hashForWitnessV0(
|
||||||
|
inputIndex,
|
||||||
|
meaningfulScript,
|
||||||
|
prevout.value,
|
||||||
|
sighashType,
|
||||||
|
);
|
||||||
|
} else if (isP2WPKH(meaningfulScript)) {
|
||||||
|
// P2WPKH uses the P2PKH template for prevoutScript when signing
|
||||||
|
const signingScript = payments.p2pkh({ hash: meaningfulScript.slice(2) })
|
||||||
|
.output;
|
||||||
|
hash = unsignedTx.hashForWitnessV0(
|
||||||
|
inputIndex,
|
||||||
|
signingScript,
|
||||||
|
prevout.value,
|
||||||
|
sighashType,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// non-segwit
|
||||||
|
if (input.nonWitnessUtxo === undefined)
|
||||||
|
throw new Error(
|
||||||
|
`Input #${inputIndex} has witnessUtxo but non-segwit script: ` +
|
||||||
|
`${meaningfulScript.toString('hex')}`,
|
||||||
|
);
|
||||||
|
hash = unsignedTx.hashForSignature(
|
||||||
|
inputIndex,
|
||||||
|
meaningfulScript,
|
||||||
|
sighashType,
|
||||||
|
);
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
script,
|
script: meaningfulScript,
|
||||||
sighashType,
|
sighashType,
|
||||||
hash,
|
hash,
|
||||||
};
|
};
|
||||||
|
@ -1235,8 +1203,10 @@ function pubkeyInInput(pubkey, input, inputIndex, cache) {
|
||||||
} else {
|
} else {
|
||||||
throw new Error("Can't find pubkey in input without Utxo data");
|
throw new Error("Can't find pubkey in input without Utxo data");
|
||||||
}
|
}
|
||||||
const meaningfulScript = getMeaningfulScript(
|
const { meaningfulScript } = getMeaningfulScript(
|
||||||
script,
|
script,
|
||||||
|
inputIndex,
|
||||||
|
'input',
|
||||||
input.redeemScript,
|
input.redeemScript,
|
||||||
input.witnessScript,
|
input.witnessScript,
|
||||||
);
|
);
|
||||||
|
@ -1244,15 +1214,22 @@ function pubkeyInInput(pubkey, input, inputIndex, cache) {
|
||||||
}
|
}
|
||||||
function pubkeyInOutput(pubkey, output, outputIndex, cache) {
|
function pubkeyInOutput(pubkey, output, outputIndex, cache) {
|
||||||
const script = cache.__TX.outs[outputIndex].script;
|
const script = cache.__TX.outs[outputIndex].script;
|
||||||
const meaningfulScript = getMeaningfulScript(
|
const { meaningfulScript } = getMeaningfulScript(
|
||||||
script,
|
script,
|
||||||
|
outputIndex,
|
||||||
|
'output',
|
||||||
output.redeemScript,
|
output.redeemScript,
|
||||||
output.witnessScript,
|
output.witnessScript,
|
||||||
);
|
);
|
||||||
return pubkeyInScript(pubkey, meaningfulScript);
|
return pubkeyInScript(pubkey, meaningfulScript);
|
||||||
}
|
}
|
||||||
function getMeaningfulScript(script, redeemScript, witnessScript) {
|
function getMeaningfulScript(
|
||||||
const { p2sh, p2wsh } = payments;
|
script,
|
||||||
|
index,
|
||||||
|
ioType,
|
||||||
|
redeemScript,
|
||||||
|
witnessScript,
|
||||||
|
) {
|
||||||
const isP2SH = isP2SHScript(script);
|
const isP2SH = isP2SHScript(script);
|
||||||
const isP2SHP2WSH = isP2SH && redeemScript && isP2WSHScript(redeemScript);
|
const isP2SHP2WSH = isP2SH && redeemScript && isP2WSHScript(redeemScript);
|
||||||
const isP2WSH = isP2WSHScript(script);
|
const isP2WSH = isP2WSHScript(script);
|
||||||
|
@ -1262,31 +1239,30 @@ function getMeaningfulScript(script, redeemScript, witnessScript) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'scriptPubkey or redeemScript is P2WSH but witnessScript missing',
|
'scriptPubkey or redeemScript is P2WSH but witnessScript missing',
|
||||||
);
|
);
|
||||||
let payment;
|
|
||||||
let meaningfulScript;
|
let meaningfulScript;
|
||||||
if (isP2SHP2WSH) {
|
if (isP2SHP2WSH) {
|
||||||
meaningfulScript = witnessScript;
|
meaningfulScript = witnessScript;
|
||||||
payment = p2sh({ redeem: p2wsh({ redeem: { output: meaningfulScript } }) });
|
checkRedeemScript(index, script, redeemScript, ioType);
|
||||||
if (!payment.redeem.output.equals(redeemScript))
|
checkWitnessScript(index, redeemScript, witnessScript, ioType);
|
||||||
throw new Error('P2SHP2WSH witnessScript and redeemScript do not match');
|
|
||||||
if (!payment.output.equals(script))
|
|
||||||
throw new Error(
|
|
||||||
'P2SHP2WSH witnessScript+redeemScript and scriptPubkey do not match',
|
|
||||||
);
|
|
||||||
} else if (isP2WSH) {
|
} else if (isP2WSH) {
|
||||||
meaningfulScript = witnessScript;
|
meaningfulScript = witnessScript;
|
||||||
payment = p2wsh({ redeem: { output: meaningfulScript } });
|
checkWitnessScript(index, script, witnessScript, ioType);
|
||||||
if (!payment.output.equals(script))
|
|
||||||
throw new Error('P2WSH witnessScript and scriptPubkey do not match');
|
|
||||||
} else if (isP2SH) {
|
} else if (isP2SH) {
|
||||||
meaningfulScript = redeemScript;
|
meaningfulScript = redeemScript;
|
||||||
payment = p2sh({ redeem: { output: meaningfulScript } });
|
checkRedeemScript(index, script, redeemScript, ioType);
|
||||||
if (!payment.output.equals(script))
|
|
||||||
throw new Error('P2SH redeemScript and scriptPubkey do not match');
|
|
||||||
} else {
|
} else {
|
||||||
meaningfulScript = script;
|
meaningfulScript = script;
|
||||||
}
|
}
|
||||||
return meaningfulScript;
|
return {
|
||||||
|
meaningfulScript,
|
||||||
|
type: isP2SHP2WSH
|
||||||
|
? 'p2shp2wsh'
|
||||||
|
: isP2SH
|
||||||
|
? 'p2sh'
|
||||||
|
: isP2WSH
|
||||||
|
? 'p2wsh'
|
||||||
|
: 'raw',
|
||||||
|
};
|
||||||
}
|
}
|
||||||
function pubkeyInScript(pubkey, script) {
|
function pubkeyInScript(pubkey, script) {
|
||||||
const pubkeyHash = crypto_1.hash160(pubkey);
|
const pubkeyHash = crypto_1.hash160(pubkey);
|
||||||
|
|
169
ts_src/psbt.ts
169
ts_src/psbt.ts
|
@ -984,11 +984,12 @@ function checkTxInputCache(
|
||||||
function scriptCheckerFactory(
|
function scriptCheckerFactory(
|
||||||
payment: any,
|
payment: any,
|
||||||
paymentScriptName: string,
|
paymentScriptName: string,
|
||||||
): (idx: number, spk: Buffer, rs: Buffer) => void {
|
): (idx: number, spk: Buffer, rs: Buffer, ioType: 'input' | 'output') => void {
|
||||||
return (
|
return (
|
||||||
inputIndex: number,
|
inputIndex: number,
|
||||||
scriptPubKey: Buffer,
|
scriptPubKey: Buffer,
|
||||||
redeemScript: Buffer,
|
redeemScript: Buffer,
|
||||||
|
ioType: 'input' | 'output',
|
||||||
): void => {
|
): void => {
|
||||||
const redeemScriptOutput = payment({
|
const redeemScriptOutput = payment({
|
||||||
redeem: { output: redeemScript },
|
redeem: { output: redeemScript },
|
||||||
|
@ -996,7 +997,7 @@ function scriptCheckerFactory(
|
||||||
|
|
||||||
if (!scriptPubKey.equals(redeemScriptOutput)) {
|
if (!scriptPubKey.equals(redeemScriptOutput)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`${paymentScriptName} for input #${inputIndex} doesn't match the scriptPubKey in the prevout`,
|
`${paymentScriptName} for ${ioType} #${inputIndex} doesn't match the scriptPubKey in the prevout`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1158,7 +1159,7 @@ function getHashForSig(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
let hash: Buffer;
|
let hash: Buffer;
|
||||||
let script: Buffer;
|
let prevout: Output;
|
||||||
|
|
||||||
if (input.nonWitnessUtxo) {
|
if (input.nonWitnessUtxo) {
|
||||||
const nonWitnessUtxoTx = nonWitnessUtxoTxFromCache(
|
const nonWitnessUtxoTx = nonWitnessUtxoTxFromCache(
|
||||||
|
@ -1178,85 +1179,54 @@ function getHashForSig(
|
||||||
}
|
}
|
||||||
|
|
||||||
const prevoutIndex = unsignedTx.ins[inputIndex].index;
|
const prevoutIndex = unsignedTx.ins[inputIndex].index;
|
||||||
const prevout = nonWitnessUtxoTx.outs[prevoutIndex] as Output;
|
prevout = nonWitnessUtxoTx.outs[prevoutIndex] as Output;
|
||||||
|
|
||||||
if (input.redeemScript) {
|
|
||||||
// If a redeemScript is provided, the scriptPubKey must be for that redeemScript
|
|
||||||
checkRedeemScript(inputIndex, prevout.script, input.redeemScript);
|
|
||||||
script = input.redeemScript;
|
|
||||||
} else {
|
|
||||||
script = prevout.script;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isP2WSHScript(script)) {
|
|
||||||
if (!input.witnessScript)
|
|
||||||
throw new Error('Segwit input needs witnessScript if not P2WPKH');
|
|
||||||
checkWitnessScript(inputIndex, script, input.witnessScript);
|
|
||||||
hash = unsignedTx.hashForWitnessV0(
|
|
||||||
inputIndex,
|
|
||||||
input.witnessScript,
|
|
||||||
prevout.value,
|
|
||||||
sighashType,
|
|
||||||
);
|
|
||||||
script = input.witnessScript;
|
|
||||||
} else if (isP2WPKH(script)) {
|
|
||||||
// P2WPKH uses the P2PKH template for prevoutScript when signing
|
|
||||||
const signingScript = payments.p2pkh({ hash: script.slice(2) }).output!;
|
|
||||||
hash = unsignedTx.hashForWitnessV0(
|
|
||||||
inputIndex,
|
|
||||||
signingScript,
|
|
||||||
prevout.value,
|
|
||||||
sighashType,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
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
|
prevout = input.witnessUtxo;
|
||||||
if (input.redeemScript) {
|
|
||||||
// If a redeemScript is provided, the scriptPubKey must be for that redeemScript
|
|
||||||
checkRedeemScript(
|
|
||||||
inputIndex,
|
|
||||||
input.witnessUtxo.script,
|
|
||||||
input.redeemScript,
|
|
||||||
);
|
|
||||||
_script = input.redeemScript;
|
|
||||||
} else {
|
|
||||||
_script = input.witnessUtxo.script;
|
|
||||||
}
|
|
||||||
if (isP2WPKH(_script)) {
|
|
||||||
// P2WPKH uses the P2PKH template for prevoutScript when signing
|
|
||||||
const signingScript = payments.p2pkh({ hash: _script.slice(2) }).output!;
|
|
||||||
hash = unsignedTx.hashForWitnessV0(
|
|
||||||
inputIndex,
|
|
||||||
signingScript,
|
|
||||||
input.witnessUtxo.value,
|
|
||||||
sighashType,
|
|
||||||
);
|
|
||||||
script = _script;
|
|
||||||
} else if (isP2WSHScript(_script)) {
|
|
||||||
if (!input.witnessScript)
|
|
||||||
throw new Error('Segwit input needs witnessScript if not P2WPKH');
|
|
||||||
checkWitnessScript(inputIndex, _script, input.witnessScript);
|
|
||||||
hash = unsignedTx.hashForWitnessV0(
|
|
||||||
inputIndex,
|
|
||||||
input.witnessScript,
|
|
||||||
input.witnessUtxo.value,
|
|
||||||
sighashType,
|
|
||||||
);
|
|
||||||
// want to make sure the script we return is the actual meaningful script
|
|
||||||
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');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { meaningfulScript, type } = getMeaningfulScript(
|
||||||
|
prevout.script,
|
||||||
|
inputIndex,
|
||||||
|
'input',
|
||||||
|
input.redeemScript,
|
||||||
|
input.witnessScript,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (['p2shp2wsh', 'p2wsh'].indexOf(type) >= 0) {
|
||||||
|
hash = unsignedTx.hashForWitnessV0(
|
||||||
|
inputIndex,
|
||||||
|
meaningfulScript,
|
||||||
|
prevout.value,
|
||||||
|
sighashType,
|
||||||
|
);
|
||||||
|
} else if (isP2WPKH(meaningfulScript)) {
|
||||||
|
// P2WPKH uses the P2PKH template for prevoutScript when signing
|
||||||
|
const signingScript = payments.p2pkh({ hash: meaningfulScript.slice(2) })
|
||||||
|
.output!;
|
||||||
|
hash = unsignedTx.hashForWitnessV0(
|
||||||
|
inputIndex,
|
||||||
|
signingScript,
|
||||||
|
prevout.value,
|
||||||
|
sighashType,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// non-segwit
|
||||||
|
if (input.nonWitnessUtxo === undefined)
|
||||||
|
throw new Error(
|
||||||
|
`Input #${inputIndex} has witnessUtxo but non-segwit script: ` +
|
||||||
|
`${meaningfulScript.toString('hex')}`,
|
||||||
|
);
|
||||||
|
hash = unsignedTx.hashForSignature(
|
||||||
|
inputIndex,
|
||||||
|
meaningfulScript,
|
||||||
|
sighashType,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
script,
|
script: meaningfulScript,
|
||||||
sighashType,
|
sighashType,
|
||||||
hash,
|
hash,
|
||||||
};
|
};
|
||||||
|
@ -1587,8 +1557,10 @@ function pubkeyInInput(
|
||||||
} else {
|
} else {
|
||||||
throw new Error("Can't find pubkey in input without Utxo data");
|
throw new Error("Can't find pubkey in input without Utxo data");
|
||||||
}
|
}
|
||||||
const meaningfulScript = getMeaningfulScript(
|
const { meaningfulScript } = getMeaningfulScript(
|
||||||
script,
|
script,
|
||||||
|
inputIndex,
|
||||||
|
'input',
|
||||||
input.redeemScript,
|
input.redeemScript,
|
||||||
input.witnessScript,
|
input.witnessScript,
|
||||||
);
|
);
|
||||||
|
@ -1602,8 +1574,10 @@ function pubkeyInOutput(
|
||||||
cache: PsbtCache,
|
cache: PsbtCache,
|
||||||
): boolean {
|
): boolean {
|
||||||
const script = cache.__TX.outs[outputIndex].script;
|
const script = cache.__TX.outs[outputIndex].script;
|
||||||
const meaningfulScript = getMeaningfulScript(
|
const { meaningfulScript } = getMeaningfulScript(
|
||||||
script,
|
script,
|
||||||
|
outputIndex,
|
||||||
|
'output',
|
||||||
output.redeemScript,
|
output.redeemScript,
|
||||||
output.witnessScript,
|
output.witnessScript,
|
||||||
);
|
);
|
||||||
|
@ -1612,10 +1586,14 @@ function pubkeyInOutput(
|
||||||
|
|
||||||
function getMeaningfulScript(
|
function getMeaningfulScript(
|
||||||
script: Buffer,
|
script: Buffer,
|
||||||
|
index: number,
|
||||||
|
ioType: 'input' | 'output',
|
||||||
redeemScript?: Buffer,
|
redeemScript?: Buffer,
|
||||||
witnessScript?: Buffer,
|
witnessScript?: Buffer,
|
||||||
): Buffer {
|
): {
|
||||||
const { p2sh, p2wsh } = payments;
|
meaningfulScript: Buffer;
|
||||||
|
type: 'p2sh' | 'p2wsh' | 'p2shp2wsh' | 'raw';
|
||||||
|
} {
|
||||||
const isP2SH = isP2SHScript(script);
|
const isP2SH = isP2SHScript(script);
|
||||||
const isP2SHP2WSH = isP2SH && redeemScript && isP2WSHScript(redeemScript);
|
const isP2SHP2WSH = isP2SH && redeemScript && isP2WSHScript(redeemScript);
|
||||||
const isP2WSH = isP2WSHScript(script);
|
const isP2WSH = isP2WSHScript(script);
|
||||||
|
@ -1627,32 +1605,31 @@ function getMeaningfulScript(
|
||||||
'scriptPubkey or redeemScript is P2WSH but witnessScript missing',
|
'scriptPubkey or redeemScript is P2WSH but witnessScript missing',
|
||||||
);
|
);
|
||||||
|
|
||||||
let payment: payments.Payment;
|
|
||||||
let meaningfulScript: Buffer;
|
let meaningfulScript: Buffer;
|
||||||
|
|
||||||
if (isP2SHP2WSH) {
|
if (isP2SHP2WSH) {
|
||||||
meaningfulScript = witnessScript!;
|
meaningfulScript = witnessScript!;
|
||||||
payment = p2sh({ redeem: p2wsh({ redeem: { output: meaningfulScript } }) });
|
checkRedeemScript(index, script, redeemScript!, ioType);
|
||||||
if (!payment.redeem!.output!.equals(redeemScript!))
|
checkWitnessScript(index, redeemScript!, witnessScript!, ioType);
|
||||||
throw new Error('P2SHP2WSH witnessScript and redeemScript do not match');
|
|
||||||
if (!payment.output!.equals(script!))
|
|
||||||
throw new Error(
|
|
||||||
'P2SHP2WSH witnessScript+redeemScript and scriptPubkey do not match',
|
|
||||||
);
|
|
||||||
} else if (isP2WSH) {
|
} else if (isP2WSH) {
|
||||||
meaningfulScript = witnessScript!;
|
meaningfulScript = witnessScript!;
|
||||||
payment = p2wsh({ redeem: { output: meaningfulScript } });
|
checkWitnessScript(index, script, witnessScript!, ioType);
|
||||||
if (!payment.output!.equals(script!))
|
|
||||||
throw new Error('P2WSH witnessScript and scriptPubkey do not match');
|
|
||||||
} else if (isP2SH) {
|
} else if (isP2SH) {
|
||||||
meaningfulScript = redeemScript!;
|
meaningfulScript = redeemScript!;
|
||||||
payment = p2sh({ redeem: { output: meaningfulScript } });
|
checkRedeemScript(index, script, redeemScript!, ioType);
|
||||||
if (!payment.output!.equals(script!))
|
|
||||||
throw new Error('P2SH redeemScript and scriptPubkey do not match');
|
|
||||||
} else {
|
} else {
|
||||||
meaningfulScript = script;
|
meaningfulScript = script;
|
||||||
}
|
}
|
||||||
return meaningfulScript;
|
return {
|
||||||
|
meaningfulScript,
|
||||||
|
type: isP2SHP2WSH
|
||||||
|
? 'p2shp2wsh'
|
||||||
|
: isP2SH
|
||||||
|
? 'p2sh'
|
||||||
|
: isP2WSH
|
||||||
|
? 'p2wsh'
|
||||||
|
: 'raw',
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function pubkeyInScript(pubkey: Buffer, script: Buffer): boolean {
|
function pubkeyInScript(pubkey: Buffer, script: Buffer): boolean {
|
||||||
|
|
Loading…
Add table
Reference in a new issue