@@ -7,6 +7,7 @@ use Mooish::Base -standard, -role;
77use Types::Common -sigs;
88
99use Bitcoin::Crypto qw( btc_script_tree) ;
10+ use Bitcoin::Crypto::Constants qw( :sighash) ;
1011use Bitcoin::Crypto::Transaction::Flags;
1112
1213sub _input_has_witness_utxo
@@ -19,14 +20,43 @@ sub _input_has_witness_utxo
1920
2021sub _add_partial_signature
2122{
22- my ($self , $input_index , $key , $signature ) = @_ ;
23+ my ($self , $input_index , $key , $signature , $sighash ) = @_ ;
2324
2425 $self -> add_field(
2526 type => ' PSBT_IN_PARTIAL_SIG' ,
2627 index => $input_index ,
2728 key => $key -> get_public_key,
2829 value => $signature ,
2930 );
31+
32+ if ($self -> version == 2) {
33+
34+ # NOTE: SIGHASH_DEFAULT may not be correct for pre-taproot, but it's only
35+ # used to set modifiable flags, which will be the same for SIGHASH_ALL
36+ $sighash = $sighash ? $sighash -> value : SIGHASH_ALL;
37+
38+ my $modifiable = $self -> get_all_fields(' PSBT_GLOBAL_TX_MODIFIABLE' );
39+ $modifiable //= $self
40+ -> add_field(type => ' PSBT_GLOBAL_TX_MODIFIABLE' , value => {})
41+ -> get_field(' PSBT_GLOBAL_TX_MODIFIABLE' );
42+
43+ my $value = $modifiable -> value;
44+
45+ if (!($sighash & SIGHASH_ANYONECANPAY)) {
46+ $value -> {inputs_modifiable } = !!0;
47+ }
48+
49+ if (!($sighash & SIGHASH_NONE)) {
50+ $value -> {outputs_modifiable } = !!0;
51+ }
52+
53+ if (!($sighash & SIGHASH_SINGLE)) {
54+ $value -> {has_sighash_single } = !!1;
55+ }
56+
57+ # update the value back in the PSBT
58+ $modifiable -> set_value($value );
59+ }
3060}
3161
3262sub _do_sign_P2PKH
@@ -43,7 +73,7 @@ sub _do_sign_P2PKH
4373 my $signature = $signer -> add_signature($key , sighash => $sighash ? $sighash -> value : undef )
4474 -> signature-> [-1];
4575
46- $self -> _add_partial_signature($input_index , $key , $signature );
76+ $self -> _add_partial_signature($input_index , $key , $signature , $sighash );
4777 return 1;
4878}
4979
@@ -72,7 +102,7 @@ sub _do_sign_P2WPKH
72102 my $signature = $signer -> add_signature($key , sighash => $sighash ? $sighash -> value : undef )
73103 -> signature-> [-1];
74104
75- $self -> _add_partial_signature($input_index , $key , $signature );
105+ $self -> _add_partial_signature($input_index , $key , $signature , $sighash );
76106 return 1;
77107}
78108
@@ -153,8 +183,7 @@ sub _do_sign
153183signature_for sign => (
154184 method => !!1,
155185 positional => [
156- (InstanceOf [' Bitcoin::Crypto::Key::Private' ])
157- | (InstanceOf [' Bitcoin::Crypto::Key::ExtPrivate' ]),
186+ InstanceOf [' Bitcoin::Crypto::Key::Private' ]
158187 ],
159188);
160189
@@ -175,9 +204,6 @@ sub sign
175204 }
176205
177206 return $signed ;
178-
179- # TODO: this note
180- # For PSBTv2s, a signer must update the PSBT_GLOBAL_TX_MODIFIABLE field after signing inputs so that it accurately reflects the state of the PSBT. If the Signer added a signature that does not use SIGHASH_ANYONECANPAY, the Input Modifiable flag must be set to False. If the Signer added a signature that does not use SIGHASH_NONE, the Outputs Modifiable flag must be set to False. If the Signer added a signature that uses SIGHASH_SINGLE, the Has SIGHASH_SINGLE flag must be set to True.
181207}
182208
1832091;
0 commit comments