Is your feature request related to a problem? Please describe.
Our defi-kernel trading engine needs reproducible candidate bytes for evaluation, authorization and recovery. TransactionBuilder.reference_inputs is a Python set; _build_tx_body serializes its iteration order. The same inserted references produce different body hashes across Python hash seeds, so we currently override a private method.
Describe the solution you'd like
A supported opt-in ordering policy for newly constructed candidates, using a stable out-ref order before evaluation and protocol-index resolution. Preserve existing default behavior and never normalize decoded/imported transaction CBOR: that would change existing hashes/signatures.
Describe alternatives you've considered
A private builder override works locally but is fragile. A fixed process hash seed does not establish a portable ordering contract.
Additional context
Offline reproduction, Linux/Python 3.12.14; reproduced on PyCardano 0.18.0 and current main 3bc5677. Save as refs.py and run with PYTHONHASHSEED=1 python refs.py, then seeds 2–5:
from types import SimpleNamespace
import pycardano as pc
address = pc.Address(pc.VerificationKeyHash(b"p" * 28), network=pc.Network.TESTNET)
builder = pc.TransactionBuilder(SimpleNamespace())
builder.add_input(pc.UTxO(
pc.TransactionInput(pc.TransactionId(b"z" * 32), 0),
pc.TransactionOutput(address, 10_000_000),
))
builder.add_output(pc.TransactionOutput(address, 9_800_000))
builder.fee = 200_000
for i in range(7):
builder.reference_inputs.add(
pc.TransactionInput(pc.TransactionId(bytes([i]) * 32), i)
)
body = builder._build_tx_body()
print([ref.index for ref in body.reference_inputs], str(body.id))
Seeds 1 and 2 produced [4, 3, 6, 2, 0, 1, 5] and [1, 0, 4, 2, 5, 3, 6]; five seeds yielded five body hashes. This isolates construction internals, not ledger validation; unsorted serialization is not claimed to be ledger-invalid.
Acceptance: identical bytes in opt-in mode across insertion/hash-seed permutations; unchanged default/imported bytes; consistent handling of mixed UTxO/TransactionInput references and duplicate out-refs; resolved redeemer indices must match the final order. No automatic callback discovery or broader builder redesign is requested.
Created by gpt-6-astra high under supervision of @Cerkoryn
Is your feature request related to a problem? Please describe.
Our defi-kernel trading engine needs reproducible candidate bytes for evaluation, authorization and recovery.
TransactionBuilder.reference_inputsis a Python set; _build_tx_body serializes its iteration order. The same inserted references produce different body hashes across Python hash seeds, so we currently override a private method.Describe the solution you'd like
A supported opt-in ordering policy for newly constructed candidates, using a stable out-ref order before evaluation and protocol-index resolution. Preserve existing default behavior and never normalize decoded/imported transaction CBOR: that would change existing hashes/signatures.
Describe alternatives you've considered
A private builder override works locally but is fragile. A fixed process hash seed does not establish a portable ordering contract.
Additional context
Offline reproduction, Linux/Python 3.12.14; reproduced on PyCardano 0.18.0 and current main
3bc5677. Save asrefs.pyand run withPYTHONHASHSEED=1 python refs.py, then seeds 2–5:Seeds 1 and 2 produced
[4, 3, 6, 2, 0, 1, 5]and[1, 0, 4, 2, 5, 3, 6]; five seeds yielded five body hashes. This isolates construction internals, not ledger validation; unsorted serialization is not claimed to be ledger-invalid.Acceptance: identical bytes in opt-in mode across insertion/hash-seed permutations; unchanged default/imported bytes; consistent handling of mixed UTxO/TransactionInput references and duplicate out-refs; resolved redeemer indices must match the final order. No automatic callback discovery or broader builder redesign is requested.
Created by gpt-6-astra high under supervision of @Cerkoryn