@@ -301,6 +301,8 @@ module Cardano.Api.Internal.Tx.Body
301301 -- ** Other transaction body types
302302 , TxInsCollateral (.. )
303303 , TxInsReference (.. )
304+ , TxInsReferenceDatums
305+ , getReferenceInputDatumMap
304306 , TxReturnCollateral (.. )
305307 , TxTotalCollateral (.. )
306308 , TxFee (.. )
@@ -570,16 +572,31 @@ deriving instance Eq (TxTotalCollateral era)
570572
571573deriving instance Show (TxTotalCollateral era )
572574
573- data TxInsReference era where
574- TxInsReferenceNone :: TxInsReference era
575+ data TxInsReference build era where
576+ TxInsReferenceNone :: TxInsReference build era
575577 TxInsReference
576578 :: BabbageEraOnwards era
577579 -> [TxIn ]
578- -> TxInsReference era
580+ -- ^ A list of reference inputs
581+ -> TxInsReferenceDatums build
582+ -- ^ A set of datums, whose hashes are referenced in UTXO of reference inputs. Those datums will be inserted
583+ -- to the datum map available to the scripts. Note that inserting a datum with hash not present in the reference
584+ -- input will result in an error on transaction submission.
585+ -> TxInsReference build era
579586
580- deriving instance Eq (TxInsReference era )
587+ deriving instance Eq (TxInsReference build era )
581588
582- deriving instance Show (TxInsReference era )
589+ deriving instance Show (TxInsReference build era )
590+
591+ -- | The actual datums, referenced by hash in the transaction reference inputs.
592+ type TxInsReferenceDatums build = BuildTxWith build (Set HashableScriptData )
593+
594+ getReferenceInputDatumMap
595+ :: TxInsReferenceDatums build
596+ -> Map (Hash ScriptData ) HashableScriptData
597+ getReferenceInputDatumMap = \ case
598+ ViewTx -> mempty
599+ BuildTxWith datumSet -> fromList $ map (\ h -> (hashScriptDataBytes h, h)) $ toList datumSet
583600
584601-- ----------------------------------------------------------------------------
585602-- Transaction fees
@@ -984,7 +1001,7 @@ data TxBodyContent build era
9841001 = TxBodyContent
9851002 { txIns :: TxIns build era
9861003 , txInsCollateral :: TxInsCollateral era
987- , txInsReference :: TxInsReference era
1004+ , txInsReference :: TxInsReference build era
9881005 , txOuts :: [TxOut CtxTx era ]
9891006 , txTotalCollateral :: TxTotalCollateral era
9901007 , txReturnCollateral :: TxReturnCollateral CtxTx era
@@ -1075,25 +1092,36 @@ addTxInCollateral
10751092 :: IsAlonzoBasedEra era => TxIn -> TxBodyContent build era -> TxBodyContent build era
10761093addTxInCollateral txInCollateral = addTxInsCollateral [txInCollateral]
10771094
1078- setTxInsReference :: TxInsReference era -> TxBodyContent build era -> TxBodyContent build era
1095+ setTxInsReference :: TxInsReference build era -> TxBodyContent build era -> TxBodyContent build era
10791096setTxInsReference v txBodyContent = txBodyContent{txInsReference = v}
10801097
10811098modTxInsReference
1082- :: (TxInsReference era -> TxInsReference era ) -> TxBodyContent build era -> TxBodyContent build era
1099+ :: (TxInsReference build era -> TxInsReference build era )
1100+ -> TxBodyContent build era
1101+ -> TxBodyContent build era
10831102modTxInsReference f txBodyContent = txBodyContent{txInsReference = f (txInsReference txBodyContent)}
10841103
10851104addTxInsReference
1086- :: IsBabbageBasedEra era => [TxIn ] -> TxBodyContent build era -> TxBodyContent build era
1087- addTxInsReference txInsReference =
1088- modTxInsReference
1089- ( \ case
1090- TxInsReferenceNone -> TxInsReference babbageBasedEra txInsReference
1091- TxInsReference era xs -> TxInsReference era (xs <> txInsReference)
1092- )
1105+ :: Applicative (BuildTxWith build )
1106+ => IsBabbageBasedEra era
1107+ => [TxIn ]
1108+ -> Set HashableScriptData
1109+ -> TxBodyContent build era
1110+ -> TxBodyContent build era
1111+ addTxInsReference txInsReference scriptData =
1112+ modTxInsReference $
1113+ \ case
1114+ TxInsReferenceNone -> TxInsReference babbageBasedEra txInsReference (pure scriptData)
1115+ TxInsReference era xs bScriptData' -> TxInsReference era (xs <> txInsReference) ((<> scriptData) <$> bScriptData')
10931116
10941117addTxInReference
1095- :: IsBabbageBasedEra era => TxIn -> TxBodyContent build era -> TxBodyContent build era
1096- addTxInReference txInReference = addTxInsReference [txInReference]
1118+ :: Applicative (BuildTxWith build )
1119+ => IsBabbageBasedEra era
1120+ => TxIn
1121+ -> Maybe HashableScriptData
1122+ -> TxBodyContent build era
1123+ -> TxBodyContent build era
1124+ addTxInReference txInReference mDatum = addTxInsReference [txInReference] . fromList $ maybeToList mDatum
10971125
10981126setTxOuts :: [TxOut CtxTx era ] -> TxBodyContent build era -> TxBodyContent build era
10991127setTxOuts v txBodyContent = txBodyContent{txOuts = v}
@@ -1742,11 +1770,11 @@ fromLedgerTxInsCollateral sbe body =
17421770 sbe
17431771
17441772fromLedgerTxInsReference
1745- :: ShelleyBasedEra era -> Ledger. TxBody (ShelleyLedgerEra era ) -> TxInsReference era
1773+ :: ShelleyBasedEra era -> Ledger. TxBody (ShelleyLedgerEra era ) -> TxInsReference ViewTx era
17461774fromLedgerTxInsReference sbe txBody =
17471775 caseShelleyToAlonzoOrBabbageEraOnwards
17481776 (const TxInsReferenceNone )
1749- (\ w -> TxInsReference w $ map fromShelleyTxIn . toList $ txBody ^. L. referenceInputsTxBodyL)
1777+ (\ w -> TxInsReference w ( map fromShelleyTxIn . toList $ txBody ^. L. referenceInputsTxBodyL) ViewTx )
17501778 sbe
17511779
17521780fromLedgerTxTotalCollateral
@@ -2108,11 +2136,11 @@ convPParamsToScriptIntegrityHash
21082136 -> Alonzo. TxDats (ShelleyLedgerEra era )
21092137 -> Set Plutus. Language
21102138 -> StrictMaybe L. ScriptIntegrityHash
2111- convPParamsToScriptIntegrityHash w txProtocolParams redeemers datums languages =
2139+ convPParamsToScriptIntegrityHash w ( BuildTxWith mTxProtocolParams) redeemers datums languages =
21122140 alonzoEraOnwardsConstraints w $
2113- case txProtocolParams of
2114- BuildTxWith Nothing -> SNothing
2115- BuildTxWith ( Just (LedgerProtocolParameters pp) ) ->
2141+ case mTxProtocolParams of
2142+ Nothing -> SNothing
2143+ Just (LedgerProtocolParameters pp) ->
21162144 Alonzo. hashScriptIntegrity (Set. map (L. getLanguageView pp) languages) redeemers datums
21172145
21182146convLanguages :: [(ScriptWitnessIndex , AnyScriptWitness era )] -> Set Plutus. Language
@@ -2122,11 +2150,11 @@ convLanguages witnesses =
21222150 | (_, AnyScriptWitness (PlutusScriptWitness _ v _ _ _ _)) <- witnesses
21232151 ]
21242152
2125- convReferenceInputs :: TxInsReference era -> Set Ledger. TxIn
2153+ convReferenceInputs :: TxInsReference build era -> Set Ledger. TxIn
21262154convReferenceInputs txInsReference =
21272155 case txInsReference of
21282156 TxInsReferenceNone -> mempty
2129- TxInsReference _ refTxins -> fromList $ map toShelleyTxIn refTxins
2157+ TxInsReference _ refTxins _ -> fromList $ map toShelleyTxIn refTxins
21302158
21312159-- | Returns an OSet of proposals from 'TxProposalProcedures'.
21322160convProposalProcedures
@@ -2993,11 +3021,17 @@ collectTxBodyScriptWitnessRequirements
29933021collectTxBodyScriptWitnessRequirements
29943022 aEon
29953023 bc@ TxBodyContent
2996- { txOuts
3024+ { txInsReference
3025+ , txOuts
29973026 } =
29983027 obtainAlonzoScriptPurposeConstraints aEon $ do
29993028 let sbe = shelleyBasedEra @ era
3000- supplementaldatums = TxScriptWitnessRequirements mempty mempty (getSupplementalDatums aEon txOuts) mempty
3029+ supplementaldatums =
3030+ TxScriptWitnessRequirements
3031+ mempty
3032+ mempty
3033+ (getDatums aEon txInsReference txOuts)
3034+ mempty
30013035 txInWits <-
30023036 first TxBodyPlutusScriptDecodeError $
30033037 legacyWitnessToScriptRequirements aEon $
@@ -3051,19 +3085,32 @@ collectTxBodyScriptWitnessRequirements
30513085 , txProposalWits
30523086 ]
30533087
3054- getSupplementalDatums
3088+ -- | Extract datum:
3089+ -- 1. supplemental datums from transaction outputs
3090+ -- 2. datums from reference inputs
3091+ --
3092+ -- Note that this function does not check whose datum datum hashes are present in the reference inputs. This means
3093+ -- if there are redundant datums in 'TxInsReference', a submission of such transaction will fail.
3094+ getDatums
30553095 :: AlonzoEraOnwards era
3096+ -> TxInsReference BuildTx era
3097+ -- ^ reference inputs
30563098 -> [TxOut CtxTx era ]
30573099 -> L. TxDats (ShelleyLedgerEra era )
3058- getSupplementalDatums eon [] = alonzoEraOnwardsConstraints eon mempty
3059- getSupplementalDatums eon txouts =
3060- alonzoEraOnwardsConstraints eon $
3061- L. TxDats $
3062- fromList
3063- [ (L. hashData ledgerData, ledgerData)
3064- | TxOut _ _ (TxOutSupplementalDatum _ d) _ <- txouts
3065- , let ledgerData = toAlonzoData d
3100+ getDatums eon txInsRef txOutsFromTx = alonzoEraOnwardsConstraints eon $ do
3101+ let refTxInsDats =
3102+ [ d
3103+ | TxInsReference _ _ (BuildTxWith datumSet) <- [txInsRef]
3104+ , d <- toList datumSet
30663105 ]
3106+ -- use only supplemental datum
3107+ txOutsDats = [d | TxOut _ _ (TxOutSupplementalDatum _ d) _ <- txOutsFromTx]
3108+ L. TxDats $
3109+ fromList $
3110+ [ (L. hashData ledgerData, ledgerData)
3111+ | d <- refTxInsDats <> txOutsDats
3112+ , let ledgerData = toAlonzoData d
3113+ ]
30673114
30683115extractWitnessableTxIns
30693116 :: AlonzoEraOnwards era
0 commit comments