<p>You are using the operator <code>&lt;-</code> to bind the result to <code>pkh</code>. That means that <code>pkh</code> is of type <code>PaymentPubKeyHash</code>. If the equality fails then because of another reason. If <code>pkh</code> wasn’t of the right type you would get a compilation error.</p>
<p>Maybe the way you are retrieving the datum is not correct. I would have written the following function assuming that your datum is of type <code>Stake</code>:</p>
<pre><code> stake :: ChainIndexTxOut -&gt; Maybe Stake
 stake (ScriptChainIndexTxOut _ _ (Right dd) _) = do
     Datum d &lt;- Just dd
     PlutusTx.fromBuiltinData d
 stake _ = Nothing
</code></pre>

CC BY-SA 4.0
2022-01-30T21:07:38.587Z
Thanks, that makes sense, but what else makes it fail to retrieve the funds?
I've have tested multiple things, like just returning True for the isSuitable function, which works as expected for retrieving any funds from the contract address.
So the validator works and it must be part of the isSuitable function
Will
CC BY-SA 4.0
2022-01-30T21:57:08.713Z
Maybe it is the way you retrieve the datum. I have edited my answer to show how I would have done it.
Jey
CC BY-SA 4.0
2022-01-31T15:22:03.103Z
Thanks @Jey I resolved the issue - you were right, the problem did originate from unwrapping the datum incorrectly.
Will
CC BY-SA 4.0
2022-01-31T17:55:15.613Z
Cool, I'm happy that my answer was useful.
Jey
CC BY-SA 4.0
2022-02-04T16:12:49.390Z
If my answer is correct you can accept it as the solution ; )
Jey
CC BY-SA 4.0
2022-01-30T20:25:14.027Z
2022-02-09T21:24:31.400Z
2022-02-09T21:24:31.400Z
Jey
<p>I have defined two endpoints.
One for creating a UTxO at the script address with a Datum that contains the wallet's own PaymentPubKeyHash.
And a second endpoint that spends such UTxOs from the script address.
The validator only checks for equality between the two PaymentPubKeyHashes.</p>
<p>First endpoint:</p>
<pre><code>one :: AsContractError e =&gt; Params -&gt; Contract w s e ()
one Params{..} = do
    pkh &lt;- ownPaymentPubKeyHash
    let dat = Stake PPDatum { owner = pkh }
        tx  = Constraints.mustPayToTheScript dat $ Ada.lovelaceValueOf amount
    ledgerTx &lt;- submitTxConstraints validatorInstance tx
    void $ awaitTxConfirmed $ getCardanoTxId ledgerTx
</code></pre>
<p>Second endpoint:</p>
<pre><code>second :: forall w s e. AsContractError e =&gt; Contract w s e ()
second = do 
    pkh   &lt;- ownPaymentPubKeyHash
    utxos &lt;- Map.filter (isSuitable pkh) &lt;$&gt; utxosAt validatorAddress
    ...
    where
        isSuitable :: PaymentPubKeyHash -&gt; ChainIndexTxOut -&gt; Bool
        isSuitable pkh o = case _ciTxOutDatum o of
            Left _          -&gt; False
            Right (Datum e) -&gt; case PlutusTx.fromBuiltinData e of
                Nothing -&gt; False
                Just d  -&gt; owner d == pkh
</code></pre>
<p>But the equality fails between the PaymentPubKeyHashes.</p>
<p>After testing around I recognized that the type of <em>ownPaymentPubKeyHash</em> does not just return a PaymentPubKeyHash but a <em>Contract w s e PaymentPubKeyHash</em>.</p>
<p>So how can I create the datum so that the PaymentPubKeyHashes match?</p>
<p><strong>UPDATE</strong></p>
<p>I was able to resolve my issue. It has nothing to do with the usage of <em>ownPaymentPubKeyHash</em>. As already correctly stated by others in this thread binding with the help of <code>&lt;-</code> <em>ownPaymentPubKeyHash</em> returns the type <em>PaymentPubKeyHash</em>.</p>
<p>The problem originated from unwrapping the datum incorrectly. And this was caused due to allowing two different types of datum at the script address using the pipe operator. Therefore, I needed to unwrap the datum twice.</p>
<p>My solution looks something like this now:</p>
<pre><code>data ParentDatum = One ADatum | Two BDatum

-- Helper function
getParentDatum :: ChainIndexTxOut -&gt; ParentDatum
getLotteryDatum o = case _ciTxOutDatum o of
    Left _ -&gt; traceError &quot;unexpected datum&quot;
    Right (Datum d) -&gt; do
        let parsedDatum = PlutusTx.fromBuiltinData d :: Maybe ParentDatum
        case parsedDatum of
            Just s -&gt; s
            _ -&gt; traceError &quot;Unknown datum type&quot;



