A simple validator that insures that for every transaction, the amount of ADA being locked into the contract is greater than the amount being unlocked (spent) must be possible given how simple the premise is.
Since we use a UTxO based ledger, indeed we have to track the inputs and outputs from and to the script address. So, we define the amount that is locked/unlocked here as the difference between the value send to the script and the value spent from the script. You are correct that the former (the value send to the address) can be extracted via the function valueLockedBy
defined by,
{-# INLINABLE valueLockedBy #-}
-- | Get the total value locked by the given validator in this transaction.
valueLockedBy :: TxInfo -> ValidatorHash -> Value
valueLockedBy ptx h =
let outputs = map snd (scriptOutputsAt h ptx)
in mconcat outputs
We see that this adds all the value found at the created outputs of the transaction that contain the ValidatorHash
. Here, the scriptOutputsAt
function is defined as,
{-# INLINABLE scriptOutputsAt #-}
scriptOutputsAt h p =
let flt TxOut{txOutDatumHash=Just ds, txOutAddress=Address (ScriptCredential s) _, txOutValue} | s == h = Just (ds, txOutValue)
flt _ = Nothing
in mapMaybe flt (txInfoOutputs p)
Your assessment that currently there is no dedicated function for grabbing the total value of the inputs at the script address is correct. Your list comprehension seems correct. But it is not the only way, we can rewrite the above function to work on the inputs as well,
{-# INLINABLE scriptInputsAt #-}
scriptInputsAt :: ValidatorHash -> TxInfo -> [(OutputDatum, Value)]
scriptInputsAt h p =
let flt TxInInfo{txInInfoResolved=TxOut{txOutDatum=d, txOutAddress=Address (ScriptCredential s) _, txOutValue}} | s == h = Just (d, txOutValue)
flt _ = Nothing
in mapMaybe flt (txInfoInputs p)
{-# INLINABLE valueUnlockedBy #-}
valueUnlockedBy :: TxInfo -> ValidatorHash -> Value
valueUnlockedBy ptx h =
let inputs = map snd (scriptInputsAt h ptx)
in mconcat inputs
Disclaimer: the above functions are for plutusV2 (contexts are handled differently between the two versions).