Skip to main content
added solution
Source Link
Will
  • 1.2k
  • 3
  • 16

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"

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"

added 14 characters in body
Source Link
gRebel
  • 1.8k
  • 1
  • 9
  • 36
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
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 :: 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
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
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 :: 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
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 :: 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
Source Link
Will
  • 1.2k
  • 3
  • 16

How to create Datum with ownPaymentPubKeyHash?

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?