<p>According to <a href="https://playground.plutus.iohkdev.io/doc/haddock/plutus-ledger-api/html/Plutus-V1-Ledger-Value.html#t:Value" rel="nofollow noreferrer">Ledger.Value</a></p>
<p>Value is an instance of Eq class so you should just be free to compare Value data types for equality. It is not an instance of Ord class however and you might need to do a custom comparison for your data types if you want ordering.</p>

CC BY-SA 4.0
2022-01-31T15:28:24.127Z
In my case when I go:
```haskell
compareTwoValues :: Value -> Value -> Bool
compareTwoValues v1 v2 = v1 == v2
```
This just crashes
KugisMugis
CC BY-SA 4.0
2022-03-02T17:44:51.123Z
This will work for normal inbuilt types such as bools or numbers. For custom types (and types that don't have a comparison operator) you have to define the comparison function.
KryptoKing
CC BY-SA 4.0
2022-01-30T18:27:21.427Z
2022-01-30T18:27:21.427Z
d_fajardo
<h1>Question</h1>
<p>What is the correct way to compare two instances of <code>Value</code> data type?</p>
<h1>Context</h1>
<p>I would like to check if outgoing transaction identified by <code>PubKeyHash</code> has the same <code>Value</code> as <code>Value</code> which was locked into smartcontract but I keep getting weird errors like so: <code>Command failed: transaction submit  Error: Error while submitting tx: ShelleyTxValidationError ShelleyBasedEraAlonzo (ApplyTxError [UtxowFailure (WrappedShelleyEraFailure (UtxoFailure (UtxosFailure (ValidationTagMismatch (IsValid True) (FailedUnexpectedly [PlutusFailure &quot;\nThe 3 arg plutus script (PlutusScript PlutusV1 ScriptHash \&quot;d13196be073516394395be6399e6895957d1a16c960d215d8b1d5e9f\&quot;) fails...</code></p>
<p>It seems to me as if working with <code>Value</code> data type crashes smartcontract.</p>
<p>I have tried creating SC with functions like:</p>
<pre><code>data LockFundsDatum = LockFundsDatum
    { beneficiary :: !PubKeyHash
    } deriving Show

lockedValue :: Value
lockedValue = valueLockedBy info (ownHash ctx)

validate :: Bool
validate = elem lockedValue (pubKeyOutputsAt (beneficiary datum) info)
</code></pre>
<p>or</p>
<pre><code>findTxFromThisSc :: Maybe TxOut
findTxFromThisSc = case findOwnInput ctx of
  Just txInInfo -&gt; Just (txInInfoResolved txInInfo)
  Nothing       -&gt; Nothing

getValuePaidToPkh :: Value
getValuePaidToPkh = valuePaidTo info (beneficiary dat)
  
valueOutInLovelaces :: Value -&gt; Integer
valueOutInLovelaces v = valueOf v adaSymbol adaToken

validate :: Bool
validate = case findTxFromThisSc of
      Just txo -&gt; traceIfFalse &quot;Value paid to pkh owner isn't equal to 2000000&quot; (valueOutInLovelaces getValuePaidToPkh == 2000000)
      Nothing -&gt; traceIfFalse &quot;Tx from this sc was not found&quot; False
</code></pre>
<p>But contract fails everytime. I think it is because I'm trying to use default compare with <code>Value</code> while it is not allowed.</p>
<h1>Fullcode</h1>
<pre><code>data LockFundsDatum = LockFundsDatum
    { beneficiary     :: !PubKeyHash
    , lockedTokensID  :: !CurrencySymbol
    , lockedTokenName :: !TokenName
    } deriving Show

{-# INLINABLE mkValidator #-}
mkValidator ::LockFundsDatum -&gt; () -&gt; ScriptContext -&gt; Bool
mkValidator dat _ ctx = validate
  where
    info :: TxInfo
    info = scriptContextTxInfo ctx

    lockedValue :: Value
    lockedValue = valuePaidTo info (beneficiary dat)

    valueOutInteger :: Value -&gt; Integer
    valueOutInteger v = valueOf v (lockedTokensID dat) (lockedTokenName dat)

    findTxFromThisSc :: Maybe TxOut
    findTxFromThisSc = case findOwnInput ctx of
      Just txInInfo -&gt; Just (txInInfoResolved txInInfo)
      Nothing       -&gt; Nothing

    lockedValue' :: Maybe Value
    lockedValue' = case findTxFromThisSc of
      Just txo -&gt; Just $ txOutValue txo
      Nothing  -&gt; Nothing

    test0 :: Bool
    test0 = case lockedValue' of
      Just v  -&gt; valueOutInteger v == valueOutInteger lockedValue
      Nothing -&gt; False

    test1 :: Bool
    test1 = case lockedValue' of
      Just v -&gt; traceIfTrue &quot;value of test1 is 10 true&quot; $ valueOutInteger v == 10
      Nothing -&gt; False

    test2 :: Bool
    test2 = traceIfFalse &quot;value of test2 is 10 is false&quot; $ valueOutInteger lockedValue == 10

    test3 :: Bool
    test3 = case lockedValue' of
      Just v -&gt; traceIfFalse &quot;values are not equal&quot; $ v == lockedValue
      Nothing -&gt; False

    validate :: Bool
    validate = traceIfFalse &quot;Final test failed&quot; test0 &amp;&amp; test1 &amp;&amp; test2 &amp;&amp; test3
</code></pre>
<p>In case when there are 10 of my custom token locked, test0, test1 and test2 passes but SmartContract crashes on test3</p>

CC BY-SA 4.0
2022-01-28T13:56:28.453Z
Can you paste the whole validator, i.e. the function that takes 3 arguments and returns a Bool.
Sjoerd Visscher
CC BY-SA 4.0
2022-01-30T13:17:11.170Z
Can you show your offline code? Concretely, the give contract.
kindofdev
CC BY-SA 4.0
2022-01-31T15:37:06.437Z
@SjoerdVisscher Added full code which compiles and works fine without `test3`. @kinofdev I'm not using any off-chain code, just plain cardano-cli transactions which work except with `test3` case which I just added
KugisMugis
CC BY-SA 4.0
2022-02-09T16:59:31.243Z
Are you using == from PlutusTx.Prelude or Prelude (Haskell) ?
kindofdev
CC BY-SA 4.0
2022-02-10T08:32:20.573Z
Good question. I don't know. How could I check?
KugisMugis
CC BY-SA 4.0
2022-02-13T16:39:23.797Z
It depends on the imports. For instance here,
import PlutusTx.Prelude (==)
import qualified Prelude as Haskell , 
you do Haskell equals with "1 Haskell.== 1" and "1 == 1" for Plutus equals.
(I'm a bit late, sorry. Next time mention me with @kindofdev in the comment)
kindofdev
<plutus><plutus-pioneer-program><smart-contract><haskell><on-chain>
What is the correct way to compare two instances of Value data type?
# What is the correct way to compare two instances of Value data type?

(Asked by: username_0 on 2022-01-28)

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

**Tags:** plutus, plutus-pioneer-program, smart-contract, haskell, on-chain
> **Comments:**
> **username_1**: Can you paste the whole validator, i.e. the function that takes 3 arguments and returns a Bool.  
> **username_2**: Can you show your offline code? Concretely, the give contract.  
> **username_0**: @SjoerdVisscher Added full code which compiles and works fine without `test3`. @kinofdev I'm not using any off-chain code, just plain cardano-cli transactions which work except with `test3` case which I just added  
> **username_2**: Are you using == from PlutusTx.Prelude or Prelude (Haskell) ?  
> **username_0**: Good question. I don't know. How could I check?  
> **username_2**: It depends on the imports. For instance here, import PlutusTx.Prelude (==) import qualified Prelude as Haskell ,  you do Haskell equals with "1 Haskell.== 1" and "1 == 1" for Plutus equals. (I'm a bit late, sorry. Next time mention me with @kindofdev in the comment)  

---

## 1 answers

### Answer by username_3 on 2022-01-30. Score: 0

According to [Ledger.Value](https://playground.plutus.iohkdev.io/doc/haddock/plutus-ledger-api/html/Plutus-V1-Ledger-Value.html#t:Value)

Value is an instance of Eq class so you should just be free to compare Value data types for equality. It is not an instance of Ord class however and you might need to do a custom comparison for your data types if you want ordering.

> **Comments:**
> **username_0**: In my case when I go: ```haskell compareTwoValues :: Value -> Value -> Bool compareTwoValues v1 v2 = v1 == v2 ``` This just crashes  
> **username_4**: This will work for normal inbuilt types such as bools or numbers. For custom types (and types that don't have a comparison operator) you have to define the comparison function.  

---

