2

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. However, it seems that there is a gap in the provided context functions.

We can easily get the amount of ADA that is locked in the transaction with: adaLockedBy ctx ownHash

But there is no equivalent function to get the amount of ADA unlocked in the transaction.

Am I correct in thinking that currently the only way to get the total amount of ADA unlocked in the transaction is to filter script inputs for ? ex:

[txOutValue (txInInfoResolved i) | i <- txInfoInputs (scriptContextInfoTx ctx), ((==) (txOutAddress (txInInfoResolved i)) (ScrptAddress))]

Is there no valueUnlockedBy ctx ownHash?

1 Answer 1

1

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).

1

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.