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 )