Bitcoin-Crypto
view release on metacpan or search on metacpan
lib/Bitcoin/Crypto/Transaction.pm view on Meta::CPAN
# assume $fee will be small enough to be numified from BigInt on 32 bit.
# This may be false, but we do not focus on 32 bit support
my $size = $self->virtual_size;
return "$fee" / $size;
}
sub set_rbf
{
my ($self) = @_;
# rules according to BIP125
# https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki
if (!$self->has_rbf) {
my $input = $self->inputs->[0];
Bitcoin::Crypto::Exception::Transaction->raise(
'set_rbf can only be called on a transaction with at least one input'
) unless defined $input;
$input->set_sequence_no(RBF_SEQUENCE_NO_THRESHOLD);
}
return $self;
}
sub has_rbf
{
my ($self) = @_;
foreach my $input (@{$self->inputs}) {
return !!1
if $input->sequence_no <= RBF_SEQUENCE_NO_THRESHOLD;
}
return !!0;
}
sub virtual_size
{
my ($self) = @_;
my $base = length $self->to_serialized(witness => 0);
my $with_witness = length $self->to_serialized;
my $witness = $with_witness - $base;
return $base + $witness / 4;
}
sub weight
{
my ($self) = @_;
my $base = length $self->to_serialized(witness => 0);
my $with_witness = length $self->to_serialized;
my $witness = $with_witness - $base;
return $base * 4 + $witness;
}
sub update_utxos
{
my ($self) = @_;
foreach my $input (@{$self->inputs}) {
$input->utxo->unregister if $input->utxo_registered;
}
foreach my $output_index (0 .. $#{$self->outputs}) {
my $output = $self->outputs->[$output_index];
btc_utxo->new(
txid => $self->get_hash,
output_index => $output_index,
output => $output,
($self->has_block ? (block => $self->block) : ()),
)->register;
}
return $self;
}
sub is_coinbase
{
my ($self) = @_;
my $inputs = $self->inputs;
return !!0 unless @{$inputs} == 1;
my $null_prevout = NULL_UTXO;
my $utxo_prevout = $inputs->[0]->utxo_location;
return $null_prevout->[0] eq $utxo_prevout->[0] && $null_prevout->[1] == $utxo_prevout->[1];
}
sub _verify_script_default
{
my ($self, $input, $script_runner) = @_;
my $locking_script = $input->utxo->output->locking_script;
my $is_p2sh = $script_runner->flags->p2sh && ($locking_script->type // '') eq 'P2SH';
my $is_pushes_only = $is_p2sh || $script_runner->flags->signature_pushes_only;
Bitcoin::Crypto::Exception::TransactionScript->raise(
'signature script must only contain push opcodes'
) if $is_pushes_only && !$input->signature_script->is_pushes_only;
# execute input to get initial stack
$script_runner->execute($input->signature_script);
my @stack = @{$script_runner->stack};
my @locking_stack;
my $redeem_script;
if ($is_p2sh) {
$redeem_script = pop @stack;
@locking_stack = ($redeem_script)
if defined $redeem_script;
}
else {
@locking_stack = @stack;
}
( run in 1.123 second using v1.01-cache-2.11-cpan-9581c071862 )