bitcoin_wire/transaction
Deserialize, inspect, validate, and serialize Bitcoin transactions.
Types
A violation of Bitcoin consensus rules detected during transaction validation.
Each variant identifies a specific rule that the transaction breaks.
pub type ConsensusViolation {
NoInputs
NoOutputs
BaseSizeLimitExceeded(Int)
OutputValueOutOfRange(index: Int, value: OutputValue)
TotalOutputValueOutOfRange(index: Int, total: Int)
CoinbaseWithMultipleInputs
InvalidCoinbaseScriptSigLength
DuplicateInput(
outpoint: OutPoint,
first_index: Int,
duplicate_index: Int,
)
}
Constructors
-
NoInputsThe transaction has no inputs.
Every Bitcoin transaction must contain at least one input. Transactions with zero inputs are invalid under consensus rules.
-
NoOutputsThe transaction has no outputs.
Every Bitcoin transaction must contain at least one output. Transactions with zero outputs are invalid under consensus rules.
-
BaseSizeLimitExceeded(Int)The stripped transaction serialization exceeded Bitcoin Core’s context-independent transaction base-size limit.
The contained value is the measured base size in bytes: version, CompactSize counts and script lengths, inputs, outputs, and lock time. The maximum is 1,000,000 bytes. SegWit marker, flag, and witness bytes are excluded from this transaction-level check but contribute to the separate 4,000,000-WU block-weight limit.
-
OutputValueOutOfRange(index: Int, value: OutputValue)An output value is outside the valid money range.
Consensus requires each output value to satisfy:
0 <= value <= 2,100,000,000,000,000 satoshisThe upper bound is 21,000,000 BTC expressed in satoshis.
The
indexfield indicates the zero-based position of the output, andvaluepreserves the invalid signed 64-bit amount exactly. Useoutput_value_to_stringto display it without native integer limits. -
TotalOutputValueOutOfRange(index: Int, total: Int)The cumulative sum of output values exceeds the valid money range.
During validation, Bitcoin nodes maintain a running total of all output values and require that the cumulative sum never exceed 2,100,000,000,000,000 satoshis.
The
indexfield indicates the zero-based position of the output at which the running total first exceeded 2,100,000,000,000,000 satoshis.The
totalfield is the cumulative output value at that point. Individual amounts are checked first, so the first excessive total is at most twice the maximum money amount and fits exactly inInton both targets. -
CoinbaseWithMultipleInputsA transaction identified as a coinbase transaction contains more than one input.
A coinbase transaction is defined as a transaction whose single input has a null outpoint. Under consensus rules, such a transaction must contain exactly one input.
-
InvalidCoinbaseScriptSigLengthA coinbase transaction’s scriptSig length is invalid.
Coinbase scriptSig must be between 2 and 100 bytes (inclusive).
-
DuplicateInput( outpoint: OutPoint, first_index: Int, duplicate_index: Int, )The transaction contains duplicate inputs referencing the same outpoint.
Each input in a transaction must reference a unique previous output.
The
outpointfield identifies the duplicated outpoint.The
first_indexfield indicates the zero-based index of the first occurrence of this outpoint in the input list.The
duplicate_indexfield indicates the zero-based index of the subsequent input that duplicates the same outpoint.
Phantom type indicating a transaction that has passed the context-free
Bitcoin consensus checks performed by validate_context_free_consensus.
This does not indicate full transaction validity. Context-dependent checks such as script execution, signature verification, and UTXO lookup are not performed.
pub type ContextFreeValidated =
@internal ContextFreeValidated
An error that occurred while decoding a Bitcoin transaction from bytes.
Carries the byte offset where the error occurred, the kind of error, and internal parser-location details used to build the public structural path.
pub opaque type DecodeError
The specific kind of error that occurred during transaction decoding.
Categorizes decode failures into distinct variants.
pub type DecodeErrorKind {
NonByteAlignedInput(bit_count: Int)
UnexpectedEof(bytes_needed: Int, remaining: Int)
NonMinimalCompactSize(encoded_size: Int, value: Int)
InvalidSegwitMarkerFlag(marker: Int, flag: Int)
SuperfluousWitnessRecord
InsufficientBytes(claimed: Int, remaining: Int)
IntegerOutOfRange(String)
PolicyLimitExceeded(
limit: DecodePolicyLimit,
value: Int,
max: Int,
)
TrailingBytes(Int)
}
Constructors
-
NonByteAlignedInput(bit_count: Int)The input does not contain a whole number of bytes.
Bitcoin wire-format inputs are byte-aligned. The wrapped value is the exact total number of bits in the supplied input.
-
UnexpectedEof(bytes_needed: Int, remaining: Int)The input ended before enough bytes could be read.
Arguments
- bytes_needed
-
The number of bytes the decoder required.
- remaining
-
The number of bytes available at that point.
-
NonMinimalCompactSize(encoded_size: Int, value: Int)A CompactSize-encoded integer used a non-minimal encoding.
Bitcoin’s serialization rules require CompactSize integers to use the shortest possible encoding. This error occurs when a value could have been encoded in fewer bytes than were used.
Arguments
- encoded_size
-
The size of the encoded CompactSize in bytes.
- value
-
The decoded integer value.
-
InvalidSegwitMarkerFlag(marker: Int, flag: Int)The SegWit marker byte (0x00) was present but the flag byte was not 0x01.
Arguments
- marker
-
The marker byte.
- flag
-
The invalid flag byte.
-
SuperfluousWitnessRecordSegWit serialization was used, but every input witness stack was empty.
Transactions without witness data must use legacy serialization. A witness stack containing a zero-length item is nonempty and does not trigger this error.
-
InsufficientBytes(claimed: Int, remaining: Int)A length or count requires more bytes than remain in the input.
Unlike
UnexpectedEof, which reports a failed read, this error reports a decoded length or count that is known in advance not to fit in the remaining input. This is distinct fromPolicyLimitExceeded, which enforces configured resource limits.Examples:
- A scriptSig length claims a 100-byte script, but only 99 bytes remain.
- An input count claims one input, whose smallest encoding is 41 bytes, but only 40 bytes remain.
Arguments
- claimed
-
The number of bytes required.
This may be a conservative estimate, such as
remaining + 1, rather than the exact requirement to avoid integer overflow on JavaScript. - remaining
-
The number of bytes available.
-
IntegerOutOfRange(String)A decoded 64-bit integer value exceeds the range representable by the runtime.
The original value is preserved as a string for diagnostics.
-
PolicyLimitExceeded( limit: DecodePolicyLimit, value: Int, max: Int, )A policy limit was exceeded.
Arguments
- limit
-
The
DecodePolicylimit that was violated. - value
-
The measured or decoded quantity that exceeded
max. - max
-
The configured maximum.
-
TrailingBytes(Int)One transaction was successfully decoded, but extra bytes remain, so deserialization failed.
This indicates the input buffer contains more data than a single valid transaction. The wrapped
Intis the count of trailing bytes that were not consumed.
Configuration policy for transaction decoding limits.
This type controls byte and collection-count limits during transaction decoding. Callers can configure tighter limits to constrain work and allocation when decoding untrusted inputs.
Limits are enforced during decoding. If a limit is exceeded,
decoding fails with PolicyLimitExceeded.
The limits complement one another: transaction size bounds the complete
input buffer, while input, output, and total witness item count limits bound
collection sizes as the transaction is decoded. See the corresponding
decode_policy_with_* functions for enforcement details.
Builder functions do not validate whether custom limits are useful for
decoding consensus-valid transactions. Callers that override default_decode_policy
are responsible for choosing sensible values for their use case. Overly
strict or unusual values may simply cause decoding to fail with existing
decode errors.
See Also
default_decode_policyfor the default decoding limitsdeserialize_with_policyto apply a custom policy
pub opaque type DecodePolicy
Identifies the configured DecodePolicy limit that was exceeded.
Carried by PolicyLimitExceeded. Use get_decode_error_path to identify
where the violation occurred.
pub type DecodePolicyLimit {
MaxTransactionSize
MaxInputCount
MaxOutputCount
MaxWitnessItemCount
}
Constructors
-
MaxTransactionSizeThe maximum input buffer size was exceeded.
In
PolicyLimitExceeded,valueis the total byte size of the supplied buffer. This limit is checked before decoding begins. -
MaxInputCountThe maximum number of transaction inputs was exceeded.
-
MaxOutputCountThe maximum number of transaction outputs was exceeded.
-
MaxWitnessItemCountThe maximum total number of witness items across all input stacks was exceeded.
In
PolicyLimitExceeded,valueis the cumulative item count through the current stack, including zero-length items. The error points to that stack’s item-count field, before any of its items are decoded.
An error that occurred while deserializing a Bitcoin transaction from hex.
Distinguishes invalid hexadecimal input from decode policy and transaction decoding failures.
pub type DeserializeHexError {
InvalidHex
DecodeFailed(DecodeError)
}
Constructors
-
InvalidHexThe hexadecimal string could not be converted to bytes.
This occurs before any transaction decoding begins, typically due to an odd-length hex string or the presence of invalid hexadecimal characters.
-
DecodeFailed(DecodeError)The input exceeded a decode policy limit or its decoded bytes were not a well-formed Bitcoin transaction encoding.
A byte-size policy error can be returned before hex-to-bytes conversion. This wraps a
DecodeErrorcontaining details about the failure.
A transaction input.
An input references a previous transaction output and provides the data required to satisfy that output’s spending conditions.
pub opaque type Input
Phantom type tag for ScriptBytes — marks bytes from an input’s scriptSig.
pub type InputScript
An outpoint carried by a transaction input.
For ordinary inputs, this identifies the output being spent. For coinbase inputs, it contains the null-outpoint marker and references no output.
pub opaque type OutPoint
A transaction output.
An output contains an encoded value and a raw scriptPubKey. Decoding alone does not establish that the value is within the consensus money range or that the script’s spending conditions can be satisfied.
pub opaque type Output
Phantom type tag for ScriptBytes — marks a scriptPubKey (output locking script).
pub type OutputScript
The recognised structural script type of a transaction output’s locking script.
Identifies which recognised Bitcoin script template a script_pubkey matches,
enabling type-safe dispatch when inspecting outputs.
This type is intentionally classification-only. Its variants do not carry
embedded script data such as hashes, public keys, witness programs, multisig
parameters, or OP_RETURN payloads. Call get_raw_script_bytes when caller
code needs to perform additional script-specific analysis.
pub type OutputScriptType {
P2PK
P2PKH
P2SH
P2WPKH
P2WSH
P2TR
P2A
BareMultisig
NullData
OtherWitnessProgram(version: Int)
Unrecognized
}
Constructors
-
P2PKPay-to-public-key template.
Structurally matches a 33- or 65-byte key payload followed by
OP_CHECKSIG. The classifier does not validate the public key encoding. -
P2PKHPay-to-public-key-hash.
The most common legacy output type.
-
P2SHPay-to-script-hash.
The hash of the redeem script is embedded in the
scriptPubKey. The actual spending conditions are revealed in the input’sscriptSig. -
P2WPKHPay-to-witness-public-key-hash.
SegWit v0 output for single-key spends.
-
P2WSHPay-to-witness-script-hash.
SegWit v0 output for script-based spends.
-
P2TRPay-to-taproot.
SegWit v1 output supporting key-path and script-path spends.
-
P2ABitcoin Core’s pay-to-anchor relay-policy template.
Structurally matches exactly
OP_1 OP_DATA_2 4E 73(51 02 4E 73). Recognition is limited to Bitcoin Core’s named relay policy template; it does not introduce consensus validation. -
BareMultisigBare m-of-n multisig template using
OP_CHECKMULTISIGdirectly in thescriptPubKey.Structurally matches 1–20 key payloads and 1–20 required signatures with minimally encoded counts. Key payloads may use direct,
OP_PUSHDATA1,OP_PUSHDATA2, orOP_PUSHDATA4pushes, provided their decoded sizes are 33 or 65 bytes. The classifier checks only the payload shape; it does not validate SEC prefixes or curve points. Relay-policy limits such as the 1–3-key standardness rule are outside this classification. -
NullDataA structurally recognized null-data output.
This variant represents the null-data script template, not every script that begins with
OP_RETURN.Matches scripts that begin with
OP_RETURNand whose remaining bytes satisfy Bitcoin Core-compatible push-only parsing. For historical compatibility, this includesOP_RESERVED, even though executing that opcode fails. All encoded push operations must be complete. Script size does not affect classification.An
OP_RETURNscript with a non-push opcode or malformed push operation afterOP_RETURNclassifies asUnrecognizedinstead. -
OtherWitnessProgram(version: Int)A well-formed witness program that is not one of this library’s named output types.
versionis the decoded witness version (1–16). Version 1 with a 32-byte witness program isP2TR, and the exact51 02 4E 73template isP2A, so neither appears here. A later valid witness-program assignment remainsOtherWitnessProgramuntil a major release adds a dedicated constructor.Forward-compatible. Do not treat this the same as
Unrecognized. -
UnrecognizedDoes not match any recognised structural output template.
This is the unmatched structural fallback, not a relay-policy decision.
A signed 64-bit output amount in satoshis, stored as exact wire bytes.
Every signed 64-bit value is preserved exactly on both Erlang and JavaScript targets, including negative amounts and amounts above Bitcoin’s consensus money range. This type does not establish consensus validity.
Use output_value_to_string or output_value_to_bytes_le for exact,
portable representations, or output_value_to_int for a checked native
integer conversion.
pub opaque type OutputValue
Phantom type indicating a transaction that has been successfully parsed from its canonical Bitcoin wire-format serialization but has not yet been validated against Bitcoin consensus rules.
pub type Parsed =
@internal Parsed
Raw Bitcoin script bytes.
The kind type parameter is a phantom tag distinguishing input scripts
(ScriptBytes(InputScript)) from output scripts (ScriptBytes(OutputScript)).
This type represents an uninterpreted script as it appears on the wire. No validation or opcode parsing is performed at this level.
pub opaque type ScriptBytes(kind)
A Bitcoin transaction.
A transaction transfers value by consuming previously created outputs (inputs) and creating new outputs. Transactions are either legacy (pre-SegWit) or SegWit, which affects whether witness data is present in the serialized structure.
pub opaque type Transaction(state)
A single item from a witness stack.
A witness item is an arbitrary byte sequence that may represent a public key, signature, script, or other data. Its meaning is context-dependent; this library does not interpret it.
pub opaque type WitnessItem
A witness stack for a single transaction input.
Each input in a SegWit transaction has an associated stack of byte sequences supplied as witness data. Their interpretation depends on the spending conditions. This library exposes the items without executing or validating them.
pub opaque type WitnessStack
Values
pub fn classify_output_script(
script: ScriptBytes(OutputScript),
) -> OutputScriptType
Classify the script type of a transaction output’s locking script.
Matches script_pubkey bytes against recognised Bitcoin script templates and
returns the corresponding OutputScriptType.
Classification is per-script and structural. It does not determine whether
the containing transaction satisfies a node’s configurable relay policy.
It also does not extract, decode, or interpret embedded hashes, public keys,
witness programs, multisig parameters, signatures, or data payloads. For
caller-specific script analysis, use get_raw_script_bytes on the original
script.
Classification
├─ 76 A9 14 [×20] 88 AC → P2PKH
├─ A9 14 [×20] 87 → P2SH
├─ 00 14 [×20] → P2WPKH
├─ 00 20 [×32] → P2WSH
├─ 51 20 [×32] → P2TR
├─ 51 02 4E 73 → P2A
├─ 21 [×33] AC → P2PK (33-byte payload)
├─ 41 [×65] AC → P2PK (65-byte payload)
├─ 6A … (OP_RETURN prefix)
│ ├─ complete push-only operations → NullData
│ └─ otherwise → Unrecognized
└─ (none matched)
├─ [51–60] [02–28] [×push_length] → OtherWitnessProgram(version)
└─ structural m-of-n (1 ≤ m ≤ n ≤ 20, minimal counts)
├─ AND key-payload count = n → BareMultisig
└─ otherwise → Unrecognized
Example
fn wallet_supports_output(output: Output) -> Bool {
case classify_output_script(get_output_script_pubkey(output)) {
P2WPKH | P2TR -> True
_ -> False
}
}
pub fn compute_base_size(tx: Transaction(state)) -> Int
Compute the transaction’s BIP 141 base size in bytes.
This is the byte size of the complete canonical stripped serialization
produced by serialize_stripped. For legacy transactions, it is identical
to compute_total_size. For SegWit transactions, it excludes the marker,
flag, and all witness stack bytes.
This calculation measures the existing transaction fields without allocating
a serialized BitArray.
pub fn compute_total_size(tx: Transaction(state)) -> Int
Compute the transaction’s BIP 141 total size in bytes.
This is the byte size of the complete canonical wire serialization produced
by serialize. For legacy transactions, it is identical to
compute_base_size. For SegWit transactions, it also includes the marker,
flag, and all witness stack bytes.
This calculation measures the existing transaction fields without allocating
a serialized BitArray.
pub fn compute_txid(tx: Transaction(state)) -> hash256.Hash256
Compute the transaction identifier (txid) for a transaction.
The txid is the double SHA-256 hash of the transaction’s stripped serialization. The returned hash uses the same little-endian byte order found on the Bitcoin wire.
pub fn compute_virtual_size(tx: Transaction(state)) -> Int
Compute the transaction’s virtual size in virtual bytes (vbytes).
A virtual byte is four weight units. The result is the transaction’s BIP 141 weight divided by four and rounded up. For example, a transaction weighing 665 weight units has a virtual size of 167 vbytes.
This calculation does not allocate a serialized BitArray or enforce size
or weight limits.
pub fn compute_weight(tx: Transaction(state)) -> Int
Compute the transaction’s BIP 141 weight in weight units.
Weight is calculated as base_size * 3 + total_size. Equivalently, each
byte in the stripped serialization contributes four weight units and each
byte present only in the complete serialization contributes one.
This calculation measures the existing transaction fields without allocating
a serialized BitArray or measuring the base fields more than once.
This function only measures the transaction. It does not enforce the enclosing block’s consensus weight limit.
pub fn compute_wtxid(tx: Transaction(state)) -> hash256.Hash256
Compute the witness transaction identifier (wtxid) for a transaction.
The wtxid is the double SHA-256 hash of the transaction’s full wire serialization. The returned hash uses the same little-endian byte order found on the Bitcoin wire. For legacy transactions, the wtxid is identical to the txid.
pub fn decode_policy_max_input_count(policy: DecodePolicy) -> Int
Get the maximum transaction input count.
pub fn decode_policy_max_output_count(
policy: DecodePolicy,
) -> Int
Get the maximum transaction output count.
pub fn decode_policy_max_tx_size(policy: DecodePolicy) -> Int
Get the maximum serialized transaction size.
pub fn decode_policy_max_witness_item_count(
policy: DecodePolicy,
) -> Int
Get the maximum total witness item count across all input stacks.
pub fn decode_policy_with_max_input_count(
policy: DecodePolicy,
max_input_count: Int,
) -> DecodePolicy
Return a policy with a custom maximum transaction input count.
After the decoded count has been checked against the bytes remaining in the input, this limit is enforced before any input is decoded. It can bound input parsing and list allocation more tightly than the transaction-size limit alone.
pub fn decode_policy_with_max_output_count(
policy: DecodePolicy,
max_output_count: Int,
) -> DecodePolicy
Return a policy with a custom maximum transaction output count.
After the decoded count has been checked against the bytes remaining in the input, this limit is enforced before any output is decoded. It can bound output parsing and list allocation more tightly than the transaction-size limit alone.
pub fn decode_policy_with_max_tx_size(
policy: DecodePolicy,
max_tx_size: Int,
) -> DecodePolicy
Return a policy with a custom maximum serialized transaction size.
For byte-aligned input, this limit is checked before whole-value decoding begins and provides its primary byte envelope. It is not applied when a transaction is decoded as a prefix inside a block; the enclosing block policy owns that byte envelope.
pub fn decode_policy_with_max_witness_item_count(
policy: DecodePolicy,
max_witness_item_count: Int,
) -> DecodePolicy
Return a policy with a custom maximum total witness item count.
This limit counts items across all input stacks in one transaction, including zero-length items. After each stack’s count has been checked against the bytes remaining, its contribution to the cumulative count is checked before any of its items are decoded. Empty stacks contribute zero items.
pub fn default_decode_policy() -> DecodePolicy
The default transaction decoding policy.
Provides permissive limits, applied automatically when using deserialize
or deserialize_hex. They indirectly bound heap usage during binary
decoding by limiting serialized size and collection counts. Callers with
stricter resource budgets can configure lower limits.
By default, whole-value decoding accepts serialized transactions up to 4,000,000 bytes, up to 100,000 inputs, up to 125,000 outputs, and up to 4,000,000 witness items in total across all input stacks, including zero-length items.
These defaults cover canonical encodings of consensus-valid transactions within Bitcoin’s 4,000,000-weight-unit block limit. Consensus validation is separate.
pub fn deserialize(
bytes: BitArray,
) -> Result(Transaction(Parsed), DecodeError)
Deserialize a Bitcoin transaction from its canonical Bitcoin wire-format serialization.
This is the standard entry point for converting a complete serialized Bitcoin transaction into a typed value. The entire input must contain exactly one transaction; trailing bytes are rejected.
This function applies the permissive default_decode_policy limits on
transaction size, input/output counts, and total witness item count.
For custom resource limits, use deserialize_with_policy instead.
The returned transaction is marked as Parsed, meaning its structure was
successfully parsed but it has not yet been checked against Bitcoin
consensus rules.
Returns
Ok(Transaction(Parsed)): Successfully deserialized within the default policy limits.Error(DecodeError): The bytes were not a well-formed transaction encoding within the default policy limits.
pub fn deserialize_hex(
hex: String,
) -> Result(Transaction(Parsed), DeserializeHexError)
Deserialize a Bitcoin transaction from its hexadecimal string representation.
This is a convenience function that combines hex-to-bytes conversion with transaction deserialization. It’s useful when working with transaction data in hexadecimal format, such as from block explorers, RPC responses, or test vectors.
This function applies default_decode_policy for resource limits.
For custom resource limits, use deserialize_hex_with_policy instead.
Valid hex that exceeds the byte-size limit is rejected before conversion. Invalid hex takes precedence, including for oversized input. Checking an oversized string’s characters still requires work proportional to its length.
Returns
Ok(Transaction(Parsed)): Successfully deserialized within the default policy limits.Error(InvalidHex): The hex string was invalid (odd length or invalid characters).Error(DecodeFailed(error)): The decoded bytes were not a well-formed transaction encoding within the default policy limits.
pub fn deserialize_hex_with_policy(
hex: String,
policy: DecodePolicy,
) -> Result(Transaction(Parsed), DeserializeHexError)
Deserialize a Bitcoin transaction from hexadecimal with custom resource limits.
This function combines hex-to-bytes conversion with policy-based transaction deserialization, providing both the convenience of hexadecimal input and fine-grained control over resource limits. Use this when working with hex-encoded transaction data that requires custom resource constraints.
Valid hex that exceeds the byte-size limit is rejected before conversion. Invalid hex takes precedence, including for oversized input. Checking an oversized string’s characters still requires work proportional to its length.
Returns
Ok(Transaction(Parsed)): Successfully deserialized within the supplied policy limits.Error(InvalidHex): The hex string was invalid (odd length or invalid characters).Error(DecodeFailed(error)): The decoded bytes were not a well-formed transaction encoding within the supplied policy limits.
pub fn deserialize_with_policy(
bytes: BitArray,
policy: DecodePolicy,
) -> Result(Transaction(Parsed), DecodeError)
Deserialize a Bitcoin transaction with custom resource limits.
Like deserialize, but accepts a DecodePolicy to override the resource
limits applied during decoding. Use default_decode_policy and the
decode_policy_with_* builder functions to construct custom policies.
Byte alignment is validated before resource limits. For byte-aligned inputs,
limits that are exceeded produce a PolicyLimitExceeded error. See
DecodePolicy and default_decode_policy for available options and defaults.
Returns
Ok(Transaction(Parsed)): Successfully deserialized within the supplied policy limits.Error(DecodeError): The bytes were not a well-formed transaction encoding within the supplied policy limits.
pub fn get_decode_error_kind(err: DecodeError) -> DecodeErrorKind
Get the specific kind of decoding error that occurred.
Returns the DecodeErrorKind variant that categorizes what went wrong,
such as UnexpectedEof, NonMinimalCompactSize, PolicyLimitExceeded, etc.
This allows you to handle different error types differently.
Example
fn is_truncated(error: DecodeError) -> Bool {
case get_decode_error_kind(error) {
UnexpectedEof(_, _) -> True
InsufficientBytes(_, _) -> True
_ -> False
}
}
pub fn get_decode_error_offset(err: DecodeError) -> Int
Get the byte offset where a decoding error occurred.
The offset is a zero-based position into the input buffer, indicating where the decoder was reading when it encountered the error. This is useful for debugging and error reporting.
pub fn get_decode_error_path(err: DecodeError) -> String
Get the structural path for a decoding error.
The path is derived from internal parser-location details and uses a stable,
machine-friendly format rooted at transaction. Collection indices are
zero-based and written in brackets.
For example, an error at the scriptSig length prefix of the third input
produces transaction.inputs[2].script_sig.length.
The path identifies where the error occurred but does not include the byte
offset or error kind. Use get_decode_error_offset and
get_decode_error_kind for those details.
pub fn get_input_count(tx: Transaction(state)) -> Int
Get the number of inputs in a transaction.
Returns the decoded CompactSize input count from the transaction wire encoding.
pub fn get_input_script_sig(
input: Input,
) -> ScriptBytes(InputScript)
Get the scriptSig from an input.
For non-coinbase inputs, the scriptSig may provide data used during script execution. This library does not execute or validate scripts.
pub fn get_input_sequence(input: Input) -> Int
Get the sequence number from an input.
Sequence values can participate in relative lock-time consensus rules and transaction replacement policy. This library exposes the value without interpreting those semantics.
pub fn get_inputs(tx: Transaction(state)) -> List(Input)
Get the transaction inputs.
Returns the inputs in the same order they appear in the transaction serialization.
pub fn get_lock_time(tx: Transaction(state)) -> Int
Get the unsigned 32-bit lock-time value from a transaction.
Values less than 500,000,000 encode block heights, values greater than or equal to 500,000,000 encode Unix timestamps, and zero encodes no lock-time constraint.
Whether this value constrains transaction finality also depends on the input sequence numbers and block context. This library exposes the value without evaluating finality.
pub fn get_outpoint_txid(outpoint: OutPoint) -> hash256.Hash256
Get the transaction ID from an outpoint.
The hash uses the same little-endian byte order found on the Bitcoin wire. For coinbase inputs, which do not reference a previous output, this returns an all-zero hash.
pub fn get_outpoint_vout(outpoint: OutPoint) -> Int
Get the output index from an outpoint.
Returns the zero-based index of the output within the referenced transaction.
For coinbase inputs (which don’t reference a previous output), returns 0xFFFFFFFF,
a special sentinel value indicating no previous output.
pub fn get_output_count(tx: Transaction(state)) -> Int
Get the number of outputs in a transaction.
Returns the decoded CompactSize output count from the transaction wire encoding.
pub fn get_output_script_pubkey(
output: Output,
) -> ScriptBytes(OutputScript)
Get the raw scriptPubKey from a transaction output.
A scriptPubKey encodes the conditions for spending an output. This library exposes the script bytes without executing or validating them.
pub fn get_output_value(output: Output) -> OutputValue
Get the decoded value from a transaction output.
For an output from a Transaction(Parsed), this value may be negative or
exceed Bitcoin’s consensus money range. Use
validate_context_free_consensus to check the transaction’s output values.
pub fn get_outputs(tx: Transaction(state)) -> List(Output)
Get the transaction outputs.
Returns the outputs in the same order they appear in the transaction serialization.
pub fn get_raw_script_bytes(script: ScriptBytes(k)) -> BitArray
Get the raw bytes from a ScriptBytes.
pub fn get_script_size(script: ScriptBytes(k)) -> Int
Get the byte size of a ScriptBytes.
The size is measured from the raw script bytes and excludes the CompactSize length prefix used when the script is serialized in a transaction.
pub fn get_version(tx: Transaction(state)) -> Int
Get the transaction version.
The version may affect which consensus rules or transaction semantics apply.
The version field is encoded as 4 little-endian bytes in the transaction
wire format. This function returns those bytes interpreted as an unsigned
32-bit integer in the range 0 through 4_294_967_295.
Some Bitcoin documentation and APIs have represented this field as a signed 32-bit integer. This function does not use that convention.
For example, raw version bytes ff ff ff ff are returned as
4_294_967_295, not -1.
pub fn get_witness_item_bytes(item: WitnessItem) -> BitArray
Get the raw bytes from a witness item.
pub fn get_witness_items(
stack: WitnessStack,
) -> List(WitnessItem)
Get the witness items from a witness stack.
Returns the witness items in order as they appear in the serialization.
pub fn get_witnesses(
tx: Transaction(state),
) -> Result(List(WitnessStack), Nil)
Get the witness stacks from a SegWit transaction.
For SegWit transactions, the witness stacks are returned in order, corresponding 1-to-1 with the transaction inputs by position.
Returns
Ok(witnesses): The transaction uses SegWit serialization.Error(Nil): The transaction uses legacy serialization, which does not contain witness data.
pub fn has_coinbase_shape(
tx: Transaction(ContextFreeValidated),
) -> Bool
Check whether a context-free-validated transaction has coinbase shape.
The ContextFreeValidated state guarantees that transaction-local consensus
checks have already been applied. For this function, True means the
transaction has the context-free coinbase structure:
- exactly one input
- the input uses the null outpoint
- the coinbase scriptSig length is within the consensus range
This does not prove that the transaction is valid as the coinbase transaction of a block. Block-level checks such as transaction position, block height, subsidy, and fees are outside the scope of this function.
Returns True if the transaction has coinbase shape, False otherwise.
pub fn input_has_null_outpoint(input: Input) -> Bool
Check whether an input contains the null outpoint.
The null outpoint is the structural coinbase input marker. This function
does not establish that the containing transaction has valid coinbase shape.
Use validate_context_free_consensus followed by has_coinbase_shape for
that guarantee.
pub fn is_null_outpoint(outpoint: OutPoint) -> Bool
Check whether an outpoint is the null outpoint.
The null outpoint is the special previous output reference used as the
coinbase input marker: an all-zero txid with vout 0xFFFFFFFF.
pub fn is_segwit(tx: Transaction(state)) -> Bool
Check whether a transaction uses the SegWit format.
SegWit (Segregated Witness) transactions separate witness data from the main transaction structure, enabling features like improved scalability and transaction malleability fixes.
Returns True for SegWit transactions, False for legacy transactions.
pub fn is_witness_stack_empty(stack: WitnessStack) -> Bool
Check whether a witness stack contains no items.
A stack containing a zero-length item is not empty. Emptiness refers to the number of items, not the number of bytes contained in those items.
pub fn output_value_to_bytes_le(value: OutputValue) -> BitArray
Return an output amount’s exact eight bytes in little-endian wire order.
pub fn output_value_to_int(
value: OutputValue,
) -> Result(Int, Nil)
Attempt to convert an output amount to a native integer.
Always succeeds on the Erlang target. On the JavaScript target, succeeds
only within the safe integer range -9_007_199_254_740_991 through
9_007_199_254_740_991, inclusive; otherwise returns Error(Nil) without
rounding the amount.
This conversion does not check Bitcoin’s consensus money range. Output
amounts from a transaction that passed validate_context_free_consensus
are guaranteed to convert successfully on both targets.
pub fn output_value_to_string(value: OutputValue) -> String
Return an output amount’s exact signed base-10 representation.
This preserves the full value on both Erlang and JavaScript targets, including amounts outside Bitcoin’s consensus money range.
pub fn serialize(tx: Transaction(state)) -> BitArray
Serialize a transaction in its full wire form, including witness data.
Returns the complete serialization used when computing the wtxid:
version, SegWit marker and flag (if applicable), inputs, outputs,
witness stacks (if applicable), and lock_time. For legacy transactions,
this is identical to serialize_stripped.
See Also
compute_wtxid— hashes this serialization to produce the wtxidserialize_stripped— the no-witness serialization used for the txid
pub fn serialize_stripped(tx: Transaction(state)) -> BitArray
Serialize a transaction without witness data (the “stripped” form).
Returns the stripped transaction serialization used when computing the
txid: version, inputs, outputs, and lock_time — with no SegWit marker,
flag, or witness stacks, regardless of whether the transaction is SegWit.
See Also
compute_txid— hashes this serialization to produce the txidserialize— the full wire serialization including witness data
pub fn validate_context_free_consensus(
tx: Transaction(Parsed),
) -> Result(
Transaction(ContextFreeValidated),
List(ConsensusViolation),
)
Validate a transaction against context-free Bitcoin consensus rules.
“Context-free” means these checks require only the transaction itself — no UTXO set, no block context, and no knowledge of other transactions.
This function enforces all Bitcoin consensus rules that apply to an individual transaction and can be evaluated without UTXO, script-execution, block, or chain context.
The following consensus rules are enforced:
- At least one input
- At least one output
- Base (stripped) serialization is at most 1,000,000 bytes, matching Bitcoin Core’s transaction-level check. SegWit marker, flag, and witness bytes are excluded from this check but contribute to the enclosing block’s separate 4,000,000-WU weight limit.
- Output values are between 0 and 2,100,000,000,000,000 satoshis
- Cumulative output value does not exceed 2,100,000,000,000,000 satoshis
- Coinbase transactions contain exactly one input
- Coinbase scriptSig length is 2–100 bytes (inclusive)
- No two inputs reference the same previous output
Context-dependent checks — script execution, signature verification, input-spend validation against the UTXO set, and block-level rules — are not performed.
Returns
Ok(Transaction(ContextFreeValidated)): The transaction passed all context-free consensus checks listed above.Error(violations): The transaction failed one or more context-free consensus checks. The list contains the detected violations.