@@ -301,6 +301,8 @@ module Cardano.Api.Internal.Tx.Body
301
301
-- ** Other transaction body types
302
302
, TxInsCollateral (.. )
303
303
, TxInsReference (.. )
304
+ , TxInsReferenceActualDatums
305
+ , getReferenceInputDatumMap
304
306
, TxReturnCollateral (.. )
305
307
, TxTotalCollateral (.. )
306
308
, TxFee (.. )
@@ -432,6 +434,8 @@ import Cardano.Api.Internal.SerialiseJSON
432
434
import Cardano.Api.Internal.Tx.BuildTxWith
433
435
import Cardano.Api.Internal.Tx.Output
434
436
import Cardano.Api.Internal.Tx.Sign
437
+ import Cardano.Api.Internal.Tx.UTxO (UTxO )
438
+ import Cardano.Api.Internal.Tx.UTxO qualified as UTxO
435
439
import Cardano.Api.Internal.TxIn
436
440
import Cardano.Api.Internal.TxMetadata
437
441
import Cardano.Api.Internal.Utils
@@ -570,16 +574,32 @@ deriving instance Eq (TxTotalCollateral era)
570
574
571
575
deriving instance Show (TxTotalCollateral era )
572
576
573
- data TxInsReference era where
574
- TxInsReferenceNone :: TxInsReference era
577
+ data TxInsReference build era where
578
+ TxInsReferenceNone :: TxInsReference build era
575
579
TxInsReference
576
580
:: BabbageEraOnwards era
577
581
-> [TxIn ]
578
- -> TxInsReference era
582
+ -- ^ A list of reference inputs
583
+ -> TxInsReferenceActualDatums build
584
+ -- ^ A set of datums, which hashes are referenced in UTXO of reference inputs. Those datums will be inserted
585
+ -- to the datum map available to the scripts.
586
+ -> TxInsReference build era
579
587
580
- deriving instance Eq (TxInsReference era )
588
+ deriving instance Eq (TxInsReference build era )
581
589
582
- deriving instance Show (TxInsReference era )
590
+ deriving instance Show (TxInsReference build era )
591
+
592
+ -- | The actual datums, referenced by hash in the transaction reference inputs.
593
+ --
594
+ -- Only datums referenced by hashes in UTXOs of reference inputs, will be inserted into the transaction.
595
+ type TxInsReferenceActualDatums build = BuildTxWith build (Set HashableScriptData )
596
+
597
+ getReferenceInputDatumMap
598
+ :: TxInsReferenceActualDatums build
599
+ -> Map (Hash ScriptData ) HashableScriptData
600
+ getReferenceInputDatumMap = \ case
601
+ ViewTx -> mempty
602
+ BuildTxWith datumSet -> fromList $ map (\ h -> (hashScriptDataBytes h, h)) $ toList datumSet
583
603
584
604
-- ----------------------------------------------------------------------------
585
605
-- Transaction fees
@@ -984,7 +1004,7 @@ data TxBodyContent build era
984
1004
= TxBodyContent
985
1005
{ txIns :: TxIns build era
986
1006
, txInsCollateral :: TxInsCollateral era
987
- , txInsReference :: TxInsReference era
1007
+ , txInsReference :: TxInsReference build era
988
1008
, txOuts :: [TxOut CtxTx era ]
989
1009
, txTotalCollateral :: TxTotalCollateral era
990
1010
, txReturnCollateral :: TxReturnCollateral CtxTx era
@@ -1075,25 +1095,35 @@ addTxInCollateral
1075
1095
:: IsAlonzoBasedEra era => TxIn -> TxBodyContent build era -> TxBodyContent build era
1076
1096
addTxInCollateral txInCollateral = addTxInsCollateral [txInCollateral]
1077
1097
1078
- setTxInsReference :: TxInsReference era -> TxBodyContent build era -> TxBodyContent build era
1098
+ setTxInsReference :: TxInsReference build era -> TxBodyContent build era -> TxBodyContent build era
1079
1099
setTxInsReference v txBodyContent = txBodyContent{txInsReference = v}
1080
1100
1081
1101
modTxInsReference
1082
- :: (TxInsReference era -> TxInsReference era ) -> TxBodyContent build era -> TxBodyContent build era
1102
+ :: (TxInsReference build era -> TxInsReference build era )
1103
+ -> TxBodyContent build era
1104
+ -> TxBodyContent build era
1083
1105
modTxInsReference f txBodyContent = txBodyContent{txInsReference = f (txInsReference txBodyContent)}
1084
1106
1085
1107
addTxInsReference
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
- )
1108
+ :: Applicative (BuildTxWith build )
1109
+ => IsBabbageBasedEra era
1110
+ => [TxIn ]
1111
+ -> Set HashableScriptData
1112
+ -> TxBodyContent build era
1113
+ -> TxBodyContent build era
1114
+ addTxInsReference txInsReference scriptData =
1115
+ modTxInsReference $
1116
+ \ case
1117
+ TxInsReferenceNone -> TxInsReference babbageBasedEra txInsReference (pure scriptData)
1118
+ TxInsReference era xs bScriptData' -> TxInsReference era (xs <> txInsReference) ((<> scriptData) <$> bScriptData')
1093
1119
1094
1120
addTxInReference
1095
- :: IsBabbageBasedEra era => TxIn -> TxBodyContent build era -> TxBodyContent build era
1096
- addTxInReference txInReference = addTxInsReference [txInReference]
1121
+ :: Applicative (BuildTxWith build )
1122
+ => IsBabbageBasedEra era
1123
+ => TxIn
1124
+ -> TxBodyContent build era
1125
+ -> TxBodyContent build era
1126
+ addTxInReference txInReference = addTxInsReference [txInReference] mempty
1097
1127
1098
1128
setTxOuts :: [TxOut CtxTx era ] -> TxBodyContent build era -> TxBodyContent build era
1099
1129
setTxOuts v txBodyContent = txBodyContent{txOuts = v}
@@ -1370,9 +1400,11 @@ createTransactionBody
1370
1400
:: forall era
1371
1401
. HasCallStack
1372
1402
=> ShelleyBasedEra era
1403
+ -> UTxO era
1404
+ -- ^ UTXO for reference inputs
1373
1405
-> TxBodyContent BuildTx era
1374
1406
-> Either TxBodyError (TxBody era )
1375
- createTransactionBody sbe bc =
1407
+ createTransactionBody sbe utxo bc =
1376
1408
shelleyBasedEraConstraints sbe $ do
1377
1409
(sData, mScriptIntegrityHash, scripts) <-
1378
1410
caseShelleyToMaryOrAlonzoEraOnwards
@@ -1387,7 +1419,7 @@ createTransactionBody sbe bc =
1387
1419
)
1388
1420
( \ aeon -> do
1389
1421
TxScriptWitnessRequirements languages scripts dats redeemers <-
1390
- collectTxBodyScriptWitnessRequirements aeon bc
1422
+ collectTxBodyScriptWitnessRequirements aeon utxo bc
1391
1423
1392
1424
let pparams = txProtocolParams bc
1393
1425
sData = TxBodyScriptData aeon dats redeemers
@@ -1742,11 +1774,11 @@ fromLedgerTxInsCollateral sbe body =
1742
1774
sbe
1743
1775
1744
1776
fromLedgerTxInsReference
1745
- :: ShelleyBasedEra era -> Ledger. TxBody (ShelleyLedgerEra era ) -> TxInsReference era
1777
+ :: ShelleyBasedEra era -> Ledger. TxBody (ShelleyLedgerEra era ) -> TxInsReference ViewTx era
1746
1778
fromLedgerTxInsReference sbe txBody =
1747
1779
caseShelleyToAlonzoOrBabbageEraOnwards
1748
1780
(const TxInsReferenceNone )
1749
- (\ w -> TxInsReference w $ map fromShelleyTxIn . toList $ txBody ^. L. referenceInputsTxBodyL)
1781
+ (\ w -> TxInsReference w ( map fromShelleyTxIn . toList $ txBody ^. L. referenceInputsTxBodyL) ViewTx )
1750
1782
sbe
1751
1783
1752
1784
fromLedgerTxTotalCollateral
@@ -2108,11 +2140,11 @@ convPParamsToScriptIntegrityHash
2108
2140
-> Alonzo. TxDats (ShelleyLedgerEra era )
2109
2141
-> Set Plutus. Language
2110
2142
-> StrictMaybe L. ScriptIntegrityHash
2111
- convPParamsToScriptIntegrityHash w txProtocolParams redeemers datums languages =
2143
+ convPParamsToScriptIntegrityHash w ( BuildTxWith mTxProtocolParams) redeemers datums languages =
2112
2144
alonzoEraOnwardsConstraints w $
2113
- case txProtocolParams of
2114
- BuildTxWith Nothing -> SNothing
2115
- BuildTxWith ( Just (LedgerProtocolParameters pp) ) ->
2145
+ case mTxProtocolParams of
2146
+ Nothing -> SNothing
2147
+ Just (LedgerProtocolParameters pp) ->
2116
2148
Alonzo. hashScriptIntegrity (Set. map (L. getLanguageView pp) languages) redeemers datums
2117
2149
2118
2150
convLanguages :: [(ScriptWitnessIndex , AnyScriptWitness era )] -> Set Plutus. Language
@@ -2122,11 +2154,11 @@ convLanguages witnesses =
2122
2154
| (_, AnyScriptWitness (PlutusScriptWitness _ v _ _ _ _)) <- witnesses
2123
2155
]
2124
2156
2125
- convReferenceInputs :: TxInsReference era -> Set Ledger. TxIn
2157
+ convReferenceInputs :: TxInsReference build era -> Set Ledger. TxIn
2126
2158
convReferenceInputs txInsReference =
2127
2159
case txInsReference of
2128
2160
TxInsReferenceNone -> mempty
2129
- TxInsReference _ refTxins -> fromList $ map toShelleyTxIn refTxins
2161
+ TxInsReference _ refTxins _ -> fromList $ map toShelleyTxIn refTxins
2130
2162
2131
2163
-- | Returns an OSet of proposals from 'TxProposalProcedures'.
2132
2164
convProposalProcedures
@@ -2986,18 +3018,27 @@ collectTxBodyScriptWitnessRequirements
2986
3018
:: forall era
2987
3019
. IsShelleyBasedEra era
2988
3020
=> AlonzoEraOnwards era
3021
+ -> UTxO era
3022
+ -- ^ UTXO for reference inputs
2989
3023
-> TxBodyContent BuildTx era
2990
3024
-> Either
2991
3025
TxBodyError
2992
3026
(TxScriptWitnessRequirements (ShelleyLedgerEra era ))
2993
3027
collectTxBodyScriptWitnessRequirements
2994
3028
aEon
3029
+ utxo
2995
3030
bc@ TxBodyContent
2996
- { txOuts
3031
+ { txInsReference
3032
+ , txOuts
2997
3033
} =
2998
3034
obtainAlonzoScriptPurposeConstraints aEon $ do
2999
3035
let sbe = shelleyBasedEra @ era
3000
- supplementaldatums = TxScriptWitnessRequirements mempty mempty (getSupplementalDatums aEon txOuts) mempty
3036
+ supplementaldatums =
3037
+ TxScriptWitnessRequirements
3038
+ mempty
3039
+ mempty
3040
+ (getDatums aEon txInsReference utxo txOuts)
3041
+ mempty
3001
3042
txInWits <-
3002
3043
first TxBodyPlutusScriptDecodeError $
3003
3044
legacyWitnessToScriptRequirements aEon $
@@ -3051,19 +3092,35 @@ collectTxBodyScriptWitnessRequirements
3051
3092
, txProposalWits
3052
3093
]
3053
3094
3054
- getSupplementalDatums
3095
+ -- | Extract datum:
3096
+ -- 1. supplemental datums from transaction outputs
3097
+ -- 2. datums from reference inputs, whose hashes are present in UTXO (for those inputs)
3098
+ getDatums
3055
3099
:: AlonzoEraOnwards era
3100
+ -> TxInsReference BuildTx era
3101
+ -- ^ reference inputs
3102
+ -> UTxO era
3103
+ -- ^ UTxO for reference inputs
3056
3104
-> [TxOut CtxTx era ]
3057
3105
-> 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
3106
+ getDatums eon txInsRef utxo txOutsFromTx = alonzoEraOnwardsConstraints eon $ do
3107
+ let refTxInsDats =
3108
+ [ d
3109
+ | TxInsReference _ txIns datumSet <- [txInsRef]
3110
+ , let datumMap = getReferenceInputDatumMap datumSet
3111
+ , txIn <- txIns
3112
+ , -- resolve only hashes
3113
+ TxOut _ _ (TxOutDatumHash _ datumHash) _ <- maybeToList $ UTxO. lookup txIn utxo
3114
+ , d <- maybeToList $ Map. lookup datumHash datumMap
3066
3115
]
3116
+ -- use only supplemental datum
3117
+ txOutsDats = [d | TxOut _ _ (TxOutSupplementalDatum _ d) _ <- txOutsFromTx]
3118
+ L. TxDats $
3119
+ fromList $
3120
+ [ (L. hashData ledgerData, ledgerData)
3121
+ | d <- refTxInsDats <> txOutsDats
3122
+ , let ledgerData = toAlonzoData d
3123
+ ]
3067
3124
3068
3125
extractWitnessableTxIns
3069
3126
:: AlonzoEraOnwards era
0 commit comments