@@ -764,13 +764,13 @@ function checkTxInputCache(cache, input) {
764
764
cache . __TX_IN_CACHE [ key ] = 1 ;
765
765
}
766
766
function scriptCheckerFactory ( payment , paymentScriptName ) {
767
- return ( inputIndex , scriptPubKey , redeemScript ) => {
767
+ return ( inputIndex , scriptPubKey , redeemScript , ioType ) => {
768
768
const redeemScriptOutput = payment ( {
769
769
redeem : { output : redeemScript } ,
770
770
} ) . output ;
771
771
if ( ! scriptPubKey . equals ( redeemScriptOutput ) ) {
772
772
throw new Error (
773
- `${ paymentScriptName } for input #${ inputIndex } doesn't match the scriptPubKey in the prevout` ,
773
+ `${ paymentScriptName } for ${ ioType } #${ inputIndex } doesn't match the scriptPubKey in the prevout` ,
774
774
) ;
775
775
}
776
776
} ;
@@ -877,7 +877,7 @@ function getHashForSig(inputIndex, input, cache, sighashTypes) {
877
877
) ;
878
878
}
879
879
let hash ;
880
- let script ;
880
+ let prevout ;
881
881
if ( input . nonWitnessUtxo ) {
882
882
const nonWitnessUtxoTx = nonWitnessUtxoTxFromCache (
883
883
cache ,
@@ -893,83 +893,51 @@ function getHashForSig(inputIndex, input, cache, sighashTypes) {
893
893
) ;
894
894
}
895
895
const prevoutIndex = unsignedTx . ins [ inputIndex ] . index ;
896
- const prevout = nonWitnessUtxoTx . outs [ prevoutIndex ] ;
897
- if ( input . redeemScript ) {
898
- // If a redeemScript is provided, the scriptPubKey must be for that redeemScript
899
- checkRedeemScript ( inputIndex , prevout . script , input . redeemScript ) ;
900
- script = input . redeemScript ;
901
- } else {
902
- script = prevout . script ;
903
- }
904
- if ( isP2WSHScript ( script ) ) {
905
- if ( ! input . witnessScript )
906
- throw new Error ( 'Segwit input needs witnessScript if not P2WPKH' ) ;
907
- checkWitnessScript ( inputIndex , script , input . witnessScript ) ;
908
- hash = unsignedTx . hashForWitnessV0 (
909
- inputIndex ,
910
- input . witnessScript ,
911
- prevout . value ,
912
- sighashType ,
913
- ) ;
914
- script = input . witnessScript ;
915
- } else if ( isP2WPKH ( script ) ) {
916
- // P2WPKH uses the P2PKH template for prevoutScript when signing
917
- const signingScript = payments . p2pkh ( { hash : script . slice ( 2 ) } ) . output ;
918
- hash = unsignedTx . hashForWitnessV0 (
919
- inputIndex ,
920
- signingScript ,
921
- prevout . value ,
922
- sighashType ,
923
- ) ;
924
- } else {
925
- hash = unsignedTx . hashForSignature ( inputIndex , script , sighashType ) ;
926
- }
896
+ prevout = nonWitnessUtxoTx . outs [ prevoutIndex ] ;
927
897
} else if ( input . witnessUtxo ) {
928
- let _script ; // so we don't shadow the `let script` above
929
- if ( input . redeemScript ) {
930
- // If a redeemScript is provided, the scriptPubKey must be for that redeemScript
931
- checkRedeemScript (
932
- inputIndex ,
933
- input . witnessUtxo . script ,
934
- input . redeemScript ,
935
- ) ;
936
- _script = input . redeemScript ;
937
- } else {
938
- _script = input . witnessUtxo . script ;
939
- }
940
- if ( isP2WPKH ( _script ) ) {
941
- // P2WPKH uses the P2PKH template for prevoutScript when signing
942
- const signingScript = payments . p2pkh ( { hash : _script . slice ( 2 ) } ) . output ;
943
- hash = unsignedTx . hashForWitnessV0 (
944
- inputIndex ,
945
- signingScript ,
946
- input . witnessUtxo . value ,
947
- sighashType ,
948
- ) ;
949
- script = _script ;
950
- } else if ( isP2WSHScript ( _script ) ) {
951
- if ( ! input . witnessScript )
952
- throw new Error ( 'Segwit input needs witnessScript if not P2WPKH' ) ;
953
- checkWitnessScript ( inputIndex , _script , input . witnessScript ) ;
954
- hash = unsignedTx . hashForWitnessV0 (
955
- inputIndex ,
956
- input . witnessScript ,
957
- input . witnessUtxo . value ,
958
- sighashType ,
959
- ) ;
960
- // want to make sure the script we return is the actual meaningful script
961
- script = input . witnessScript ;
962
- } else {
898
+ prevout = input . witnessUtxo ;
899
+ } else {
900
+ throw new Error ( 'Need a Utxo input item for signing' ) ;
901
+ }
902
+ const { meaningfulScript, type } = getMeaningfulScript (
903
+ prevout . script ,
904
+ inputIndex ,
905
+ 'input' ,
906
+ input . redeemScript ,
907
+ input . witnessScript ,
908
+ ) ;
909
+ if ( [ 'p2shp2wsh' , 'p2wsh' ] . indexOf ( type ) >= 0 ) {
910
+ hash = unsignedTx . hashForWitnessV0 (
911
+ inputIndex ,
912
+ meaningfulScript ,
913
+ prevout . value ,
914
+ sighashType ,
915
+ ) ;
916
+ } else if ( isP2WPKH ( meaningfulScript ) ) {
917
+ // P2WPKH uses the P2PKH template for prevoutScript when signing
918
+ const signingScript = payments . p2pkh ( { hash : meaningfulScript . slice ( 2 ) } )
919
+ . output ;
920
+ hash = unsignedTx . hashForWitnessV0 (
921
+ inputIndex ,
922
+ signingScript ,
923
+ prevout . value ,
924
+ sighashType ,
925
+ ) ;
926
+ } else {
927
+ // non-segwit
928
+ if ( input . nonWitnessUtxo === undefined )
963
929
throw new Error (
964
930
`Input #${ inputIndex } has witnessUtxo but non-segwit script: ` +
965
- `${ _script . toString ( 'hex' ) } ` ,
931
+ `${ meaningfulScript . toString ( 'hex' ) } ` ,
966
932
) ;
967
- }
968
- } else {
969
- throw new Error ( 'Need a Utxo input item for signing' ) ;
933
+ hash = unsignedTx . hashForSignature (
934
+ inputIndex ,
935
+ meaningfulScript ,
936
+ sighashType ,
937
+ ) ;
970
938
}
971
939
return {
972
- script,
940
+ script : meaningfulScript ,
973
941
sighashType,
974
942
hash,
975
943
} ;
@@ -1235,24 +1203,33 @@ function pubkeyInInput(pubkey, input, inputIndex, cache) {
1235
1203
} else {
1236
1204
throw new Error ( "Can't find pubkey in input without Utxo data" ) ;
1237
1205
}
1238
- const meaningfulScript = getMeaningfulScript (
1206
+ const { meaningfulScript } = getMeaningfulScript (
1239
1207
script ,
1208
+ inputIndex ,
1209
+ 'input' ,
1240
1210
input . redeemScript ,
1241
1211
input . witnessScript ,
1242
1212
) ;
1243
1213
return pubkeyInScript ( pubkey , meaningfulScript ) ;
1244
1214
}
1245
1215
function pubkeyInOutput ( pubkey , output , outputIndex , cache ) {
1246
1216
const script = cache . __TX . outs [ outputIndex ] . script ;
1247
- const meaningfulScript = getMeaningfulScript (
1217
+ const { meaningfulScript } = getMeaningfulScript (
1248
1218
script ,
1219
+ outputIndex ,
1220
+ 'output' ,
1249
1221
output . redeemScript ,
1250
1222
output . witnessScript ,
1251
1223
) ;
1252
1224
return pubkeyInScript ( pubkey , meaningfulScript ) ;
1253
1225
}
1254
- function getMeaningfulScript ( script , redeemScript , witnessScript ) {
1255
- const { p2sh, p2wsh } = payments ;
1226
+ function getMeaningfulScript (
1227
+ script ,
1228
+ index ,
1229
+ ioType ,
1230
+ redeemScript ,
1231
+ witnessScript ,
1232
+ ) {
1256
1233
const isP2SH = isP2SHScript ( script ) ;
1257
1234
const isP2SHP2WSH = isP2SH && redeemScript && isP2WSHScript ( redeemScript ) ;
1258
1235
const isP2WSH = isP2WSHScript ( script ) ;
@@ -1262,31 +1239,30 @@ function getMeaningfulScript(script, redeemScript, witnessScript) {
1262
1239
throw new Error (
1263
1240
'scriptPubkey or redeemScript is P2WSH but witnessScript missing' ,
1264
1241
) ;
1265
- let payment ;
1266
1242
let meaningfulScript ;
1267
1243
if ( isP2SHP2WSH ) {
1268
1244
meaningfulScript = witnessScript ;
1269
- payment = p2sh ( { redeem : p2wsh ( { redeem : { output : meaningfulScript } } ) } ) ;
1270
- if ( ! payment . redeem . output . equals ( redeemScript ) )
1271
- throw new Error ( 'P2SHP2WSH witnessScript and redeemScript do not match' ) ;
1272
- if ( ! payment . output . equals ( script ) )
1273
- throw new Error (
1274
- 'P2SHP2WSH witnessScript+redeemScript and scriptPubkey do not match' ,
1275
- ) ;
1245
+ checkRedeemScript ( index , script , redeemScript , ioType ) ;
1246
+ checkWitnessScript ( index , redeemScript , witnessScript , ioType ) ;
1276
1247
} else if ( isP2WSH ) {
1277
1248
meaningfulScript = witnessScript ;
1278
- payment = p2wsh ( { redeem : { output : meaningfulScript } } ) ;
1279
- if ( ! payment . output . equals ( script ) )
1280
- throw new Error ( 'P2WSH witnessScript and scriptPubkey do not match' ) ;
1249
+ checkWitnessScript ( index , script , witnessScript , ioType ) ;
1281
1250
} else if ( isP2SH ) {
1282
1251
meaningfulScript = redeemScript ;
1283
- payment = p2sh ( { redeem : { output : meaningfulScript } } ) ;
1284
- if ( ! payment . output . equals ( script ) )
1285
- throw new Error ( 'P2SH redeemScript and scriptPubkey do not match' ) ;
1252
+ checkRedeemScript ( index , script , redeemScript , ioType ) ;
1286
1253
} else {
1287
1254
meaningfulScript = script ;
1288
1255
}
1289
- return meaningfulScript ;
1256
+ return {
1257
+ meaningfulScript,
1258
+ type : isP2SHP2WSH
1259
+ ? 'p2shp2wsh'
1260
+ : isP2SH
1261
+ ? 'p2sh'
1262
+ : isP2WSH
1263
+ ? 'p2wsh'
1264
+ : 'raw' ,
1265
+ } ;
1290
1266
}
1291
1267
function pubkeyInScript ( pubkey , script ) {
1292
1268
const pubkeyHash = crypto_1 . hash160 ( pubkey ) ;
0 commit comments