-- inside the off-chain endpoint code
-- {...} 
    where
        isSuitable :: PaymentPubKeyHash -&gt; ChainIndexTxOut -&gt; Bool
        isSuitable pkh o = case getParentDatum o of
            One ADatum{..} -&gt; owner == pkh
            Two BDatum{..} -&gt; owner == pkh
            _              -&gt; traceError &quot;Unhandled datum type&quot;

</code></pre>

<plutus><plutus-pioneer-program><datum>
How to create Datum with ownPaymentPubKeyHash?
# How to create Datum with ownPaymentPubKeyHash?

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

I have defined two endpoints.
One for creating a UTxO at the script address with a Datum that contains the wallet's own PaymentPubKeyHash.
And a second endpoint that spends such UTxOs from the script address.
The validator only checks for equality between the two PaymentPubKeyHashes.
First endpoint:
one :: AsContractError e => Params -> Contract w s e ()
one Params{..} = do
    pkh <- ownPaymentPubKeyHash
    let dat = Stake PPDatum { owner = pkh }
        tx  = Constraints.mustPayToTheScript dat $ Ada.lovelaceValueOf amount
    ledgerTx <- submitTxConstraints validatorInstance tx
    void $ awaitTxConfirmed $ getCardanoTxId ledgerTx

Second endpoint:
second :: forall w s e. AsContractError e => Contract w s e ()
second = do 
    pkh   <- ownPaymentPubKeyHash
    utxos <- Map.filter (isSuitable pkh) <$> utxosAt validatorAddress
    ...
    where
        isSuitable :: PaymentPubKeyHash -> ChainIndexTxOut -> Bool
        isSuitable pkh o = case _ciTxOutDatum o of
            Left _          -> False
            Right (Datum e) -> case PlutusTx.fromBuiltinData e of
                Nothing -> False
                Just d  -> owner d == pkh

But the equality fails between the PaymentPubKeyHashes.
After testing around I recognized that the type of ownPaymentPubKeyHash does not just return a PaymentPubKeyHash but a Contract w s e PaymentPubKeyHash.
So how can I create the datum so that the PaymentPubKeyHashes match?
UPDATE
I was able to resolve my issue. It has nothing to do with the usage of ownPaymentPubKeyHash. As already correctly stated by others in this thread binding with the help of <- ownPaymentPubKeyHash returns the type PaymentPubKeyHash.
The problem originated from unwrapping the datum incorrectly. And this was caused due to allowing two different types of datum at the script address using the pipe operator. Therefore, I needed to unwrap the datum twice.
My solution looks something like this now:
data ParentDatum = One ADatum | Two BDatum

-- Helper function
getParentDatum :: ChainIndexTxOut -> ParentDatum
getLotteryDatum o = case _ciTxOutDatum o of
    Left _ -> traceError "unexpected datum"
    Right (Datum d) -> do
        let parsedDatum = PlutusTx.fromBuiltinData d :: Maybe ParentDatum
        case parsedDatum of
            Just s -> s
            _ -> traceError "Unknown datum type"



-- inside the off-chain endpoint code
-- {...} 
    where
        isSuitable :: PaymentPubKeyHash -> ChainIndexTxOut -> Bool
        isSuitable pkh o = case getParentDatum o of
            One ADatum{..} -> owner == pkh
            Two BDatum{..} -> owner == pkh
            _              -> traceError "Unhandled datum type"

**Tags:** plutus, plutus-pioneer-program, datum

---

## 1 answers

### Answer by username_1 on 2022-01-30. Score: 3 | Accepted answer

You are using the operator <- to bind the result to pkh. That means that pkh is of type PaymentPubKeyHash. If the equality fails then because of another reason. If pkh wasn’t of the right type you would get a compilation error.
Maybe the way you are retrieving the datum is not correct. I would have written the following function assuming that your datum is of type Stake:
 stake :: ChainIndexTxOut -> Maybe Stake
 stake (ScriptChainIndexTxOut _ _ (Right dd) _) = do
     Datum d <- Just dd
     PlutusTx.fromBuiltinData d
 stake _ = Nothing

> **Comments:**
> **username_0**: Thanks, that makes sense, but what else makes it fail to retrieve the funds? I've have tested multiple things, like just returning True for the isSuitable function, which works as expected for retrieving any funds from the contract address. So the validator works and it must be part of the isSuitable function  
> **username_1**: Maybe it is the way you retrieve the datum. I have edited my answer to show how I would have done it.  
> **username_0**: Thanks @Jey I resolved the issue - you were right, the problem did originate from unwrapping the datum incorrectly.  
> **username_1**: Cool, I'm happy that my answer was useful.  
> **username_1**: If my answer is correct you can accept it as the solution ; )  

---

