Skip to content

Commit af8f41a

Browse files
authored
Merge pull request #1439 from bitcoinjs/checkFinalizedSighash
Check signatures for finalized inputs too
2 parents 87c80d0 + 06b38a7 commit af8f41a

File tree

3 files changed

+48
-4
lines changed

3 files changed

+48
-4
lines changed

src/psbt.js

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -626,8 +626,14 @@ function checkFees(psbt, cache, opts) {
626626
function checkInputsForPartialSig(inputs, action) {
627627
inputs.forEach(input => {
628628
let throws = false;
629-
if ((input.partialSig || []).length === 0) return;
630-
input.partialSig.forEach(pSig => {
629+
let pSigs = [];
630+
if ((input.partialSig || []).length === 0) {
631+
if (!input.finalScriptSig && !input.finalScriptWitness) return;
632+
pSigs = getPsigsFromInputFinalScripts(input);
633+
} else {
634+
pSigs = input.partialSig;
635+
}
636+
pSigs.forEach(pSig => {
631637
const { hashType } = bscript.signature.decode(pSig.signature);
632638
const whitelist = [];
633639
const isAnyoneCanPay =
@@ -899,6 +905,20 @@ function getPayment(script, scriptType, partialSig) {
899905
}
900906
return payment;
901907
}
908+
function getPsigsFromInputFinalScripts(input) {
909+
const scriptItems = !input.finalScriptSig
910+
? []
911+
: bscript.decompile(input.finalScriptSig) || [];
912+
const witnessItems = !input.finalScriptWitness
913+
? []
914+
: bscript.decompile(input.finalScriptWitness) || [];
915+
return scriptItems
916+
.concat(witnessItems)
917+
.filter(item => {
918+
return Buffer.isBuffer(item) && bscript.isCanonicalScriptSignature(item);
919+
})
920+
.map(sig => ({ signature: sig }));
921+
}
902922
function getScriptFromInput(inputIndex, input, cache) {
903923
const unsignedTx = cache.__TX;
904924
const res = {

test/psbt.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,9 @@ describe(`Psbt`, () => {
625625
}, new RegExp('Can not modify transaction, signatures exist.'))
626626
psbt.validateSignaturesOfInput(0)
627627
psbt.finalizeAllInputs()
628+
assert.throws(() => {
629+
psbt.setVersion(3)
630+
}, new RegExp('Can not modify transaction, signatures exist.'))
628631
assert.strictEqual(
629632
psbt.extractTransaction().toHex(),
630633
'02000000013ebc8203037dda39d482bf41ff3be955996c50d9d4f7cfc3d2097a694a7' +

ts_src/psbt.ts

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -795,8 +795,14 @@ function checkFees(psbt: Psbt, cache: PsbtCache, opts: PsbtOpts): void {
795795
function checkInputsForPartialSig(inputs: PsbtInput[], action: string): void {
796796
inputs.forEach(input => {
797797
let throws = false;
798-
if ((input.partialSig || []).length === 0) return;
799-
input.partialSig!.forEach(pSig => {
798+
let pSigs: PartialSig[] = [];
799+
if ((input.partialSig || []).length === 0) {
800+
if (!input.finalScriptSig && !input.finalScriptWitness) return;
801+
pSigs = getPsigsFromInputFinalScripts(input);
802+
} else {
803+
pSigs = input.partialSig!;
804+
}
805+
pSigs.forEach(pSig => {
800806
const { hashType } = bscript.signature.decode(pSig.signature);
801807
const whitelist: string[] = [];
802808
const isAnyoneCanPay = hashType & Transaction.SIGHASH_ANYONECANPAY;
@@ -1121,6 +1127,21 @@ function getPayment(
11211127
return payment!;
11221128
}
11231129

1130+
function getPsigsFromInputFinalScripts(input: PsbtInput): PartialSig[] {
1131+
const scriptItems = !input.finalScriptSig
1132+
? []
1133+
: bscript.decompile(input.finalScriptSig) || [];
1134+
const witnessItems = !input.finalScriptWitness
1135+
? []
1136+
: bscript.decompile(input.finalScriptWitness) || [];
1137+
return scriptItems
1138+
.concat(witnessItems)
1139+
.filter(item => {
1140+
return Buffer.isBuffer(item) && bscript.isCanonicalScriptSignature(item);
1141+
})
1142+
.map(sig => ({ signature: sig })) as PartialSig[];
1143+
}
1144+
11241145
interface GetScriptReturn {
11251146
script: Buffer | null;
11261147
isSegwit: boolean;

0 commit comments

Comments
 (0)