I have an in-depth question that needs good knowledge of the ledger rules.

I was thinking about how to program efficiently and design apps such that they are parallelizable, a good practice for achieving this is building modular and piece wise. While thinking about certain contracts that could validate in parallel I wondered how such transactions are build and specified for validation. This is not a canonical task and can be ambiguous for a validator. So a natural conclusion is that to preserve determinism one has to fully specify a transaction, some question on this specification.

Consider a transaction that tries to consume n eUTxO's of contract instance A and m of the contract instance B. Then this transaction has to have n+m datums that match the inputs.

Question 1: Do you specify in your transaction which datum corresponds to which input or does the validator node matches them by hashing your suggested datum? Also, if certain datums match, can you save on transaction size by appending the datum once and specifying the datum to each input?

Question 2: Do you append the contracts A and B multiple time (n+m times to be exact) to the transaction or just once for each occurrence? Again, the latter would save on transaction size.

Now there is also another integral part of consuming eUTxO's, namely their redeemers. Since each eUTxO generally have a different redeemer one also has to specify which redeemer is associated to which input.

Question 3: How is this association between redeemer en input specified in a transaction? And moreover, can this specification again be non-injective. That is, a redeemer can be appended once to the transaction but be associated to multiple inputs? This would again save on transaction size.

And lastly we have the outputs where we give each one a possible new datum. These new datums, how are the specified and can they be assigned in a non-injective way to save on transaction size?

2 Answers 2


Datums are stored in a hash map per transaction, so if a transaction uses the same datum multiple times, the datum is stored once and only the hashes are stored multiple times. The same goes for redeemers.

(I don't understand all the questions, but this is at least a partial answer. Feel free to add to this answer.)

  • Thank you Sjoerd, This clears things up about the whole "efficient handling of data" in a transaction of datums. Am I correct that you can extend this hash map idea for the redeemer and script as well?
    – Fermat
    Commented Jan 24, 2022 at 11:47
  • @Fermat Indeed. Commented Jan 24, 2022 at 16:28

I don't have good knowledge of ledger rules, but I can refer to TxInfo data type in Plutus

data TxInfo = TxInfo
    { txInfoInputs          :: [TxInInfo] -- ^ Transaction inputs
    , txInfoReferenceInputs :: [TxInInfo] -- ^ Transaction reference inputs
    , txInfoOutputs         :: [TxOut] -- ^ Transaction outputs
    , txInfoFee             :: Value -- ^ The fee paid by this transaction.
    , txInfoMint            :: Value -- ^ The 'Value' minted by this transaction.
    , txInfoDCert           :: [DCert] -- ^ Digests of certificates included in this transaction
    , txInfoWdrl            :: Map StakingCredential Integer -- ^ Withdrawals
    , txInfoValidRange      :: POSIXTimeRange -- ^ The valid range for the transaction.
    , txInfoSignatories     :: [PubKeyHash] -- ^ Signatures provided with the transaction, attested that they all signed the tx
    , txInfoRedeemers       :: Map ScriptPurpose Redeemer
    , txInfoData            :: Map DatumHash Datum
    , txInfoId              :: TxId
    -- ^ Hash of the pending transaction (excluding witnesses)

Here you can see that you need to provide Datum only once per each DatumHash, but for outputs, you need to provide a list [TxOut] with DatumHash in each list item. Redeemers should be provided for each UTxO you are trying to spend.

Regarding contracts, you need to attach script only once even if validating multiple UTxOs.

My answers are based on practical experience, so I may be wrong from Ledger perspective.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.