Question
What is the correct way to compare two instances of Value
data type?
Context
I would like to check if outgoing transaction identified by PubKeyHash
has the same Value
as Value
which was locked into smartcontract but I keep getting weird errors like so: Command failed: transaction submit Error: Error while submitting tx: ShelleyTxValidationError ShelleyBasedEraAlonzo (ApplyTxError [UtxowFailure (WrappedShelleyEraFailure (UtxoFailure (UtxosFailure (ValidationTagMismatch (IsValid True) (FailedUnexpectedly [PlutusFailure "\nThe 3 arg plutus script (PlutusScript PlutusV1 ScriptHash \"d13196be073516394395be6399e6895957d1a16c960d215d8b1d5e9f\") fails...
It seems to me as if working with Value
data type crashes smartcontract.
I have tried creating SC with functions like:
data LockFundsDatum = LockFundsDatum
{ beneficiary :: !PubKeyHash
} deriving Show
lockedValue :: Value
lockedValue = valueLockedBy info (ownHash ctx)
validate :: Bool
validate = elem lockedValue (pubKeyOutputsAt (beneficiary datum) info)
or
findTxFromThisSc :: Maybe TxOut
findTxFromThisSc = case findOwnInput ctx of
Just txInInfo -> Just (txInInfoResolved txInInfo)
Nothing -> Nothing
getValuePaidToPkh :: Value
getValuePaidToPkh = valuePaidTo info (beneficiary dat)
valueOutInLovelaces :: Value -> Integer
valueOutInLovelaces v = valueOf v adaSymbol adaToken
validate :: Bool
validate = case findTxFromThisSc of
Just txo -> traceIfFalse "Value paid to pkh owner isn't equal to 2000000" (valueOutInLovelaces getValuePaidToPkh == 2000000)
Nothing -> traceIfFalse "Tx from this sc was not found" False
But contract fails everytime. I think it is because I'm trying to use default compare with Value
while it is not allowed.
Fullcode
data LockFundsDatum = LockFundsDatum
{ beneficiary :: !PubKeyHash
, lockedTokensID :: !CurrencySymbol
, lockedTokenName :: !TokenName
} deriving Show
{-# INLINABLE mkValidator #-}
mkValidator ::LockFundsDatum -> () -> ScriptContext -> Bool
mkValidator dat _ ctx = validate
where
info :: TxInfo
info = scriptContextTxInfo ctx
lockedValue :: Value
lockedValue = valuePaidTo info (beneficiary dat)
valueOutInteger :: Value -> Integer
valueOutInteger v = valueOf v (lockedTokensID dat) (lockedTokenName dat)
findTxFromThisSc :: Maybe TxOut
findTxFromThisSc = case findOwnInput ctx of
Just txInInfo -> Just (txInInfoResolved txInInfo)
Nothing -> Nothing
lockedValue' :: Maybe Value
lockedValue' = case findTxFromThisSc of
Just txo -> Just $ txOutValue txo
Nothing -> Nothing
test0 :: Bool
test0 = case lockedValue' of
Just v -> valueOutInteger v == valueOutInteger lockedValue
Nothing -> False
test1 :: Bool
test1 = case lockedValue' of
Just v -> traceIfTrue "value of test1 is 10 true" $ valueOutInteger v == 10
Nothing -> False
test2 :: Bool
test2 = traceIfFalse "value of test2 is 10 is false" $ valueOutInteger lockedValue == 10
test3 :: Bool
test3 = case lockedValue' of
Just v -> traceIfFalse "values are not equal" $ v == lockedValue
Nothing -> False
validate :: Bool
validate = traceIfFalse "Final test failed" test0 && test1 && test2 && test3
In case when there are 10 of my custom token locked, test0, test1 and test2 passes but SmartContract crashes on test3
test3
. @kinofdev I'm not using any off-chain code, just plain cardano-cli transactions which work except withtest3
case which I just added