File Coverage

blib/lib/Bitcoin/Crypto/Transaction.pm
Criterion Covered Total %
statement 93 93 100.0
branch 18 22 81.8
condition 8 11 72.7
subroutine 25 25 100.0
pod n/a
total 144 151 95.3


line stmt bran cond sub pod time code
1             package Bitcoin::Crypto::Transaction;
2             $Bitcoin::Crypto::Transaction::VERSION = '2.000_01'; # TRIAL
3             $Bitcoin::Crypto::Transaction::VERSION = '2.00001';
4 9     9   126 use v5.10;
  9         38  
5 9     9   93 use strict;
  9         34  
  9         209  
6 9     9   42 use warnings;
  9         39  
  9         223  
7              
8 9     9   112 use Moo;
  9         67  
  9         138  
9 9     9   4353 use Mooish::AttributeBuilder -standard;
  9         42  
  9         62  
10 9     9   1243 use Type::Params -sigs;
  9         22  
  9         82  
11 9     9   3908 use Scalar::Util qw(blessed);
  9         28  
  9         492  
12 9     9   92 use Carp qw(carp);
  9         40  
  9         522  
13 9     9   90 use List::Util qw(sum);
  9         17  
  9         692  
14              
15 9     9   89 use Bitcoin::Crypto qw(btc_script btc_utxo);
  9         24  
  9         512  
16 9     9   70 use Bitcoin::Crypto::Constants;
  9         18  
  9         262  
17 9     9   50 use Bitcoin::Crypto::Exception;
  9         32  
  9         263  
18 9     9   4020 use Bitcoin::Crypto::Transaction::Input;
  9         35  
  9         336  
19 9     9   4554 use Bitcoin::Crypto::Transaction::Output;
  9         37  
  9         336  
20 9     9   4824 use Bitcoin::Crypto::Transaction::Digest;
  9         43  
  9         397  
21 9     9   80 use Bitcoin::Crypto::Util qw(hash256 to_format);
  9         30  
  9         507  
22 9     9   67 use Bitcoin::Crypto::Helpers qw(pack_varint unpack_varint);
  9         51  
  9         526  
23             use Bitcoin::Crypto::Types
24 9     9   69 qw(IntMaxBits ArrayRef InstanceOf HashRef Object ByteStr Str PositiveInt PositiveOrZeroInt Enum BitcoinScript Bool);
  9         21  
  9         56  
25 9     9   38935 use Bitcoin::Crypto::Script::Common;
  9         29  
  9         30892  
