0

1st way I tried to do it was to get validator address using this function:

{-# INLINABLE scriptAddress #-}
-- | The address that should be used by a transaction output locked by the given validator script.
scriptAddress :: Validator -> Address
scriptAddress validator = Address (ScriptCredential (validatorHash validator)) Nothing

For example:

-- | The validator script of the game.
gameValidator :: ValidatorScript
gameValidator =
    ValidatorScript ($$(Ledger.compileScript [|| validateGuess ||]))

gameAddress :: Address
gameAddress = Ledger.scriptAddress gameValidator

Then use this gameAddress variable as parameter in minting policy, which compiles and works fine.

But real contract address never matches the address parameter, script fails on cardano-cli submit:

txOutputs :: [TxOut]
txOutputs = txInfoOutputs info

ownOutput :: TxOut
ownOutput = case [o | o <- txOutputs, gameAddress == txOutAddress o] of
[o] -> o
_ -> error ()

We always get an error here (I am sure that there is an output to the same smart contract).

This gameAddress has no awareness of mainnet/testnet, maybe that's the reason why it does not match? Maybe there is a way to fix this?

Also, is there a way to simply hardcode smart contract address into Plutus code? Like we can do with PubKeyHash?:

hardcodedPubKeyHash :: PubKeyHash
hardcodedPubKeyHash = "f1befc070bbc16ea613cfc0f0a5c0f856063f1ecbe640556136568f8"

2 Answers 2

3

If it does not match, it means your off-chain code is using a different address than what you expect on-chain.

An address is comprised of two parts, the payment and the staking part. You seem to be calculating the address of the payment part being the ValidatorHash of your game script and the staking part to be Nothing.

Maybe your off-chain code is creating the address slightly differently?

There is a function scriptOutputsAt in V1/V2 plutus (https://github.com/input-output-hk/plutus/blob/5cc518f1202930ad52b8ba838af32af084c0e754/plutus-ledger-api/src/Plutus/V1/Ledger/Contexts.hs#L251-L258) which you could also use. It explicitly only looks at the payment part and ignores the staking part.

2
  • good point. managed to make it working using scriptOutputsAt function. Nothing else worked, even extracting ValidatorHash from each output and comparing it to ValidatorHash parameter from contract (gameValidatorHash = validatorHash $ Validator $ mkGameScript). Thanks!
    – serx
    Aug 2, 2022 at 7:36
  • If it worked, you can accept the answer (I guess there is a button for that). Aug 3, 2022 at 6:32
0

In Haskell "f1befc070bbc16ea613cfc0f0a5c0f856063f1ecbe640556136568f8" is a string (because its enclosed in double quotes), not a PubKeyHash.

I think all you need to add the constructor like this (it compiles, but not 100% sure it does the right thing):

hardcodedPubKeyHash :: PubKeyHash
hardcodedPubKeyHash = PubKeyHash "f1befc070bbc16ea613cfc0f0a5c0f856063f1ecbe640556136568f8"

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.