hi I am getting this error while trying to unlock tokens from my treasury contract it is already topp up with tokens when trying to unlock with the access token doesn't know the exact reason behind this pls help me out


{-# LANGUAGE DeriveAnyClass        #-}
{-# LANGUAGE DeriveGeneric         #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MultiParamTypeClasses      #-}
{-# LANGUAGE OverloadedStrings          #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE DataKinds #-}
module Stake.StackingTreasury where

import              Ledger              hiding (singleton)
import qualified Ledger.Typed.Scripts as Scripts
import              Ledger.Value        as Value
import              Ledger.Ada
import qualified    PlutusTx
import              PlutusTx.Prelude    hiding (Semigroup (..), unless)

import              Stake.StackingTypes

{-# INLINEABLE mkValidator #-}
mkValidator :: TreasuryParam -> WithdrawalDatum -> StackingDetails -> ScriptContext -> Bool
mkValidator tp dat b ctx =    traceIfFalse "Only Issuer can change Treasury"              signedByIssuer ||
                              traceIfFalse "Access token missing from input"              inputHasAuthToken &&
                              traceIfFalse "Access token missing from contract output"    contractOutputHasAuthToken &&
                              traceIfFalse "Output Value must match StackingDetails"      checkValueToStackingContract &&
                              traceIfFalse "Treasury must keep remaining tokens"          treasuryGetsTokensBack &&
                              traceIfFalse "redeemer is not datum"                        checkReIsOutDat

    info :: TxInfo
    info = scriptContextTxInfo ctx

    signedByIssuer :: Bool
    signedByIssuer = txSignedBy info $ tTreasuryIssuerPkh tp

    -- Create a list of all CurrencySymbol in tx input
    inVals :: [CurrencySymbol]
    inVals = symbols $ valueSpent info

    -- Check that list of CurrencySymbols includes Auth CurrencySymbol
    inputHasAuthToken :: Bool
    inputHasAuthToken = tAccessTokenPolicyId tp `elem` inVals

    -- The Value to be included in Stacking Contract UTXO
    toStackingContract :: Value
    toStackingContract = valueLockedBy info (bountyContractHash tp)

    -- Check that the Auth Token is sent to Bounty Contract UTXO
    contractOutputHasAuthToken :: Bool
    contractOutputHasAuthToken = tAccessTokenPolicyId tp `elem` symbols toStackingContract

    -- Check that the Value sent to Contract UTXO matches what is specified in the Redeemer
    -- Note: For now, we can just remember to match Treasury Redeemer to Bounty Datum
    -- when we build transactions
    checkValueToStackingContract :: Bool
    checkValueToStackingContract =  valueOf toStackingContract (tBountyTokenPolicyId tp) (tBountyTokenName tp) >= tokenAmount b

    -- The UTXO input from Treasury
    ownInput :: TxOut
    ownInput = case findOwnInput ctx of
        Nothing -> traceError "treasury input missing"
        Just i  -> txInInfoResolved i

    -- The UTXO output back to Treasury
    ownOutput :: TxOut
    ownOutput = case getContinuingOutputs ctx of
        [o] -> o -- There must be exactly ONE output UTXO
        _   -> traceError "expected exactly one treasury output"

    -- Values of each
    treasuryInputValue :: Value
    treasuryInputValue = txOutValue ownInput

    treasuryOutputValue :: Value
    treasuryOutputValue = txOutValue ownOutput

    -- Compare Values from and to Treasury to make sure that Treasury gets the right value back.

    treasuryGetsTokensBack :: Bool
    treasuryGetsTokensBack = valueOf treasuryInputValue (tBountyTokenPolicyId tp) (tBountyTokenName tp) - valueOf treasuryOutputValue (tBountyTokenPolicyId tp) (tBountyTokenName tp) <= valueOf toStackingContract (tBountyTokenPolicyId tp) (tBountyTokenName tp)

    getStackingDatum :: Maybe StackingDatum
    getStackingDatum = let os = [ o | o <- txInfoOutputs info, txOutValue o == toStackingContract ] in
                  case os of
                    [o] -> stackingDatum o (`findDatum` info)
                    _   -> Nothing

    checkReIsOutDat :: Bool
    checkReIsOutDat = case getStackingDatum of
      Nothing -> False
      Just ns -> bedIssuerPkh   ns == issuerPkh b &&
                 bedContributorPkh ns == contributorPkh b &&
                 bedTokenAmount ns == tokenAmount b &&
                 bedExpirationTime ns == expirationTime b

-- typedValidator :: TreasuryParam -> TypedValidator TreasuryTypes
-- typedValidator tp =
--   mkTypedValidator @TreasuryTypes
--     $$(PlutusTx.compile [||mkValidator||]) `PlutusTx.applyCode` PlutusTx.liftCode tp
--     $$(PlutusTx.compile [||wrap||])
--   where
--     wrap = wrapValidator @WithdrawalDatum @StackingDetails

-- validator :: TreasuryParam -> Validator
-- validator = validatorScript . typedValidator

typedValidator :: TreasuryParam -> Scripts.TypedValidator TreasuryTypes
typedValidator tp = Scripts.mkTypedValidator @TreasuryTypes
    ($$(PlutusTx.compile [|| mkValidator ||])
        `PlutusTx.applyCode` PlutusTx.liftCode tp)
    $$(PlutusTx.compile [|| wrap ||])
    wrap = Scripts.wrapValidator @WithdrawalDatum @StackingDetails

validator :: TreasuryParam -> Validator
validator = Scripts.validatorScript . typedValidator

utxo at treasury address with datum hash of 123

cardano-cli query utxo --address addr_test1wpcsng9wvph3yn6felqewnq9wwcvuwpwdumrax2dset0vecwhasah --testnet-magic 1


                     TxHash                                 TxIx        Amount
0e4f0c3c372bb3c3d044f4ff72f200ad962f0f51190794dc43ca8f119b0faec2     1        2000000 lovelace + 99999999 d7d0b7e1195d3c51fefcf4e40146de39fe11162dcc56427f9e9db196.48616c + TxOutDatumHash ScriptDataInBabbageEra "7cfec515f56d4413375aa9775f5de15ee60180861e9eaa954bcf9d015054857c"

getting this error while trying to unlock funds from treasury conttract to stacking contract

Command failed: transaction build  Error: The following scripts have execution failures:
the script for transaction input 0 (in the order of the TxIds) failed with: 
The Plutus script evaluation failed: An error has occurred:  User error:
The machine terminated because of an error, either from a built-in function or from an explicit use of 'error'.
Caused by: [ (builtin unConstrData) (con data #187b) ]
Script debugging logs: 

unlocking command


cardano-cli transaction build \
--babbage-era \
--tx-in $CONTRACT_TXIN \
--tx-in-script-file $TREASURY_PLUTUS_SCRIPT \
--tx-in-datum-value 123 \
--tx-in-redeemer-file $BOUNTY_DATUM \
--tx-in $TXIN1 \
--tx-in $TXIN2 \
--tx-in-collateral $COLLATERAL \
--tx-out-datum-embed-file $BOUNTY_DATUM \
--tx-out-datum-hash 7cfec515f56d4413375aa9775f5de15ee60180861e9eaa954bcf9d015054857c \
--change-address $CONTRIBUTOR \
--protocol-params-file protocol.json \
--testnet-magic 1 \
--out-file commitment-tx.draft

1 Answer 1


You need to provide datum and redeemer that match the types your validator is expecting. Those funds cannot be unlocked now because the datum hash is for a value of a different type.

You're using datum value 123, which is of type Integer but your validator expects WithdrawalDatum. You're passing datum.json for your redeemer, that must be using correct schema for type StackingDetails.

  • i used datum hash of 123 for locking funds should I try a different datum with unlocking Oct 26, 2022 at 4:38
  • is there no way to unlock a utxo that was instansiated with the wrong datum type? Nov 11, 2022 at 21:59
  • There's currently no way to unlock utxo with a hash for the wrong datum type, same goes for the absence of hash.
    – james
    Nov 12, 2022 at 9:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.