26              
27             has param 'version' => (
28             isa => IntMaxBits [32],
29             default => 1,
30             );
31              
32             has field 'inputs' => (
33             isa => ArrayRef [InstanceOf ['Bitcoin::Crypto::Transaction::Input']],
34             default => sub { [] },
35             );
36              
37             has field 'outputs' => (
38             isa => ArrayRef [InstanceOf ['Bitcoin::Crypto::Transaction::Output']],
39             default => sub { [] },
40             );
41              
42             has param 'locktime' => (
43             isa => IntMaxBits [32],
44             default => 0,
45             );
46              
47             with qw(
48             Bitcoin::Crypto::Role::ShallowClone
49             );
50              
51             signature_for add_input => (
52             method => Object,
53             positional => [ArrayRef, {slurpy => 1}],
54             );
55              
56             sub add_input
57             {
58             my ($self, $data) = @_;
59              
60             if (@$data == 1) {
61             $data = $data->[0];
62              
63             Bitcoin::Crypto::Exception::Transaction->raise(
64             'expected an input object'
65             ) unless blessed $data && $data->isa('Bitcoin::Crypto::Transaction::Input');
66             }
67             else {
68             $data = Bitcoin::Crypto::Transaction::Input->new(@$data);
69             }
70              
71             push @{$self->inputs}, $data;
72             return $self;
73             }
74              
75             signature_for add_output => (
76             method => Object,
77             positional => [ArrayRef, {slurpy => 1}],
78             );
79              
80             sub add_output
81             {
82             my ($self, $data) = @_;
83              
84             if (@$data == 1) {
85             $data = $data->[0];
86              
87             Bitcoin::Crypto::Exception::Transaction->raise(
88             'expected an output object'
89             ) unless blessed $data && $data->isa('Bitcoin::Crypto::Transaction::Output');
90             }
91             else {
92             $data = Bitcoin::Crypto::Transaction::Output->new(@$data);
93             }
94              
95             push @{$self->outputs}, $data;
96             return $self;
97             }
98              
99             signature_for to_serialized => (
100             method => Object,
101             named => [
102             witness => Bool,
103             {default => 1},
104             ],
105             );
106              
107             sub to_serialized
108             {
109             my ($self, $args) = @_;
110              
111             # transaction should be serialized as follows:
112             # - version, 4 bytes
113             # - number of inputs, 1-9 bytes
114             # - serialized inputs
115             # - number of outputs, 1-9 bytes
116             # - serialized outputs
117             # - lock time, 4 bytes
118              
119             # segwit transaction should be serialized as follows:
120             # - version, 4 bytes
121             # - 0x0001, if witness data is present
122             # - number of inputs, 1-9 bytes
123             # - serialized inputs
124             # - number of outputs, 1-9 bytes
125             # - serialized outputs
126             # - witness data
127             # - lock time, 4 bytes
128              
129             my $serialized = '';
130              
131             $serialized .= pack 'V', $self->version;
132              
133             # Process inputs
134             my @inputs = @{$self->inputs};
135              
136             my $with_witness = $args->witness && grep { $_->has_witness } @inputs;
137             if ($with_witness) {
138             $serialized .= "\x00\x01";
139             }
140              
141             $serialized .= pack_varint(scalar @inputs);
142             foreach my $input (@inputs) {
143             $serialized .= $input->to_serialized;
144             }
145              
146             # Process outputs
147             my @outputs = @{$self->outputs};
148             $serialized .= pack_varint(scalar @outputs);
149             foreach my $item (@outputs) {
150             $serialized .= $item->to_serialized;
151             }
152              
153             if ($with_witness) {
154             foreach my $input (@inputs) {
155             my @this_witness = $input->has_witness ? @{$input->witness} : ();
156              
157             $serialized .= pack_varint(scalar @this_witness);
158             foreach my $witness_item (@this_witness) {
159             $serialized .= pack_varint(length $witness_item);
160             $serialized .= $witness_item;
161             }
162             }
163             }
164              
165             $serialized .= pack 'V', $self->locktime;
166              
167             return $serialized;
168             }
169              
170             signature_for from_serialized => (
171             method => Str,
172             positional => [ByteStr],
173             );
174              
175             sub from_serialized
176             {
177             my ($class, $serialized) = @_;
178             my $pos = 0;
179              
180             my $version = unpack 'V', substr $serialized, $pos, 4;
181             $pos += 4;
182              
183             my $witness_flag = (substr $serialized, $pos, 2) eq "\x00\x01";
184             $pos += 2 if $witness_flag;
185              
186             my ($input_count_len, $input_count) = unpack_varint(substr $serialized, $pos, 9);
187             $pos += $input_count_len;
188              
189             my @inputs;
190             for (1 .. $input_count) {
191             push @inputs, Bitcoin::Crypto::Transaction::Input->from_serialized(
192             $serialized, pos => \$pos
193             );
194             }
195              
196             my ($output_count_len, $output_count) = unpack_varint(substr $serialized, $pos, 9);
197             $pos += $output_count_len;
198              
199             my @outputs;
200             for (1 .. $output_count) {
201             push @outputs, Bitcoin::Crypto::Transaction::Output->from_serialized(
202             $serialized, pos => \$pos
203             );
204             }
205              
206             if ($witness_flag) {
207             foreach my $input (@inputs) {
208             my ($input_witness_len, $input_witness) = unpack_varint(substr $serialized, $pos, 9);
209             $pos += $input_witness_len;
210              
211             my @witness;
212             for (1 .. $input_witness) {
213             my ($witness_count_len, $witness_count) = unpack_varint(substr $serialized, $pos, 9);
214             $pos += $witness_count_len;
215              
216             push @witness, substr $serialized, $pos, $witness_count;
217             $pos += $witness_count;
218             }
219              
220             $input->set_witness(\@witness);
221             }
222             }
223              
224             my $locktime = unpack 'V', substr $serialized, $pos, 4;
225             $pos += 4;
226              
227             Bitcoin::Crypto::Exception::Transaction->raise(
228             'serialized transaction data is corrupted'
229             ) if $pos != length $serialized;
230              
231             my $tx = $class->new(
232             version => $version,
233             locktime => $locktime,
234             );
235              
236             @{$tx->inputs} = @inputs;
237             @{$tx->outputs} = @outputs;
238              
239             return $tx;
240             }
241              
242             signature_for get_hash => (
243             method => Object,
244             positional => [],
245             );
246              
247             sub get_hash
248             {
249             my ($self) = @_;
250              
251             return scalar reverse hash256($self->to_serialized(witness => 0));
252             }
253              
254             signature_for get_digest => (
255             method => Object,
256             positional => [HashRef, {slurpy => !!1}],
257             );
258              
259             sub get_digest
260             {
261             my ($self, $params) = @_;
262              
263             $params->{transaction} = $self;
264             my $digest = Bitcoin::Crypto::Transaction::Digest->new($params);
265             return $digest->get_digest;
266             }
267              
268             signature_for fee => (
269             method => Object,
270             positional => [],
271             );
272              
273             sub fee
274             {
275             my ($self) = @_;
276              
277             my $input_value = 0;
278             foreach my $input (@{$self->inputs}) {
279             $input_value += $input->utxo->output->value;
280             }
281              
282             my $output_value = 0;
283             foreach my $output (@{$self->outputs}) {
284             $output_value += $output->value;
285             }
286              
287             return $input_value - $output_value;
288             }
289              
290             signature_for fee_rate => (
291             method => Object,
292             positional => [],
293             );
294              
295             sub fee_rate
296             {
297             my ($self) = @_;
298              
299             my $fee = $self->fee;
300             my $size = $self->virtual_size;
301              
302             return $fee->as_float / $size;
303             }
304              
305             signature_for set_rbf => (
306             method => Object,
307             positional => [],
308             );
309              
310             sub set_rbf
311             {
312             my ($self) = @_;
313              
314             # rules according to BIP125
315             # https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki
316             if (!$self->has_rbf) {
317             $self->inputs->[0]->set_sequence_no(Bitcoin::Crypto::Constants::rbf_sequence_no_threshold);
318             }
319              
320             return $self;
321             }
322              
323             signature_for has_rbf => (
324             method => Object,
325             positional => [],
326             );
327              
328             sub has_rbf
329             {
330             my ($self) = @_;
331              
332             foreach my $input (@{$self->inputs}) {
333             return !!1
334             if $input->sequence_no <= Bitcoin::Crypto::Constants::rbf_sequence_no_threshold;
335             }
336              
337             return !!0;
338             }
339              
340             signature_for virtual_size => (
341             method => Object,
342             positional => [],
343             );
344              
345             sub virtual_size
346             {
347             my ($self) = @_;
348              
349             my $base = length $self->to_serialized(witness => 0);
350             my $with_witness = length $self->to_serialized;
351             my $witness = $with_witness - $base;
352              
353             return $base + $witness / 4;
354             }
355              
356             signature_for weight => (
357             method => Object,
358             positional => [],
359             );
360              
361             sub weight
362             {
363             my ($self) = @_;
364              
365             my $base = length $self->to_serialized(witness => 0);
366             my $with_witness = length $self->to_serialized;
367             my $witness = $with_witness - $base;
368              
369             return $base * 4 + $witness;
370             }
371              
372             signature_for update_utxos => (
373             method => Object,
374             positional => [],
375             );
376              
377             sub update_utxos
378             {
379             my ($self) = @_;
380              
381             foreach my $input (@{$self->inputs}) {
382             $input->utxo->unregister;
383             }
384              
385             foreach my $output_index (0 .. $#{$self->outputs}) {
386             my $output = $self->outputs->[$output_index];
387              
388             btc_utxo->new(
389             txid => $self->get_hash,
390             output_index => $output_index,
391             output => $output,
392             )->register;
393             }
394              
395             return $self;
396             }
397              
398             sub _verify_script_default
399             {
400 49     49   196 my ($self, $input, $script_runner) = @_;
401 49         276 my $locking_script = $input->utxo->output->locking_script;
402              
403 49 50       262 Bitcoin::Crypto::Exception::TransactionScript->raise(
404             'signature script must only contain push opcodes'
405             ) unless $input->signature_script->is_pushes_only;
406              
407             # execute input to get initial stack
408 49         355 $script_runner->execute($input->signature_script);
409 49         162 my $stack = $script_runner->stack;
410              
411             # execute previous output
412             # NOTE: shallow copy of the stack
413             Bitcoin::Crypto::Exception::TransactionScript->trap_into(
414             sub {
415 49     49   379 $script_runner->execute($locking_script, [@$stack]);
416 36 50       270 die 'execution yielded failure'
417             unless $script_runner->success;
418             },
419 49         390 'locking script'
420             );
421              
422 36 100 100     367 if ($locking_script->has_type && $locking_script->type eq 'P2SH') {
423 14         588 my $redeem_script = btc_script->from_serialized(pop @$stack);
424              
425             Bitcoin::Crypto::Exception::TransactionScript->trap_into(
426             sub {
427 14     14   119 $script_runner->execute($redeem_script, $stack);
428 14 100       86 die 'execution yielded failure'
429             unless $script_runner->success;
430             },
431 14         167 'redeem script'
432             );
433              
434 13 100       87 if ($redeem_script->is_native_segwit) {
435 10         70 $self->_verify_script_segwit($input, $script_runner, $redeem_script);
436             }
437             }
438             }
439              
440             sub _verify_script_segwit
441             {
442 20     20   83 my ($self, $input, $script_runner, $compat_script) = @_;
443              
444 20 50 66     122 die 'signature script is not empty in segwit input'
445             unless $compat_script || $input->signature_script->is_empty;
446              
447             # execute input to get initial stack
448 20         87 my $signature_script = btc_script->new;
449 20   50     57 foreach my $witness (@{$input->witness // []}) {
  20         125  
450 57         163 $signature_script->push($witness);
451             }
452 20         115 $script_runner->execute($signature_script);
453 20         102 my $stack = $script_runner->stack;
454              
455 20   66     180 my $locking_script = $compat_script // $input->utxo->output->locking_script;
456 20         91 my $hash = substr $locking_script->to_serialized, 2;
457 20         52 my $actual_locking_script;
458 20 100       420 if ($locking_script->type eq 'P2WPKH') {
    50          
459 11         227 $actual_locking_script = Bitcoin::Crypto::Script::Common->new(PKH => $hash);
460             }
461             elsif ($locking_script->type eq 'P2WSH') {
462 9         369 $actual_locking_script = Bitcoin::Crypto::Script::Common->new(WSH => $hash);
463             }
464              
465             # execute previous output
466             # NOTE: shallow copy of the stack
467             Bitcoin::Crypto::Exception::TransactionScript->trap_into(
468             sub {
469 20     20   149 $script_runner->execute($actual_locking_script, [@$stack]);
470 18 100       132 die 'execution yielded failure'
471             unless $script_runner->success;
472             },
473 20         211 'segwit locking script'
474             );
475              
476 17 100       445 if ($locking_script->type eq 'P2WSH') {
477 9         184 my $redeem_script = btc_script->from_serialized(pop @$stack);
478              
479             Bitcoin::Crypto::Exception::TransactionScript->trap_into(
480             sub {
481 9     9   60 $script_runner->execute($redeem_script, $stack);
482 8 100       33 die 'execution yielded failure'
483             unless $script_runner->success;
484             },
485 9         97 'segwit redeem script'
486             );
487             }
488             }
489              
490             signature_for verify => (
491             method => Object,
492             named => [
493             block => InstanceOf ['Bitcoin::Crypto::Block'],
494             {optional => 1},
495             ],
496             );
497              
498             sub verify
499             {
500             my ($self, $args) = @_;
501             my $block = $args->block;
502              
503             my $script_runner = Bitcoin::Crypto::Script::Runner->new(
504             transaction => $self,
505             );
506              
507             my @inputs = @{$self->inputs};
508              
509             # amount checking
510             my $total_in = sum map { $_->utxo->output->value } @inputs;
511             my $total_out = sum map { $_->value } @{$self->outputs};
512              
513             Bitcoin::Crypto::Exception::Transaction->raise(
514             'output value exceeds input'
515             ) if $total_in < $total_out;
516              
517             # locktime checking
518             if (
519             $self->locktime > 0 && grep {
520             $_->sequence_no != Bitcoin::Crypto::Constants::max_sequence_no
521             } @inputs
522             )
523             {
524             if (defined $block) {
525             my $locktime = $self->locktime;
526             my $is_timestamp = $locktime >= Bitcoin::Crypto::Constants::locktime_height_threshold;
527              
528             Bitcoin::Crypto::Exception::Transaction->raise(
529             'locktime was not satisfied'
530             ) if $locktime > ($is_timestamp ? $block->median_time_past : $block->height);
531             }
532             else {
533             carp 'trying to verify locktime but no block parameter was passed';
534             }
535             }
536              
537             # per-input verification
538             foreach my $input_index (0 .. $#inputs) {
539             my $input = $inputs[$input_index];
540             my $utxo = $input->utxo;
541             $script_runner->transaction->set_input_index($input_index);
542              
543             # run bitcoin script
544             my $procedure = '_verify_script_default';
545             $procedure = '_verify_script_segwit'
546             if $utxo->output->locking_script->is_native_segwit;
547              
548             Bitcoin::Crypto::Exception::TransactionScript->trap_into(
549             sub {
550             $self->$procedure($input, $script_runner);
551             },
552             "transaction input $input_index verification has failed"
553             );
554              
555             # check sequence (BIP 68)
556             if ($self->version >= 2 && !($input->sequence_no & (1 << 31))) {
557             my $sequence = $input->sequence_no;
558             my $time_based = $sequence & (1 << 22);
559             my $relative_locktime = $sequence & 0x0000ffff;
560              
561             if (defined $block && $utxo->has_block) {
562             my $utxo_block = $utxo->block;
563             my $now = $time_based ? $block->median_time_past : $block->height;
564             my $then = $time_based ? $utxo_block->median_time_past : $utxo_block->height;
565             $relative_locktime <<= 9 if $time_based;
566              
567             Bitcoin::Crypto::Exception::Transaction->raise(
568             'relative locktime was not satisfied'
569             ) if $now < $then + $relative_locktime;
570             }
571             else {
572             carp 'trying to verify relative locktime but no block parameter was passed or utxo block was set';
573             }
574             }
575             }
576              
577             return;
578             }
579              
580             signature_for dump => (
581             method => Object,
582             named => [
583             ],
584             );
585              
586             sub dump
587             {
588             my ($self, $params) = @_;
589              
590             my @result;
591             push @result, 'Transaction ' . to_format [hex => $self->get_hash];
592             push @result, 'version: ' . $self->version;
593             push @result, 'size: ' . $self->virtual_size . 'vB, ' . $self->weight . 'WU';
594             push @result, 'fee: ' . $self->fee . ' sat (~' . (int($self->fee_rate * 100) / 100) . ' sat/vB)';
595             push @result, 'replace-by-fee: ' . ($self->has_rbf ? 'yes' : 'no');
596             push @result, 'locktime: ' . $self->locktime;
597             push @result, '';
598              
599             push @result, @{$self->inputs} . ' inputs:';
600             foreach my $input (@{$self->inputs}) {
601             push @result, $input->dump;
602             push @result, '';
603             }
604              
605             push @result, @{$self->outputs} . ' outputs:';
606             foreach my $output (@{$self->outputs}) {
607             push @result, $output->dump;
608             push @result, '';
609             }
610              
611             return join "\n", @result;
612             }
613              
614             1;
615              
616             __END__
617             =head1 NAME
618              
619             Bitcoin::Crypto::Transaction - Bitcoin transaction instance
620              
621             =head1 SYNOPSIS
622              
623             use Bitcoin::Crypto qw(btc_utxo btc_transaction);
624              
625             # extract unspent transaction outputs from the previous transaction
626             btc_utxo->extract([hex => $serialized_previous_tx]);
627              
628             # create transaction from its serialized form
629             my $tx = btc_transaction->from_serialized([hex => $serialized_this_tx]);
630              
631             # this will verify the transaction and throw an exception if it is not correct
632             $tx->verify;
633              
634             # dump the transaction in readable format
635             print $tx->dump;
636              
637             =head1 DESCRIPTION
638              
639             Transaction support in Bitcoin::Crypto is provided on best-effort basis. The
640             goal is not to reimplement Bitcoin Core, which would most likely lead to security
641             issues, but rather to provide means to manipulate a set of well-known standard
642             transaction types. Widely used C<P2PKH>, C<P2SH>, their SegWit counterparts and
643             C<P2MS> are thoroughly tested and should be safe to use. B<Still, before
644             putting any real money on the line, make sure to check the serialized
645             transactions in other tools and review that its contents are correct. There is
646             absolutely no guarantee!>.
647              
648             See L<Bitcoin::Crypto::Manual::Transactions> for details and guidelines.
649              
650             =head1 INTERFACE
651              
652             =head2 Attributes
653              
654             =head3 version
655              
656             Integer containing version of the transaction. By default C<1>.
657              
658             I<Available in the constructor>.
659              
660             =head3 inputs
661              
662             The array reference of transaction inputs (L<Bitcoin::Crypto::Transaction::Input>).
663              
664             It's better to use L<add_input> instead of pushing directly to this array.
665              
666             =head3 outputs
667              
668             The array reference of transaction outputs (L<Bitcoin::Crypto::Transaction::Output>).
669              
670             It's better to use L<add_output> instead of pushing directly to this array.
671              
672             =head3 locktime
673              
674             Integer containing locktime of the transaction. By default C<0>.
675              
676             I<Available in the constructor>.
677              
678             =head2 Methods
679              
680             =head3 new
681              
682             $tx = $class->new(%args)
683              
684             This is a standard Moo constructor, which can be used to create the object. It
685             takes arguments specified in L</Attributes>.
686              
687             Returns class instance.
688              
689             =head3 add_input
690              
691             $object = $object->add_input($input_object)
692             $object = $object->add_input(%args)
693              
694             Adds a new input to the transaction.
695              
696             If a single scalar is passed, it must be a constructed object of L<Bitcoin::Crypto::Transaction::Input>.
697              
698             Otherwise expects a hash of arguments passed to L<Bitcoin::Crypto::Transaction::Input/new>.
699              
700             Returns itself (for chaining).
701              
702             =head3 add_output
703              
704             $object = $object->add_output($output_object)
705             $object = $object->add_output(%args)
706              
707             Same as L</add_input>, but adds an output (L<Bitcoin::Crypto::Transaction::Output>).
708              
709             =head3 to_serialized
710              
711             $serialized = $object->to_serialized(%params)
712              
713             Serializes a transaction into a bytestring.
714              
715             C<%params> can be any of:
716              
717             =over
718              
719             =item * C<witness>
720              
721             Boolean, default C<1>. If C<0> is passed, forces serialization without witness
722             data. Note that this is a no-op in non-segwit transactions.
723              
724             =back
725              
726             =head3 from_serialized
727              
728             $object = $class->from_serialized($data)
729              
730             Deserializes the bytestring C<$data> into a transaction object.
731              
732             Keep in mind deserialization requires a full set of UTXO to be registered. If
733             they are not, an exception will be raised with missing transaction id and
734             output index, which should help you fill in the blanks. See
735             L<Bitcoin::Crypto::Transaction::UTXO> for details.
736              
737             =head3 get_hash
738              
739             $txid = $object->get_hash()
740              
741             Returns the hash of the transaction, also used as its id. The return value is a
742             bytestring.
743              
744             NOTE: this method returns the hash in big endian, which is not suitable for
745             transactions. If you want to manually encode the hash into the transaction, you
746             should first C<scalar reverse> it.
747              
748             =head3 get_digest
749              
750             $digest = $object->get_digest(%params)
751              
752             This method produces the digest preimage of the transaction. It is a bytestring
753             against which the input signature is created (after hashing it with
754             C<hash256>).
755              
756             C<%params> can be any of:
757              
758             =over
759              
760             =item * C<signing_index>
761              
762             This non-negative integer is the index of the input being signed. Required.
763              
764             =item * C<signing_subscript>
765              
766             The subscript used in digesting. It is only required for C<P2SH>, C<P2WSH> and
767             custom scripts.
768              
769             =item * C<sighash>
770              
771             The sighash which should be used for the digest. By default C<SIGHASH_ALL>.
772              
773             =back
774              
775             =head3 fee
776              
777             $fee = $object->fee()
778              
779             Returns the fee - the difference between sum of input values and the sum of
780             output values. The fee is always zero or positive integer.
781              
782             =head3 fee_rate
783              
784             $fee_rate = $object->fee_rate()
785              
786             Returns the fee rate - the amount of satoshi per virtual byte (a floating point
787             value).
788              
789             NOTE: since weight of the transaction changes after signing it, it is not
790             possible to accurately measure fee rate prior to signing.
791              
792             =head3 set_rbf
793              
794             $object = $object->set_rbf()
795              
796             Sets replace-by-fee for the transaction according to BIP125. The modification
797             of sequence number is always done on the first input. Has no effect if the
798             transaction already has the RBF rule.
799              
800             =head3 has_rbf
801              
802             $bool = $object->has_rbf()
803              
804             Returns true if the transaction is subject to replace-by-fee.
805              
806             =head3 virtual_size
807              
808             my $vB_size = $object->virtual_size()
809              
810             Returns the virtual size of the transaction (in vBytes).
811              
812             C<virtual_size> is used for fee calculations (witness data is discounted by 75%).
813              
814             =head3 weight
815              
816             my $B_size = $object->weight()
817              
818             Returns the weight of the transaction (in bytes).
819              
820             C<weight> is the representation of the transaction's size after serializing.
821              
822             =head3 update_utxos
823              
824             $object = $object->update_utxos()
825              
826             This method accepts the transaction as confirmed by the network. It unregisters
827             all UTXOs it consumed and registers its own outputs as new UTXOs. This means
828             new transactions can be created without the need to register the new UTXOs
829             manually.
830              
831             NOTE: it does not verify the transaction by itself.
832              
833             =head3 verify
834              
835             $object->verify(%params)
836              
837             Verifies the transaction according to the Bitcoin consensus rules. Returns
838             nothing, but will throw an exception if the verification failed.
839              
840             See L<Bitcoin::Crypto::Manual::Transactions/Current known problems with transactions>.
841              
842             C<%params> can be any of:
843              
844             =over
845              
846             =item * C<block>
847              
848             Optional instance of L<Bitcoin::Crypto::Block> - used for locktime and sequence
849             verification. If it is not passed and the transaction includes these checks, it
850             will still verify without an exception but a warning will be issued.
851              
852             =back
853              
854             =head3 dump
855              
856             $text = $object->dump()
857              
858             Returns a readable description of the transaction.
859              
860             =head1 EXCEPTIONS
861              
862             This module throws an instance of L<Bitcoin::Crypto::Exception> if it
863             encounters an error. It can produce the following error types from the
864             L<Bitcoin::Crypto::Exception> namespace:
865              
866             =over
867              
868             =item * Bitcoin::Crypto::Exception::Transaction - general error with transaction
869              
870             =item * Bitcoin::Crypto::Exception::TransactionScript - error during transaction scripts execution
871              
872             =back
873              
874             =head1 SEE ALSO
875              
876             =over
877              
878             =item L<Bitcoin::Crypto::Transaction::Input>
879              
880             =item L<Bitcoin::Crypto::Transaction::Output>
881              
882             =item L<Bitcoin::Crypto::Transaction::UTXO>
883              
884             =item L<Bitcoin::Crypto::Script>
885              
886             =back
887              
888             =cut
889