text:
recursive mustPayToTheScript loop?
I want to make a recursive loop on endpoint call so that it calls mustPayToTheScript 1000 times with a decreasing datum so that it amounts to 1000 utxos siting at the same script address is this possible with plutus considering that its built on a functional language?
import           Control.Monad          hiding (fmap)
import           Data.Aeson             (ToJSON, FromJSON)
import           Data.Text              (Text)
import           Data.Void              (Void)
import           GHC.Generics           (Generic)
import           Plutus.Contract
import           Plutus.Contract        as Contract
import           Ledger.Address         as Add
import           Plutus.Trace.Emulator  as Emulator
import qualified PlutusTx
import           PlutusTx.Prelude       hiding (Semigroup(..), unless)
import           Ledger                 hiding (mint, singleton)
import           Ledger.Constraints     as Constraints
import qualified Ledger.Typed.Scripts   as Scripts
import           Ledger.Value           as Value
import           Playground.Contract    (printJson, printSchemas, ensureKnownCurrencies, stage, ToSchema)
import           Playground.TH          (mkKnownCurrencies, mkSchemaDefinitions)
import           Playground.Types       (KnownCurrency (..))
import           Prelude                (IO, Show (..), String)
import           Text.Printf            (printf)
import           Wallet.Emulator.Wallet
import           PlutusTx.Prelude
import           Wallet.Effects         as Effects
import qualified PlutusTx.Builtins      as Builtins
import           Plutus.V1.Ledger.Ada as Ada
import           Ledger.Tx              (scriptTxOut, ChainIndexTxOut)
import           Plutus.ChainIndex.Tx
import           Ledger.Blockchain
import           Playground.Contract
import           Prelude              ((/), Float, toInteger, floor)
import           Cardano.Api hiding (Value, TxOut,Address)
import           Cardano.Api.Shelley hiding (Value, TxOut, Address)
import           Codec.Serialise hiding (encode)

minADA :: Value
minADA = Ada.lovelaceValueOf 2000000

price :: Value
price = Ada.lovelaceValueOf 10000000

data ContractInfo = ContractInfo
    { policyID :: !CurrencySymbol
    , walletOwner :: !PubKeyHash
    , nameOfToken :: !TokenName
    } deriving (Generic, ToJSON, FromJSON)

contractInfo = ContractInfo
    { policyID = "8b0dbdd6504ff8f129400ab3b21f12a52ffb09f0b3cff594cb5bb868"
    , walletOwner = "a2c20c77887ace1cd986193e4e75babd8993cfd56995cd5cfce609c2"
    , nameOfToken = "reward"
    }

--purchase portion of the contract
data LootBoxData
instance Scripts.ValidatorTypes LootBoxData where
    type instance RedeemerType LootBoxData = ()
    type instance DatumType LootBoxData = Integer

--Checks the validatorHash to make sure the LootBox has tokens to host the transaction
--If never changed by the end of the project use the builtins script validator
{-# INLINABLE mkValidator #-}
mkValidator :: Integer -> () -> ScriptContext -> Bool
mkValidator _ _ ctx = True

lootBox :: Scripts.TypedValidator LootBoxData
lootBox = Scripts.mkTypedValidator @LootBoxData
    $$(PlutusTx.compile [|| mkValidator ||])
    $$(PlutusTx.compile [|| wrap ||]) where
        wrap = Scripts.wrapValidator @Integer

valHash :: Ledger.ValidatorHash
valHash = Scripts.validatorHash lootBox

validate :: Validator
validate = Scripts.validatorScript lootBox

valAddress :: Address
valAddress = Scripts.validatorAddress lootBox

--Start of minting portion of the smart contract

{-# INLINABLE mkPolicy #-}
mkPolicy :: PubKeyHash -> () -> ScriptContext -> Bool
mkPolicy pkh () ctx = txSignedBy (scriptContextTxInfo ctx) pkh

policy :: PubKeyHash -> Scripts.MintingPolicy
policy pkh = mkMintingPolicyScript $
    $$(PlutusTx.compile [|| Scripts.wrapMintingPolicy . mkPolicy||])
    `PlutusTx.applyCode`
    (PlutusTx.liftCode pkh)

--dont need
curSymbol :: PubKeyHash -> CurrencySymbol
curSymbol = scriptCurrencySymbol . policy

data MintParams = MintParams
    { mpTokenName :: !TokenName
    , mpAmount    :: !Integer
    } deriving (Generic, ToJSON, FromJSON, ToSchema)

PlutusTx.makeLift ''MintParams

--Start of endpoints
type SignedSchema =
    Endpoint "mint" MintParams
     .\/ Endpoint "lock" MintParams
     .\/ Endpoint "purchase" ()

mint :: AsContractError e => MintParams -> Contract w s e ()
mint mp = do
    ppkh <- Contract.ownPaymentPubKeyHash
    let pkh     = unPaymentPubKeyHash ppkh
        val     = Value.singleton (curSymbol pkh) (mpTokenName mp) (mpAmount mp)
        lookups = Constraints.mintingPolicy $ policy (pkh)
        tx      = Constraints.mustMintValue val
    ledgerTx <- submitTxConstraintsWith @Void lookups tx
    void $ awaitTxConfirmed $ getCardanoTxId ledgerTx
    logInfo @String $ printf "forged %s" (show val)

lock :: MintParams -> Contract w SignedSchema Text ()
lock mp =  do
-- make a recusive function that allows for the creation of a 1000 utxos of diffrent datums from a wallet (cheap if implemented correctly)

    let v   = Value.singleton (policyID contractInfo) (nameOfToken contractInfo) (mpAmount mp) <> minADA
        txc =   foldl
                (\acc i -> acc <> (Constraints.mustPayToTheScript (i) $ v)
                (TxConstraints [] [] []))
                [1..1000]

    ledgerTx <- submitTx txc
    void $ awaitTxConfirmed $ getCardanoTxId ledgerTx

purchase :: () -> Contract w SignedSchema Text ()
purchase _ =  do
    utxos <- fundsAtAddressGeq valAddress (Ada.lovelaceValueOf 1)

    let redeemer = ()
        ppkh     = walletOwner contractInfo
        tx       = mustPayToPubKey (Add.PaymentPubKeyHash ppkh) price <> collectFromScript utxos redeemer

    void (submitTxConstraintsSpending lootBox utxos tx)

endpoints :: Contract () SignedSchema Text ()
endpoints = awaitPromise (mint' `select` lock' `select` purchase') >> endpoints
  where
    mint' = endpoint @"mint" mint
    lock' = endpoint @"lock" lock
    purchase' = endpoint @"purchase" purchase

mkSchemaDefinitions ''SignedSchema

mkKnownCurrencies []

Do you mean something like this:
v = lovelaceValueOf 2_000_000
txc = foldl
      (\acc i -> acc <> (Constraints.mustPayToTheScript (YourDatum i) $ v))
      (TxConstraints [] [] [])
      [1..1000]

Yes. also would that be considered recursion?

No, it is not using a recursive function. It just uses a fold -a very useful pattern.

ok I look into fold some more, thank you

So I tried out your method but it seems like the compliler dosent like the treatment of the TXContraints any ideas?

You probably need to correctly declare the types. If you add your code in the question I can edit my answer.

Ok I added it there error is in the lock endpoint function

There was a missing parenthesis in my code. I added it. You put it on the wrong line. Also there are many things missing in your lock-function. Start by making your code work for one UTxO and then use foldl to do it for 1000.

Haskell allows you to loop (recursively). And since all off-chain codes (mustPayTo... included) are written in Haskell, it is be possible.


text:
What is the correct way to compare DatumHash?
What is the correct way to compare DatumHash?
I imported the Eq function from PlutusTx
import PlutusTx.Prelude (Eq((==)))
...

checkDatumHash :: TxOut -> Bool
    checkDatumHash txOut = traceIfFalse "Incorrect datum" (own_dh == Just new_dh)
        where

            --d = Datum (PlutusTx.toBuiltinData nfts)
            --dh = fromJust (findDatumHash (Datum (PlutusTx.toBuiltinData nfts)) info)
            --new_d = findDatum dh info
            new_dt = nfts {p = r_prct, l = mk_prct}
            new_dh = datumHash (Datum (PlutusTx.toBuiltinData new_dt))
            own_dh =   txOutDatumHash txOut

It's fine to compare 2 Datum datas or PubKeyHash but I got unsupported feature error when compare 2 DatumHash data. (For above example, it's fine to compare: new_d == Just d)
GHC Core to PLC plugin: E042:Error: Unsupported feature: Kind: forall k. k -> *
Context: Compiling kind: forall k. k -> *
...

The error message may not show the direct issue, it points to my validator
typedBuyValidator :: [PubKeyHash] -> Scripts.TypedValidator Sale
typedBuyValidator [pkh1, pkh2] = Scripts.mkTypedValidator @Sale
    ($$(PlutusTx.compile [|| mkBuyValidator ||]) `PlutusTx.applyCode` PlutusTx.liftCode [pkh1, pkh2])
    $$(PlutusTx.compile [|| wrap ||])
  where
    wrap = Scripts.wrapValidator @DatumInfo @RedeemInfo

Why both DatumHash and PubKeyHash look very similar where both are wrapper of  PlutusTx.BuiltinByteString but issue happened only in DatumHash?
Another strange thing to me that I can compile the code using function findDatum from Ledger successfully where this also makes comparison of DatumHash inside.
findDatum :: DatumHash -> TxInfo -> Maybe Datum
findDatum dsh TxInfo{txInfoData} = snd <$> find f txInfoData
    where
        f (dsh', _) = dsh' == dsh

UPDATE:
I tested the comparision DatumHash by getting another own_dh1 to compare with own_dh and it compiled successfully:
checkDatumHash :: TxOut -> Bool
    checkDatumHash txOut = traceIfFalse "Incorrect datum" (own_dh == own_dh1)
        where

            --d = Datum (PlutusTx.toBuiltinData nfts)
            --dh = fromJust (findDatumHash (Datum (PlutusTx.toBuiltinData nfts)) info)
            --new_d = findDatum dh info
            new_dt = nfts {p = r_prct, l = mk_prct}
            new_dh = datumHash (Datum (PlutusTx.toBuiltinData new_dt))
            own_dh =   txOutDatumHash txOut
            own_dh1 =   txOutDatumHash txOut

Then I thought that maybe the problem may not relate to comparision but datumHash function which is hashing Datum to DatumHash was not allowed to run on Onchain code. Am I correct ?
new_dh = datumHash (Datum (PlutusTx.toBuiltinData new_dt))

Looked into plutus fw code, I found the function datumHash will eventually call to this function
-- NOT a builtin, only safe off-chain, hence the NOINLINE
{-# NOINLINE builtinDataToData #-}
-- | Convert a 'BuiltinData' into a 'PLC.Data'. Only works off-chain.
builtinDataToData :: BuiltinData -> PLC.Data
builtinDataToData (BuiltinData d) = d

I guess it's not possible to run datumHash in on-chain, this also caused my issue.

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
Cardano-node updated to 1.33.0 - gLiveView not connecting to node
I have updated my relay node to 1.33.0 and gLiveView will not run.  The node is up and running and I can see it working with simpleLiveView, but when i run gLiveView I get an error. "could not connect to running instance"
Node is running

simpleLiveView

Node version is 1.33.0

This is the error for gLiveView

Any ideas where I can start to troubleshoot the issue?
Thanks,

Have you ensured that all your path variables are set appropriately in your ~/.bashrc folder, and that gLiveView is updated to the latest version (v1.25.1)?

if i am right, that you use cntools, please read below...
take a backup of your files in the folder "scripts",
and download again the env and gLive files.
if you want download all your files, just to be updated.
cd tmp/
./prereqs.sh -f

but please, dont forget to take backup of your current files, so that you bring back the settings to env file and the rest you use.

Thank you for the reply, yes that is correct I use cntools. In my env file the only change I have made is to set the port CNODE_PORT=6000 like in the guild-operators common env  [link] (https://cardano-community.github.io/guild-operators/Scripts/env/) is there something else i shoud check in the env file?  Should I replace all the script files in the folder or just the gLive files?

it looks you run a relay, then is fine only the setting for the port. - when you ask me for all files or only gLive, i used to update all files once per month. it is good. but you dont have to. - it would be nice if you vote my answers if that helps you mate.

Yeah, it did not solve my issue.  I did the ./prereqs.sh update, but still cannot run gLiveView

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
How to calculate fees in Plutus
Let's say I have an Ledger.Constraints.UnbalancedTx with consumed regular UTxOs, script UTxOs and minting scripts, how can I calculate the fees of this transaction in Plutus ? This function would ideally also have the number of needed signatures as input argument.
My idea is to construct an UnbalancedTx that has all the UTxOs needed to cover fees and then balance it with the exact fee figure computed. I want to then export this transaction via the PAB and hand it over to Nami Wallet for signature.


text:
Will transactions created with a local cardano-node be faster if I add more relays to my node topology file?
I'm using a local cardano-node to do some transactions from time to time. Recently I noticed some error messages in the logs of the node. It seemed like the connection to the relays-new.cardano-mainnet.iohk.io relay had some problems.
While searching for ways to solve this, I realized that I can set up multiple relay nodes in my mainnet-topology.json file. Is this something one should do? Will it make the node more resilient and will it improve transaction speed?
Bonus question: Where can I find a list of relay nodes (including port and valency)?

If your connection(s) to the IOHK-hosted relays was in fact the problem, then yes, connecting to other SPO relay nodes should help alleviate the issue.
I couldn't find one single list containing pools' public facing relays, but if you search for a specific pools' metadata using any explorer like Cardanoscan, you can find their metadata URLs which contain their relays' info. I'd recommend having a good number of single pool operators as buddy relays. You can refer to the single pool alliance topology registry for a list of such pools
Alternatively, Guild Operators' topologyUpdater script allows SPOs to automatically push their relays' IPs and ports to one location where it also pulls from to update everybody. This greatly simplifies the process of finding peers, though it is heavily centralized and only intended as a stopgap until full p2p is released.

I already had a look at the topologyUpdater script before asking this question but it seems like the API has some sort of IP whitelisting when fetching the list of relays, therefore I wasn't able to use it. The single pool alliance topology registry seems like what I need, thanks!


text:
Where is Week04.Monad?
Doing Week 04 of cohort 3 Plutus Pioneers here.
In the repl inside the nix shell, inside ~/plutus/plutus-pioneer-program/code/week04
Watching PPP 030402 at 34:54 to about 39:59.
When I do

:l src/Week04/Either.hs

I get

Prelude Data.Char Text.Read Week04.Either> import Week04.Either
Prelude Data.Char Text.Read Week04.Either> :l src/Week04/Either.hs
: warning: [-Wmissing-home-modules]
These modules are needed for compilation but not listed in your .cabal file's other-modules:
Week04.Monad
Ok, two modules loaded.
Prelude Data.Char Text.Read Week04.Either>

Oddly, I can directly import Week04.Monad in the repl

Prelude Data.Char Text.Read Week04.Either> import Week04.Monad
Prelude Data.Char Text.Read Week04.Either Week04.Monad> :l src/Week04/Either.hs
: warning: [-Wmissing-home-modules]
These modules are needed for compilation but not listed in your .cabal file's other-modules:
Week04.Monad
Ok, two modules loaded.
Prelude Data.Char Text.Read Week04.Either Week04.Monad>

and Week04.Monad IS part of the plutus-pioneer-program-week04.cabal file

library
  hs-source-dirs:      src
  exposed-modules:     Week04.Contract
                     , Week04.Either
                     , Week04.Homework
                     , Week04.Maybe
                     , Week04.Monad
                     , Week04.Trace
                     , Week04.Writer
  other-modules:       Week04.Vesting
  build-depends:       aeson
                     , base ^>=4.14.1.0
                     , containers
                     , data-default
                     , freer-extras
                     , playground-common
                     , plutus-contract
                     , plutus-ledger
                     , plutus-ledger-api
                     , plutus-ledger-constraints
                     , plutus-tx-plugin
                     , plutus-tx
                     , text
  default-language:    Haskell2010

but it is listed under "exposed-modules" rather than "other-modules". If I manually edit to put it under other-modules (and remove it from exposed-modules, and various combinations), and even if I exit (:q) and re-enter the repl, the error persists, and I cannot replicate what is being demonstrated in the video.
Any guidance? Thanks.

Here: Prelude Data.Char Text.Read Week04.Either> import Week04.Either
You don't need neither "import Wee04.Either" nor ":l src/Week04/Either.hs" because it is already loaded. (See left side of ">" )

That doesn't seem to make any difference. If I leave the repl and re-enter, I can produce this:
Prelude Week04.Contract> :l src/Week04/Either.hs
: warning: [-Wmissing-home-modules]
These modules are needed for compilation but not listed in your .cabal file's other-modules:
Week04.Monad
Ok, two modules loaded.
Prelude Week04.Either>
And shouldn't cabal/nix/Haskell handle an attempted double import painlessly?

I see that "import Week04.Either" works, loading module Week04.Either. Why do you want do ":l src/Week04/Either.hs " ?

Just wanted to add that I also receive that error even when I add Week04.Monad to other-modules. While it is annoying that the warning appears, you can still follow along with what Lars does in the video

Yes, I see now that I can follow along even with the error, probably related to exiting and re-entering either the repl or my nix shell. Was getting errors with everything prior to that. As to adding "Week04.Either" vs ":l src/Week04/Either.hs" I think that has to do with my current directory, perhaps whether the module is compiled, and some ambiguity - do you (@kindofdev) mean "import ..." or ":l ..."?

I meant that using import Week04.Either works

You can find Week04.Monad here.


text:
What is the value of ADA locked in a Native token?
I was wondering, if ADA locked  in an native asset is equally valuable? For me it is like if somebody put a draw on a ticket but there are other implications:  it can give trouble when making transactions because it adds to the transactions size. Should we accept a payment of 500 ADA that have native assets be as valuable as one without Native Assets? Can we stake ADA along with native assets... or this locked value can not be staked?
EDIT: I mean min ADA needed for moving this ADA together with the native assets.
EDIT: For example you are asking for 500 ADA as payment for some work, but they send you 500 ADA with 200 NFT, if those NFT have not value in any marketplace, would this payment be equally valuable as a payment with only 500 ADA?

Are you referring to the minimum ADA value attached to each UTxO?

Yes I will update

ADA locked in an asset is equally valuable only insofar as you trust the underlying logic of the script address that keeps it locked. Assuming the smart contract is bulletproof, then yes - it is reasonable to say that a 500-ADA token is worth the same as 500 ADA.
Staking however is a bit more complicated. Currently, there is no way to stake anything other than raw ADA on L1. This does not mean that other tokens won't be stake-able in the future (see my answer here on the matter). Once new staking structures are set up on sidechains/hdyra heads, and eventually maybe even on L1, you'd be able to stake any token to any node willing to accept such a token as a form of stake.
On a different note, clever use of pointer addresses may make it possible to maintain staking rights over native-asset locked-values. For example, I could set up a script address that guards the 500 ADA with a pointer component that gives the receiver of the asset staking rights to the guarded ADA. Although, I'd imagine this could get cumbersome and difficult to trade.

What about if the locked asset has a undesirable IPFS hash... so every time you open your Wallet you see a disgusting image? like a ticket with a ugly message written in? also the Native Assets make cumbersome to make the transactions perse

Also every transaction that happens carring native assets is more vulnerable to get: outPut to Big error, as well as pay more fees, because the Tx Size is bigger. And makes harder to find any native asset needed in your Wallet, and if you have a big quantity of NFTs in a single UTXO, this UTXOs is harder to be used by the above remarks

Ada isn't locked in a native asset. The native asset requires an associated amount of ada held in a utxo at a minimum. In the case above of 500 Ada + 1 token, a transaction can be created with two outputs, one of 497 Ada and one of 2 ada with a fee of 1 Ada (high fee, using it for simplicity. In reality, it will be smaller). You can also combine assets from multiple utxos into a single one to have a smaller minutxo required to hold the assets to reclaim some of the Ada if someone sends you a token + 1.5 ada for exmaple.

" The native asset requires an associated amount of ADA held in a utxo at a minimum" that's what i mean with locked.


text:
Applycode to untyped validator, template Haskell
I am trying to learn the basics of the PlutusTx module. In this module is a function applyCode which maps the signatures CompiledCodeIn uni fun (a -> b) -> CompiledCodeIn uni fun a -> CompiledCodeIn uni fun b. In my understanding this function is there to splice in inputs. So given the following validator
{-# LANGUAGE DataKinds           #-}
{-# LANGUAGE FlexibleContexts    #-}
{-# LANGUAGE NoImplicitPrelude   #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell     #-}
{-# LANGUAGE TypeApplications    #-}
{-# LANGUAGE TypeFamilies        #-}
{-# LANGUAGE OverloadedStrings   #-}
{-# LANGUAGE TypeOperators       #-}

module Modules.Contract where

import           Control.Monad       hiding (fmap)
import           Data.Map            as Map
import           Data.Text           (Text)
import           Data.Void           (Void)
import           Plutus.Contract
import           PlutusTx            as PlutusTx
import           PlutusTx.Prelude    as P hiding (Semigroup(..), unless)
import           Ledger              hiding (singleton)
import           Ledger.Constraints  as Constraints
import qualified Ledger.Scripts      as Scripts
import           Ledger.Ada          as Ada
import           Playground.Contract (printJson, printSchemas, ensureKnownCurrencies, stage)
import           Playground.TH       (mkKnownCurrencies, mkSchemaDefinitions)
import           Playground.Types    (KnownCurrency (..))
import           Prelude             (IO, Semigroup (..), String)
import           Text.Printf         (printf)

{-# OPTIONS_GHC -fno-warn-unused-imports #-}
someList :: [Integer]
someList = [1,2,3]

someListBuiltin :: BuiltinData
someListBuiltin = PlutusTx.toBuiltinData someList

{-# INLINABLE mkValidator #-}
mkValidator :: BuiltinData -> BuiltinData -> BuiltinData -> BuiltinData -> ()
mkValidator someListBuiltin _ r _
        | (someListBuiltin P.!! 1) == r = ()
        | otherwise                     = traceError "wrong redeemer"

Notice that I use BuiltinData instead of a typed version and I import the Plutus.Prelude as P. This simple validator checks if the redeemer is the first element in the list (so if r = (I 1) it would validate. Now how do I splice this pre determined list in the validator via template haskell? My attempt by using applyCode in infix style
validator :: Validator
validator = mkValidatorScript ($$(PlutusTx.compile [|| mkValidator ||]) `PlutusTx.applyCode` PlutusTx.liftCode someListBuiltin)

For a typed validator I got this to work.

What's the error you get?

I managed to pin it down to the fact that the P.!! function is not applicable on BuiltinData. If one wants to script with BuiltinData, do you have to convert everything back to Data to use the Plutus.Prelude functions? I got the applyCode working now (it was a wrong module import).

Ah, it might be a better idea to use mkTypedValidatorScript which will do the conversions for you.

I agree, but everything should be possible in the non-typed version as well right? Lars said in his lecture that the non-typed validator where smaller in size since the conversion is skipped. So thats why I wanted to learn the non-typed style too.

In that case you'll have to pattern match on the Data constructors, there won't be functions like (!!) to help you.

But one can use (<$>) :: Functor f => (a -> b) -> f a -> f b to circumvent that right? its no problem that type signatures need checking more. Also I am not scared to use some monadic structures, better to learn real haskell by doing :)

I don't think so, not sure which Functor you're thinking of here.

I am not a haskell legend but from the type signature deduced that since Data is just some wrapper around Integer, list, Bytestring etc we should have such a function that tries to apply to the internal type. Thanks for the help Sjoerd!

That's sadly not how it works, but I like how you're thinking! If you pattern match on List xs, you can then do xs !! 0.


text:
How to create the policy.vkey and policy.skey with Cardanocli-js?
I am looking for a method to create the policy.vkey and policy.skey.
unfortunately my search has been unsuccessful so far.
I have searched the library https://github.com/Berry-Pool/cardanocli-js/blob/main/API.md but found nothing.
I want to create a NFT with the library "cardanocli-js".
Thanks for the help
want to create an NFT and I get the following error in my code

const mintScript = {
  "type": "all",
  "scripts": [
    {
      "type": "before",
      "slot": expireSlot
    },
    {
      "keyHash": cardanocliJs.addressKeyHash(wallet.name),
      "type": "sig",
    }
  ]
}

const policy = cardanocliJs.transactionPolicyid(mintScript);
const BERRYCOIN = policy + ".TestNFT";
const ASSET_NAME = 'Test-BildNFT';

console.log(policy);

const metadata = {
  "721": {
      [policy]: {
          [ASSET_NAME]: {
              "name": ASSET_NAME,
              "id": 1,
              "artist": 'Dave',
              "size": "big",
              "mediaType": "image/jpeg",
              "collection": "CollectionTest",
              "image": 'ipfs://QmYBfPDQ7reFcFvYESuipFL8R4FaqGZdMieCaUTHnZTB73',
              "description": 'Test Picture NFT',
          }
      }
  }
}

const tx = {
  txIn: wallet.balance().utxo,
  txOut: [
    {
      address: wallet.paymentAddr,
      value: { ...wallet.balance().value, [BERRYCOIN]: 1 },
    },
  ],
  mint: [
    { action: "mint", quantity: 1, asset: BERRYCOIN, script: mintScript },
  ],
  witnessCount: 2,
  metadata: metadata,
};

const raw = createTransaction(tx);
const signed = signTransaction(wallet, raw);
console.log(cardanocliJs.transactionView({ txFile: signed }));
const txHash = cardanocliJs.transactionSubmit(signed);
console.log(txHash);

const createTransaction = (tx) => {
  let raw = cardanocliJs.transactionBuildRaw(tx);
  let fee = cardanocliJs.transactionCalculateMinFee({
    ...tx,
    txBody: raw,
  });
  tx.txOut[0].value.lovelace -= fee;
  return cardanocliJs.transactionBuildRaw({ ...tx, fee });
};

const signTransaction = (wallet, tx, script) => {
  return cardanocliJs.transactionSign({
    signingKeys: [wallet.payment.skey, wallet.payment.skey],
    txBody: tx,
  });
};
Command failed: transaction submit  Error: Error while submitting tx: ShelleyTxValidationError ShelleyBasedEraAlonzo (ApplyTxError [UtxowFailure (WrappedShelleyEraFailure (ScriptWitnessNotValidatingUTXOW (fromList [ScriptHash "857ebbcadda9fd10568262fdaf64d20935681752968390cf9a830952"])))])
node:child_process:903
    throw err;
    ^

Error: Command failed: cardano-cli transaction submit --testnet-magic 1097911063 --tx-file ./tmp/tx_orkb4h9js.signed
Command failed: transaction submit  Error: Error while submitting tx: ShelleyTxValidationError ShelleyBasedEraAlonzo (ApplyTxError [UtxowFailure (WrappedShelleyEraFailure (ScriptWitnessNotValidatingUTXOW (fromList [ScriptHash "857ebbcadda9fd10568262fdaf64d20935681752968390cf9a830952"])))])

A policy key is just a payment key (or stake key, depending on where the policy is listed in the address). So in the example of using cardanocli-js, you would use the addressKeyGen method. https://github.com/Berry-Pool/cardanocli-js/blob/main/API.md#CardanocliJs+addressKeyGen


text:
What do unusual symbols "@" and ".\/" in off-chain code mean?
I was wondering about syntax I am not used to in the off-chain code.
What does @ mean in the following context?
logInfo @String $ printf "made a gift"
What does .\/ mean in the following context?
type GiftSchema = Endpoint "give" Integer .\/ Endpoint "grab" ()
I guess that it has to do to the multiple GHC extensions invoked in Plutus code but I do not have the time to understand each and everyone of them.

@String is from TypeApplications. logInfo has type logInfo :: forall a effs. Member (LogMsg a) effs => a -> Eff effs (), so logInfo @String fixes a to be String. (That this is needed here is because of another extension OverloadedStrings, so "made a gift" is not necessarily of type String)
.\/ is not from an extension, but an operator defined by the row-types library.


text:
npm start is failing
Had worked all last week.
This week after messing around to get cabal repl working, npm start has been abending.
Screen shot attached.
Tried as suggested "GC_DONT_GC=1 npm run start"      It didn't help.

Looks like some weird caching issue. Can you try it with a fresh checkout?

I'm game! If doesn't work I'll go back 2 zero, wipe out all my plutus directories & start fresh: Git clone, nix build, cabal setup etc. I'm beginner to developing off the mainframe. this is really linux, haskell, plutus, blockchain course rolled in one and I'm sticking against all odds.  I accept it'll be extremly difficult. Most here been on linux platform years. I have 2 pay dues like everyone. My goal:DONT quit. I let go that I'll keep current with course. I'll push forward as best I can. I already learned much about  blockchain linux haskell nix, etc. Sjoerd,Thank u million for response!


text:
Shared database between Daedalus and Cardano-node
I just started diving into the command line tools and as a first step I want to get a Cardano node running. My question is, whether it's a good idea to use the database from the Daedalus wallet (under $HOME/Library/Application Support/Daedalus Mainnet/chain on macOS) and point the cardano-node argument database-path there? Will there be any conflicts between the node instance and Daedalus, perhaps when running them at the same time?

I do something like this on Linux to conserve space. Only one node can share the chain state at the same time though. Further, if you switch back and forth between newer/older version of cardano-node, it will trigger ledger state rebuilds which take a while before the node is functioning. If your only goal is to be able to use the CLI, you can start Daedalus and set CARDANO_NODE_SOCKET_PATH to the path in Daedalus.

Thanks! Yes, I noticed the rebuild after launching Daedalus again, which is actually a dealbreaker then for me for this setup. In any case, your suggestion is perhaps the best way for now, thanks for this hint. Just a quick follow-up question: I am not sure where the socket is actually located, I can't find it either in Application Support or within the App package...

Ah, just found a post that it's supposed to be at $HOME/Library/Application Support/Daedalus Mainnet/cardano-node.socket


text:
Can anyone see whats wrong with my off-chain code
Im trying to create and send a utxo of tokens to a wallet through collectFromScript and I cant seem to get it to work. Can I get some help? I am trying to create a valid input for the collectFromScript function but I dont know how to map TxOutRef and ChainIndexTxOut so that it will produce (Map TxoutRef ChainIndexTxOut).
purchaseUtxo ::  ChainIndexTxOut
purchaseUtxo = case fromTxOut (scriptTxOut (Value.singleton (policyID contractInfo) (nameOfToken contractInfo) (1)) validate (Datum $ PlutusTx.toBuiltinData ()) )  of
    Nothing     ->  error ()
    Just x      ->  x

purchase :: AsContractError e => PurchaseParams -> Contract w s e ()
purchase p =  do
    utxos <- utxosAt valAddress
    utxoMap <- (map TxOutRef (purchaseUtxo))
    let redeemer = ()
        pkh = ownPubKey
        tx       = Constraints.mustPayToTheScript () price <> collectFromScript utxoMap

    void (submitTxConstraintsSpending lootBox utxos tx)

Compilation Error, Line 146, Column 17 (jump)

 error:
    • Couldn't match expected type ‘Contract
                                      w s e (Data.Map.Internal.Map TxOutRef ChainIndexTxOut)’
                  with actual type ‘[Integer] -> [TxOutRef]’
    • Probable cause: ‘map’ is applied to too few arguments
      In a stmt of a 'do' block: utxoMap <- (map (TxOutRef purchaseUtxo))
      In the expression:
        do utxos <- utxosAt valAddress
           utxoMap <- (map (TxOutRef purchaseUtxo))
           let redeemer = ()
               pkh = ownPubKey
               ....
           void (submitTxConstraintsSpending lootBox utxos tx)
      In an equation for ‘purchase’:
          purchase p
            = do utxos <- utxosAt valAddress
                 utxoMap <- (map (TxOutRef purchaseUtxo))
                 let redeemer = ...
                     ....
                 ....
    • Relevant bindings include
        purchase :: PurchaseParams -> Contract w s e ()
          (bound at /tmp/web-ghc-work-689a3b2c3d276385/Main.hs:144:1)
    |
146 |     utxoMap <- (map (TxOutRef purchaseUtxo))
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^

Compilation Error, Line 146, Column 31 (jump)

 error:
    • Couldn't match expected type ‘TxId’
                  with actual type ‘ChainIndexTxOut’
    • In the first argument of ‘TxOutRef’, namely ‘purchaseUtxo’
      In the first argument of ‘map’, namely ‘(TxOutRef purchaseUtxo)’
      In a stmt of a 'do' block: utxoMap <- (map (TxOutRef purchaseUtxo))
    |
146 |     utxoMap <- (map (TxOutRef purchaseUtxo))
    |

                ^^^^^^^^^^^^

It might be more valuable to the site if you pose your question in a way other people can find it.

I changed my explanation I how that it helps

    • Couldn't match expected type ‘Contract
                                      w s e (Data.Map.Internal.Map TxOutRef ChainIndexTxOut)’
                  with actual type ‘[Integer] -> [TxOutRef]’
    • Probable cause: ‘map’ is applied to too few arguments

This is saying that it expects a Contract monad but it's getting a function [Integer] -> [TxOutRef]. So, there are two problems:
You aren't passing map any [integer], so it's just an unresolved function, but, more importantly,map doesn't return a Contract monad, so <- doesn't make sense here. <- within a do block must be used on the same type of monad, which in this case is Contract.


text:
What is where executed and when?
To wrap my around what happens when I where, I tried to visualize it. In order to be able to show the interaction between two different systems generating transactions, I have a Generator A and Generator B.
In short:

some dev writes and compiles a script (smart contract)
that smart contract must be deployed, I suppose this is done by transacting it to the blockchain
if a Tx generator (someone/something making and submitting transactions) wants to make a transaction, it needs the script, so it has to fetch it from a location the dev has put that script. The script (smart contract) itself is not on the blockchain. The generator also may need a redeemer and some context. The Tx can be tested locally before sending it to the network.
if another Tx generator wants to use the same script, but one or more blocks later, it will need the datum (previous state of the script), which must be exposed by the previous generator somehow.

Inside the nodes:

Txs are received and batched. The 'winning' node may validate all the Txs, reject the invalid ones and add the valid ones to a new block. If that's done, the whole block is broadcasted (and each node checks the validity of the block).
validation of a Tx means that for each spending (E)UTxO the according address must 'approve' that transaction. The node validates the approvals by:

normal address: the transaction is signed (by using the private key of the corresponding public address). Validation is done by checking the hash (generated with the private key) and validating the hash with the public key.
script address: validation is done be executing the script giving the context (UTxOs), redeemer (some additional data added by the generator) and the datum (previous state of the script).

The blockchain itself only stores hashes (of script, datum etc), but not actual data (except for amount of Ada or other tokens), although there seems to be an option to add metadata (which, for the sake of clarity, don't take into account)
Am I understanding it correctly, or do I miss something (or many things :) )?
Thanks!

One detail to add here:

In short:

if another Tx generator wants to use the same script, but one or more blocks later, it will need the datum (previous state of the script), which must be exposed by the previous generator somehow.

Tx has an option to provide the full Datum in the UTXO and not just the hash so that's one way for the "previous generator" to provide the Datum.

ok, thx! Yeah, I didn't include that yet, but I will. I wasn't sure how to do it. That will make the scheme a bit more complex, but I guess it will still be readable.
(If that's the biggest issue, I do get how things work :) ).
Thanks again!

The blockchain does not only store hashes. It also stores the datum and the script of spent UTxOs. It would otherwise not be possible to validate the transaction in retrospect. So while you don't need to provide the script and the datum (though the latter is done by default in Plutus off-chain code) when generating the UTxO, they currently need to be included in the transaction that spends these UTxOs.
I say "currently" because there is an improvement proposal in the pipeline that allows reference scripts. With this improvement, it is not necessary to include the script in every transaction. It is enough if the script was include once in a past transaction and added to the blockchain. Future transactions then can reference this script.
Besides this, you got the process flow right.

Well, I have heard Lars (and others) say multiple times now that one always should provide the datum (and also the script) because the blockchain only stores hashes. For the datum it's clear you can do both, and when another 'Tx Generator' needs the datum, it has to be passed in some way (UTxO metadata, publish somewhere, pass to others in any other way).
For the script itself, I hear contradictory statements. I guess I'll need to ask it Lars in the next Q&A :).

How could you implement referencing scripts if they were not put onto the blockchain ? You need to provide the script in your offline code, this is true. But then it makes it to the blockchain as part of the transaction. There is no contradiction here.

You send the script together with your Tx. That's how I understand it, but I'm not 100% sure either. https://youtu.be/ABtffZPoUqU?list=PLNEK_Ejlx3x2zxcfoVGARFExzOHwXFCCL&t=1427 : the vesting script is added in the Tx, the blockchain checks if it's the right script by comparing the hash. Lars saying there: 'you have to provide the actual script'.
(I hear contradictory statements: it's stored on the bockchain vs it is not stored on the blockchain. When send together with the Tx, it's not stored on it, only executed on it.)

in my schema, the script is not stored on the blockchain. The script is send in the Tx together with datum and redeemer. But it is executed on the blockchain (or rather, on a blockchain-node).
Reference script, right, that may be a different thing, but there's no mention in the course so far (lecture 3) of reference scripts, so I don't know about them yet :).


text:
Problem serializing on-chain code into Plutus Script
Command:
cabal run my-app "a1" 100 "a2" 120000 "a12" "Token" "Product" True 234532453452 True 120000 32432342234234 "a2" "a2" 1 "a3"
Output:
my-app: unpaired digit
CallStack (from HasCallStack):
  error, called at src/Data/Either/Extras.hs:6:34 in plutus-ledger-api-0.1.0.0-722448a5fae0f9232a42f0b4d7b674e63f6fcb91b2188125b0779e3215e4fb4f:Data.Either.Extras

Code snippet:

data STP = STP
    { stpA      :: !Bool
    , stpB      :: !POSIXTime
    , stpC      :: !Bool
    , stpD      :: !(Maybe Integer)
    , stpE      :: !(Maybe POSIXTime)
    , stpF      :: !(Maybe BuiltinByteString)
    } deriving (Show, Generic, FromJSON, ToJSON, Prelude.Eq, ToSchema)

data GOP = GOP
    { gopG      :: !PaymentPubKeyHash
    , gopH      :: !Integer
    , gopI      :: !BuiltinByteString
    , gopJ      :: !Integer
    , gopK      :: !CurrencySymbol
    , gopL      :: !TokenName
    , gopM      :: !TokenName
    , gopType   :: !STP
    , gopToken  :: !(Maybe ThreadToken)
    } deriving (Show, Generic, Eq, Ord, FromJSON, ToJSON, Prelude.Eq, ToSchema)

-------------

main :: IO ()
main = do
    [gopG', gopH', gopI', gopJ', gopK', gopL', gopM', stpA', stpB', stpC', stpD', stpE', stpF', txOutRefId', txOutRefIdx', ttCurrencySymbol'] <- getArgs
    let b   = POSIXTime (read stpB')
        d   = Just (read stpD')
        e   = Just $ POSIXTime (read stpE')
        stp         = STP
                    { stpA      = read stpA'
                    , stpB      = b
                    , stpC      = read stpC'
                    , stpD      = d
                    , stpE      = e
                    , stpF      = Nothing
                    }
        gop         = GOP
                    { gopG      = PaymentPubKeyHash (fromString gopG')
                    , gopH      = read gopH'
                    , gopI      = fromString gopI'
                    , gopJ      = read gopJ'
                    , gopK      = fromString gopK'
                    , gopL      = fromString gopL'
                    , gopM      = fromString gopM'
                    , gopType   = stp
                    , gopToken  = Just $ ThreadToken (TxOutRef (fromString txOutRefId') txOutRefIdx') $ fromString ttCurrencySymbol'
                    }
        orderFile = "scripts/app.plutus"
    writePlutusScript orderFile (dagribizOrderSerialised gop) (dagribizOrderSBS gop)

writePlutusScript :: FilePath -> PlutusScript PlutusScriptV1 -> SBS.ShortByteString -> IO ()
writePlutusScript filename scriptSerial scriptSBS =
  do
  result <- writeFileTextEnvelope filename Nothing scriptSerial
  case result of
    Left err -> print $ displayError err
    Right () -> return ()

"Unpaired digit" is an error from the fromHex function, which needs pairs of hexadecimal digits. So I think the error comes from your fifth argument "a12".

Thanks. I spent some months looking for "Unpaired digit" in the libraries to no avail.


text:
Incorrect Pub Key from Wallet Emulator
I am getting incorrect pubkeys by running mockWalletPaymentPubKey $ knownWallet 1 and mockWalletPaymentPubKey $ knownWallet 2 (from here https://youtu.be/ae7U_yKIQ0Y?t=1390).
I checked that

I am in the correct directory
I imported the wallet emulator using import Wallet.Emulator
and the cabal build command ran successfully.

On restarting the repl, I get the same incorrect wallet pub keys.
Note: I was able to get the correct pub keys by looking at the transactions in the simulator.

mockWalletPaymentPubKey gives you the public key for a wallet.
For Vesting.hs, you need to use the public key hash.
Try mockWalletPaymentPubKeyHash $ knownWallet 1 instead.


text:
Confusion regarding findOwnInput function with on-chain code
Context
I was looking for a simple way to get exact TxOut on on-chain code to validate if funds are to be unlocked to correct wallet address. While looking in plutus haddoc I have found this function:
{-# INLINABLE findOwnInput #-}
-- | Find the input currently being validated.
findOwnInput :: ScriptContext -> Maybe TxInInfo
findOwnInput ScriptContext{scriptContextTxInfo=TxInfo{txInfoInputs}, scriptContextPurpose=Spending txOutRef} =
    find (\TxInInfo{txInInfoOutRef} -> txInInfoOutRef == txOutRef) txInfoInputs
findOwnInput _ = Nothing

This function returns:
-- | An input of a pending transaction.
data TxInInfo = TxInInfo
    { txInInfoOutRef   :: TxOutRef
    , txInInfoResolved :: TxOut
    } deriving stock (Generic, Haskell.Show, Haskell.Eq)

And here is where most of my confusion comes from - getOwnInput returns TxInInfo which has TxOut. All I see is TxIn is TxOut.
This makes it really unclear to me exactly which part of locking or unlocking transaction UTXO getOwnInput function returns.
Lets say that I have 10 Ada in wallet A and I'm creating locking transaction TX1 of 2 Ada to SC1. The way I see it TX1 should look like this:

UTXO1 of 10 ADA is created by taking all the funds from wallet A.
UTXO2 of 10 ADA - 2 ADA - fees1 is created and is sent back to wallet A.
UTXO3 of 2 ADA is created and sent to SC1.

Lets say that now I'm trying to unlock 2 ADA from SC1 back to wallet A by creating TX2:

UTXO4 10 ADA - 2 ADA - fees1 are taken from wallet A to pay for fees2
UTXO5 2 ADA is being taken from SC1
UTXO6 2 ADA are sent to wallet A
UTXO7 10 ADA - 2 ADA - fees1 - fees2 are sent back to wallet A

Main question
So my main question is. Which of these UTXOs does the function getOwnInput return as a txInInfoResolved when TX2 is created?
Bonus question
When TX2 is created, from Plutus validator point of view, which of UTXOs are TxOut and which are TxIn?

My guess would be that answer to main question is UTXO3, because on this tx pubKeyOutput returns Nothing. I suppose it is because UTXO3 goes into smartcontract which doesn't have PubKeyHash but has ValidatorHash instead.

Calling findOwnInput in a validator returns the value contained in the Script-UTxO that is currently being validated. In your example above it is the one with 2 Ada in it.
Your example above is, however, not correctly formulated: UTXO4 is in fact UTXO2 and UTXO5 is UTXO3, also UTXO7 and UTXO4 are not necessary.


text:
How to create signer hash for cardano-cli transaction build --required-signer-hash?
I need to use --required-signer-hash instead of --required-signer because I don't want to have access to the payment signing key, instead I want a user to create a hash and send it to us. How to create the hash of the payment signing key?

The following command gives the hash of a payment address
cardano-cli address key-hash --payment-verification-key-file payment.vkey

Remember to change the file name from payment.vkey


text:
How do validators know a policy script is expired based only on slot number?
A policy script can be set to expire. For example:
{
  "before": 51000000
}

The number corresponds to a slot number within the epoch the script is being created. However, the current slot number will be below that number again in subsequent epochs (since slot number starts at 0 each epoch and counts up). How does a validator know that the policy script is expired when it only contains slot information but not epoch information?

The slot number does not get reset with each epoch. You can see here that the slot number is strictly increasing: https://explorer.cardano.org/en.html


text:
GHC-version for Plutus
This is a short question and probably easy to answer.
Where in the Plutus GitHub repository can I check which GHC-version is needed to compile Plutus ?

It is provided by haskell.nix. See: https://github.com/input-output-hk/plutus/blob/184f27c67dc696f4dfd558e0ccdfef0f054b519b/nix/pkgs/haskell/materialized-linux/default.nix#L224

Great, this is what I was looking for.

Plutus provides its own patched version of GHC (8.10.4.20210212) through Nix.

But where can I see this ? Which file in the repository ?


text:
Cardano-Cli Transactions with Assets Utxo
I am getting an error when trying to send a transaction with the following Utxos:
                             TxHash                                 TxIx        Amount
--------------------------------------------------------------------------------------
3a197302622324ebda7b96b39bf566fb408309b8947e635675cbce94efb90bf6     1        2822751 lovelace + TxOutDatumNone
c84758dbea49a9bfd4ce143b074c2f89486027b0595e5e7ca6da5f32a63a3edf     0        5000000 lovelace + 1344000000 698a6ea0ca99f315034072af31eaac6ec11fe8558d3f48e9775aab9d.7444524950 + TxOutDatumNone

and here is the error:
Command failed: cardano-cli transaction submit                  --tx-file ./testnet/trial23_tx.signed                   --testnet-magic 1097911063
Command failed: transaction submit  Error: Error while submitting tx: ShelleyTxValidationError ShelleyBasedEraAlonzo (ApplyTxError [UtxowFailure (WrappedShelleyEraFailure (UtxoFailure (ValueNotConservedUTxO (Value 7822751 (fromList [(PolicyID {policyID = ScriptHash "698a6ea0ca99f315034072af31eaac6ec11fe8558d3f48e9775aab9d"},fromList [("tDRIP",1344000000)])])) (Value 7822751 (fromList [])))))])

is this error due to the fact I am using a Utxo which holds an asset?
I was following this tutorial: https://developers.cardano.org/docs/stake-pool-course/handbook/create-simple-transaction/
is there a tutorial that would help me understand how to create a NOT simple transaction with Utxos + assets?

here is an example of a transaction i send from 2 TxHash, sending ADA + Token
remember, the summary of 2 tx-out must be equal to 2 tx-in.
cardano-cli transaction build-raw
--fee {fee}
--tx-in b98eb283dflkh4582402u40480253c23c0fc35e1a2bcf445e18#0
--tx-in eebb2a5sldfjkdlkfjo485u30ruwldkfjs45346352126b220de8f6f#1
--tx-out addr1qy4hewroi045398753987923oriwrio2u034urrt5rz0vdpmc8lzlpqcj0yznqwaelpl+2000000+"1 0fd9819234872935727sdf7027400df7hg077dc15.5692847553"
--tx-out addr1v9uh244h55jk5k6jk4b2kn42kln53um+7049462+"8 0fd9819234872935727sdf7027400df7hg077dc15.5692847553"
--out-file tx.raw

can one Utxo have more than one asset?

like:
--tx-out "address+5000000 + 5 policyid.assethexname + 100 policyid2.assethexname2" ?

yes for sure
, and you text it the correct way.

You need to specify the Ada and asset in the output so it balances. Something like --tx-out "address+5000000 + 5 policyid.assethexname" with your remaining balance needed to balance the transaction.


text:
What is the correct way to compare two instances of Value data type?
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

Can you paste the whole validator, i.e. the function that takes 3 arguments and returns a Bool.

Can you show your offline code? Concretely, the give contract.

@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

Are you using == from PlutusTx.Prelude or Prelude (Haskell) ?

Good question. I don't know. How could I check?

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)

According to Ledger.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.

In my case when I go:
compareTwoValues :: Value -> Value -> Bool
compareTwoValues v1 v2 = v1 == v2

This just crashes

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.


text:
Cannot send a transaction using Plutus
I get the following error when I try to send a transaction that locks some ADA in a UTXO:
[pab:Warning:41] [2022-01-28 11:58:42.88 UTC] WalletClientError

"ConnectionError (HttpExceptionRequest Request {\n  host                 = "localhost"\n  port                 = 8090\n  secure               = False\n  requestHeaders       = [("Accept","application/json;charset=utf-8,application/json"),
("Content-Type","application/json;charset=utf-8")]\n  path                 = "/v2/wallets/70cf045f3e980335f39035b14d6dcc165001bea0/transactions-balance"\n  queryString          = ""\n  method               = "POST"\n  proxy                = Nothing\n  rawBody              = False\n  redirectCount        = 10\n  responseTimeout      = ResponseTimeoutDefault\n  requestVersion       = HTTP/1.1\n
proxySecureMode      = ProxySecureWithConnect\n}\n (ConnectionFailure Network.Socket.connect: <socket: 16>: unsupported operation (Cannot assign requested address)))"
Can anyone help?

Which set up are you using: the VScode container or Nix?

@Angelo, I'm using VScode container


text:
Plutus and Haskell live references
I am following the plutus pioneer program as an Haskell newbie.
I am using VSCode to look at the snippets and type my code.
I am wondering what is the best way to integrate (if possible) the languages documentation into the IDE. I would love to just reach the function documentation with a couple of clicks!
Thanks

Use this plugin: https://marketplace.visualstudio.com/items?itemName=haskell.haskell
Then from the nix-shell run code . to start VSCode and to let it use the right haskell-language-server version.

Unfortunately this doesn't work in the plutus pioneer program weeks so far (currently week03). Your IDE uses the haskell language server to get type references but if you run the command haskell-language-server in a nix-shell in the current week's repository you will get an error. This is documented in this question: HLS Compiler Error PPP Week01 (WSL2 + VSCode)

Try working from https://demeter.run, it should have this (I think)


text:
How to separate continuing outputs to compare datums
In the auction code of the Plutus pioneer program during week 1, the code approves a bid by comparing the datum with previous ones in the Plutus on-chain code. How could you repurpose this so that you could store multiple utxos of different datums tokens on the smart contract then verify transactions for only the tokens that match the needed datum?
This is the code i'm refrencing
ownOutput   :: TxOut
        outputDatum :: Integer
        (ownOutput, outputDatum) = case getContinuingOutputs ctx of
            [o] -> case txOutDatumHash o of
                Nothing   -> traceError "wrong output type"
                Just h -> case findDatum h info of
                    Nothing        -> traceError "datum not found"
                    Just (Datum d) ->  case PlutusTx.fromBuiltinData d of
                        Just iDatum' -> (o, iDatum')
                        Nothing  -> traceError "error decoding data"
            _   -> traceError "expected exactly one continuing output"

This is not a free code foundry.  If you attempt a solution and have problems, then the answers may be found here or you could ask about the specific problem you are having.

Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer.

I had a similar question:
"How do you handle 2 continuing outputs?"
Couldn't find any answers or documentation
anywhere!
After lots of experimenting, I came up with
the following code. (it handles 2 continuing outputs).
Probably not the most efficient, but it
works:
ownOutputa = (getContinuingOutputs ctx) !! 0
ownOutputb = (getContinuingOutputs ctx) !! 1

myDatum :: TxOut -> (DatumHash -> Maybe Datum) -> Maybe MyDatum
myDatum o f = do
    dh      <- txOutDatum o
    Datum d <- f dh
    PlutusTx.fromBuiltinData d

outputDatuma :: MyDatum
outputDatuma = case myDatum ownOutputa (`findDatum` info) of
    Nothing -> traceError "output datum a not found"
    Just d  -> d

outputDatumb :: MyDatum
outputDatumb = case myDatum ownOutputb (`findDatum` info) of
    Nothing -> traceError "output datum b not found"
    Just d  -> d


text:
Running `cabal haddock` on a repo with plutus code errors
Aim: document a repo with plutus code using haddock.
Problem: Naively running cabal haddock has a problem that seems to be caused by plutus (on-chain) code.
For example, plutus-pioneer-program week03 runs in the repl with cabal repl, but cabal haddock errors as follows.
Haddock coverage:
GHC Core to PLC plugin: E043:Error: Reference to a name which is not a local, a builtin, or an external INLINABLE function: Variable Ledger.Typed.Scripts.Validators.wrapValidator
            No unfolding
Context: Compiling expr: Ledger.Typed.Scripts.Validators.wrapValidator
Context: Compiling expr: Ledger.Typed.Scripts.Validators.wrapValidator
                           @ Week03.Homework1.VestingDatum
Context: Compiling expr: Ledger.Typed.Scripts.Validators.wrapValidator
                           @ Week03.Homework1.VestingDatum @ ()
Context: Compiling expr: Ledger.Typed.Scripts.Validators.wrapValidator
                           @ Week03.Homework1.VestingDatum
                           @ ()
                           Week03.Homework1.$fUnsafeFromDataVestingDatum
Context: Compiling expr: Ledger.Typed.Scripts.Validators.wrapValidator
                           @ Week03.Homework1.VestingDatum
                           @ ()
                           Week03.Homework1.$fUnsafeFromDataVestingDatum
                           PlutusTx.IsData.Instances.$fUnsafeFromData()
Context: Compiling expr at "plutus-pioneer-program-week03-0.1.0.0-inplace:Week03.Homework1:(60,8)-(60,37)"
cabal: Failed to build documentation for
plutus-pioneer-program-week03-0.1.0.0.

Is there a straightforward way to build haddock docs for repos with plutus code?

Yes! Try cabal haddock -fplugin-opt Plutus.Tx.Plugin:defer-errors.
(From https://plutus-apps.readthedocs.io/en/latest/plutus/troubleshooting.html#plugin-errors)

Editing the cabal.project file as the link suggests gets cabal haddock working so I'm good. Passing cli arguments as suggested above or in the docs linked gives an error: cabal: Unrecognised target 'PlutusTx.Plugin:defer-errors'. Expected a module name, rather than 'defer-errors'.
I tried various perturbations such as Plutus.Tx...


text:
Examples of testing on-chain code
There are extensive examples for the testing frameworks for contracts, ie off-chain code, for example as discussed in Lecture 8 of the plutus pioneer program https://youtu.be/zW3D2iM5uVg.
Its mentioned there that one thing not covered is the testing of validators directly, ie on-chain code.
Are there examples of this available?

I raised this in a PPP QA. Lars said that he knows of two possible inroads to the problem:

Write additional contracts with the sole purpose of testing.
cooked validators from Tweag


text:
In which node is a wallet connected?
I have a question
A node is needed to execute a transaction, but in which node are these wallets connected to execute a transaction?
all wallets are tied to a node? or can that specific wallet be connected to a chosen node or a public node?
for example, daedalus downloads a whole node, so I might guess that the transaction is running on the same daedalus node, but yoroi does not install any node on the user's pc, so where is that transaction sent to be validated?

You're correct - Daedalus runs a full node on the local PC, so transactions initiated on Daedalus are submitted through the local running node. The same is true for transactions submitted using cardano-cli or cardano-wallet - they use a locally running node.
For other wallet software(s) like Yoroi, Nami, etc that are browser extensions, they submit transactions via remote nodes administered on some back-end servers.

I can't speak for yoroi, but nami is another light wallet.
It interfaces with the chain using the blockfrost api.
This handles talking to the nodes.
Nami now lets you point it at a node of your choice
https://twitter.com/pernistoken/status/1485563609560551428
Other light wallets do something analogous.


text:
How can I get the wallet distribution of a token?
I'd like to determine the number of wallet holders for (example)

Lobster holders
ClayNation owners

How can I query this with a full node?

You would need db-sync to get that sort of data. https://github.com/input-output-hk/cardano-db-sync
You can use existing solutions like Koios (https://api.koios.rest/#overview).
Example for Lobster token:
curl -X GET "https://api.koios.rest/api/v0/asset_txs?_asset_policy=8654e8b350e298c80d2451beb5ed80fc9eee9f38ce6b039fb8706bc3&_asset_name=4c4f4253544552"

Response:
[
  {
    "policy_id": "8654e8b350e298c80d2451beb5ed80fc9eee9f38ce6b039fb8706bc3",
    "asset_name": "4c4f4253544552",
    "total_transactions": 340660,
    "staked_wallets": 2433,
    "unstaked_addresses": 9
  }
]

Thanks a lot, didn't know about koios.


text:
How does Cardano execute real time transactions if block time is 20 seconds?
New to the crypto space, please correct me if I misunderstood the meaning of block time.
When a cardano node submits a transaction, it goes to a local mempool and submitted on the blockchain for verification. Let's assume this part is instantaneous from the wallet node.
The official docs state that blocks are produced every 20 seconds. In other words, even if the validator nodes receive the transaction immediately, they will wait upto another 20 seconds, and then create a new block to broadcast.
This implies even a low assurance for block will take atleast 20 seconds. In my experience with cardano wallets (before the dexes were launched), it rarely took more than 10 seconds to get a high assurance for transaction.
I also read on the forums that 20 seconds block time is configurable, and can't be enforced on a node. So are we relying on SPOs to use a low block creation time interval to solve real time transactions in the long run?

Block time is 20 seconds in average. Sometimes we have blocks at shorter intervals, sometimes much longer. I saw sometimes sequences of 4 or 5 blocks at one second interval from each other. And sometimes even 2 minutes. And sometimes we have 2 or even stake pools which are minting a block in the same second, and only one will be adopted by the blockchain (this is called a slot battle). And when a stake pool mints a block without receiving the previous minted block (if it was minted in the second before, and the propagation time is more than 1 second), a height battle will occur, and only one of the 2 blocks will be adopted.
SPOs cannot choose when to mint a block. This is decided randomly, based on the VRF key of each stake pool, and is known 1.5 days before each epoch starts for the next epoch. In about 2 hours, I will know how many slots to mint blocks my stake pool has allocated for epoch 318 (exact date and time, in seconds, because one slot is one second).
The average interval of 20 seconds between block is given by a parameter, "density", which is not 0.05 (5%). This means 5 blocks in average for every 100 seconds. This is a parameter that can be adjusted, but I don't think it will be adjusted soon.
If your transactions were confirmed until now in less than 10 seconds, you were just "lucky". Now the blockchain is pretty busy, and it will probably take a few blocks until a transaction is confirmed, even more if you are using a light wallet.

Thanks for the detailed explanation. I still don't follow how would Cardano achieve real time transactions, say someone paying ADA at a coffee shop. Is density parameter tuning from 0.05 to 1.00 (or close to 1) the only way? Why not do it now?

Have one more query on your statement "In about 2 hours, I will know how many slots to mint blocks my stake pool has allocated for epoch 318". Are you suggesting slot leaders for each slot in the coming epoch are announced 1.5 days before it starts? If that were the case, wouldn't an SPO just turn on their machine for those few seconds and ignore the rest because it's not getting any revenue? Additionally, what happens a preselected slot leader is down when the slot time comes?

Yes, SPOs can find out 1.5 days before a new epoch starts the slots when their stake pools will mint blocks. They could turn off the block producer, but starting it and starting the service takes at least 10 minutes, sometimes a lot longer.
The relays cannot be stopped, because they need incoming connections to propagate blocks. It you stop them, you lose those connections, and the blocks will be lost. This is why the relays must stay connected all the time.

For real time payments a Layer 2 solution will probably be better suited.

@dev - the Cardano roadmap has a bunch of things in the pipeline coming that will lead to scalability. Hydra Head is a big one, but AFAIK there are a bunch of other things that will work together to increase Transactions Per Second to 3000+. Right now they've just introduced smart contracts and dapps, so I think that's what a lot of the work has been going to.


text:
Mongolia Course - Slides, Homework and Solutions
Does anyone know if we have access to the Mongolia course slides, homework and solutions? If so where can we find them? If not, please could they be made available? I think the homework exercises with solutions will be great practise for learning all the Haskell concepts as we follow the you tube videos.

Please note that the videos on github cover core content than the videos in YouTube

here
https://github.com/iohkedu/haskell-2020
videos, slides, homeworks and solutions
The videos here have way more content than in youtube


text:
Can complete transactions be effected using Cardano-cli with only minimal or no plutus involvement?
I'm doing week 3 of the Plutus Pioneer Program. The CLI portion was especially interesting to me. If I understand correctly, the cardano-cli can interact with the real mainnet, which presents the following opportunity: Use the CLI to execute transactions, but have everything else (all the business logic) controlled by a non-Plutus programming construct (eg. PHP, MySQL, Python, even Applescript).
Writing dynamically created shell scripts to execute individual transactions appears to be fairly straightforward. What obstacles/problems/unintended consequences might I encounter creating such a thing? Much of what Plutus smart contracts allow does not apply to the business project I am envisioning.
Update January 1, 2023.
I have just released an Applescript based installer for cardano-node. I call it FASTLAIYN (Forget About Shell Tedium, Let Applescript Install Your Nodes).
http://www.linkedresources.com/fastlaiyn/index.php
I'm also well on my way to building an Applescript based transfer wallet and NFT generator. If I can find others interested in applying Applescript to the cardano-cli, we could turn this into a legitimate Cardano project for the ecosystem.

You are correct - there were many scripts created by the community for mainnet use long before Plutus Contracts launched in September 2021. A good example of this are the Guild Operator's Wrapper Scripts. - an excellent toolkit mostly written for shell use.
If Plutus is not/minimally necessary for your business logic, then bon voyage!

Both answers offered are excellent. I wish I could vote for both.

I have some example python code that does pretty much what you ask called adawallet. https://github.com/input-output-hk/adawallet
It works by shelling out to the CLI from a python library to cardano-cli, cardano-address and cardano-hw-cli. It gets chain state from cardano-rosetta so the user creating the transactions doesn't need a full node, and user signing transactions can do so fully offline with no internet access to keep the keys secure. It keeps local state in a SQLite database.
The downside of developing an application for others to use without plutus scripts is it requires trust on the user using your service that your code will do what they asked it to. Plutus on the other hand gives you on-chain code that if the user knows what the code is supposed to do, they don't need to trust a central authority to do what they've asked. This is essentially for example the difference between a centralized exchange and a decentralized exchange. The decentralized one uses on-chain code to deliver some guarantee to the user.


text:
Cardano-Cli How to Check Address Delegation Status?
is it possible in cardano-cli to check the status of delegation for any stake.addr?
is there a command that shows which pool a stake.addr is delegated to?
does that require the use of the heavy ledger-state?

cardano-cli query stake-address-info does what you're looking for. It shows the registration status of a stake address, if it's delegated and how many rewards are available for withdrawal.


text:
Meaning of <$> notation
I see the <$> notation often in the Plutus/Haskell code but have no idea what it means. I understand that $ alone is a parenthesis replacement. Is <$> similar? Does it suggest enclosing parenthesis?
Example from the deploy.hs script in week 3.

dataToScriptData :: Data -> ScriptData
dataToScriptData (Constr n xs) = ScriptDataConstructor n $ dataToScriptData  xs
dataToScriptData (Map xs)      = ScriptDataMap [(dataToScriptData x, dataToScriptData y) | (x, y)  xs
dataToScriptData (I n)         = ScriptDataNumber n
dataToScriptData (B bs)        = ScriptDataBytes bs

So hard to do a Google search on Haskell's cryptic syntax!

It's a functor map which is essentially an fmap function for the functor class. This might be of some use: https://www.fpcomplete.com/haskell/tutorial/operators/

Hoogle is also a great resource for searching Haskell's syntax. https://hoogle.haskell.org/?hoogle=%3C%24%3E (edit: Oh I see your link immediately references Hoogle haha)

For Haskell questions of this sort Hoogle is the ultimate resource.
For operators like <$> you need to enclose them in parenthesis eg (<$>).


text:
Is Camel Case notation required for the Asset Name of an NFT?
Hello i just have noticed that i can mint NFTs with the Cardano serialization Lib with out using Camel Case notation: I can have string spaces as well a special characters.
I have read in the CIP-25 nothing that does not let me do that
https://cips.cardano.org/cips/cip25/
But using Cardano-Cli I see it is not posible. Anybody knows anything about it?

Any limitations are artificial limitations in conversion. On the blockchain it's all hex and current master branch of node the CLI expects all inputs to be hex which should remove the limitation entirely.

I aks because i minted some NFTs  and CardanoScan does not show me the human readable Name


text:
how does the magic number work for different era's?
I'm a but confused with the magic number in the testnet:

when we execute a transaction with the cli cardano-cli run transaction , we run it in the alonzo-era. when we check for the
magic number, we have to check the networkMagic field in
testnet-shelly-geneisis.json

There doesn't seem to be a networkMagic in testnet-alonzo-genesis.json, although there is in both the shelly and byron config files, and it's the same networkMagic in these two configs.
Can someone explain how this works with the magic number and the era's?
(As a small side question, why is it actually called the Alonzo era, while we're in the Cardano Goguen era? For the first two, they use the same era names, for the one we're in now, it's another name. It's a bit confusing.)

The network magic is not supposed to be mutable. The only reason it's in the Shelley Genesis is because the Shelley Genesis simplified the Byron genesis file format significantly and allows the code to "ignore" the mess of the Byron genesis file as soon as it reaches the Shelley era. Newer era Genesis files are additive to the Shelley era rather than a replacement like we had from Byron to Shelley transition.

OK, I think I more or less get it, but the magic number is a random number which is unique to the testnet 'version' or something? So, when things change, this number may change, but it's not supposed to change? That makes a bit of sense.
Now, what's with the Alonzo Era which is actually the Goguen era?


text:
PPViewHashesDontMatch and UnspendableUTxONoDatumHash error on redeeming funds from week03 example
I am trying to redeem the funds from the smart contract into the second wallet without running cardano-node (following the instructions from here: https://www.youtube.com/watch?v=ABtffZPoUqU&list=PLNEK_Ejlx3x2zxcfoVGARFExzOHwXFCCL&index=11) but I get the following error (bcc is blockfrost's cardano-cli is taken from here https://github.com/blockfrost/blockfrost-cardano-cli):
$ bcc transaction submit -f tx.signed -t
 ›   Error: Command failed: transaction submit error
 ›   ShelleyTxValidationError ShelleyBasedEraAlonzo (ApplyTxError
 ›   [UtxowFailure (UnspendableUTxONoDatumHash (fromList [TxInCompact (TxId
 ›    {_unTxId = SafeHash
 ›   \"8583cadfd7a43be943b78b7756c9f02c7825f03dbc67d6dae24f6fb12080144e\"})
 ›    0])),UtxowFailure (PPViewHashesDontMatch (SJust (SafeHash
 ›   \"ca6319c1203911911d372c25297cb9d6606b515a9157a5e9d0a5bcec642efd34\"))
 ›    (SJust (SafeHash \"a0e5ad883f81c0808f38cfc635e2ede5f760fcb4cb83f8bdcf
 ›   f0491b1f50b30f\")))])

After pretty-printing this error for a bit I found the two errors mentioned in the question.
Here are the commands I used:
# give.sh (these commands ran fine)

cardano-cli transaction build-raw \
    --alonzo-era \
    --tx-in c2e2ef139d709c1bb8a0e50efbc9100c41ca34f91a9027823afbfcb45acd6d55#1 \
    --tx-out $(cat vesting.addr)+200000000 \
    --tx-out $(cat 01.addr)+789600000 \
    --fee 200000 \
    --tx-out-datum-hash-file unit.json \
    --out-file tx.body

cardano-cli transaction sign \
    --tx-body-file tx.body \
    --signing-key-file 01.skey \
    --testnet-magic 1097911063 \
    --out-file tx.signed

bcc transaction submit -f tx.signed -t

then
# grab.sh

cardano-cli transaction build-raw \
    --alonzo-era \
    --tx-in 8583cadfd7a43be943b78b7756c9f02c7825f03dbc67d6dae24f6fb12080144e#0 \
    --tx-in-script-file vesting.plutus \
    --tx-in-datum-file unit.json \
    --tx-in-redeemer-file unit.json \
    --tx-in-execution-units "(491845099,1197950)" \
    --tx-in-collateral c2e2ef139d709c1bb8a0e50efbc9100c41ca34f91a9027823afbfcb45acd6d55#0 \
    --required-signer-hash 6cc0729360da2e3592e516f261161140ae96455c12861dec958a4d86 \
    --tx-out $(cat 02.addr)+199400000 \
    --fee 600000 \
    --protocol-params-file protocol.json \
    --out-file tx.body

cardano-cli transaction sign \
    --tx-body-file tx.body \
    --signing-key-file 02.skey \
    --testnet-magic 1097911063 \
    --out-file tx.signed

bcc transaction submit -f tx.signed -t

To fix UnspendableUTxONoDatumHash I tried to hash the unit.json file using cardano-cli transaction hash-script-data --script-data-file unit.json > datum.hash but then the final command called this address 803a67b79578b8f24a15958a232b98aa2a40ec5e4d0e172e67336a235e51f328 as UnspendableUTxONoDatumHash.
To fix PPViewHashesDontMatch I tried searching for the hashes on the blockchain explorer but didn't find anything. In any case, I checked whether the beneficiary in Deploy.hs is set correctly but didn't find anything wrong there.

Edit #1
after fixing order of options I changed the build-raw command in give.sh to
cardano-cli transaction build-raw \
    --alonzo-era \
    --tx-in 079fa1b365b9a39a729968e3702f9a638f35cdcebdb1ea2ca5aeca4d32b20a0e#1 \
    --tx-out $(cat vesting.addr)+200000000 \
    --tx-out-datum-hash 923918e403bf43c34b4ef6b48eb2ee04babed17320d8d1b9ff9ad086e86f44ec \
    --tx-out $(cat 01.addr)+199200000 \
    --fee 200000 \
    --out-file tx.body

I get a different error
 ›   Error: Command failed: "transaction submit error
 ›   ShelleyTxValidationError ShelleyBasedEraAlonzo (ApplyTxError
 ›   [UtxowFailure (PPViewHashesDontMatch (SJust (SafeHash
 ›   \"ca6319c1203911911d372c25297cb9d6606b515a9157a5e9d0a5bcec642efd34\"))
 ›    (SJust (SafeHash \"a0e5ad883f81c0808f38cfc635e2ede5f760fcb4cb83f8bdcf
 ›   f0491b1f50b30f\"))),UtxowFailure (WrappedShelleyEraFailure
 ›   (UtxoFailure (UtxosFailure (ValidationTagMismatch (IsValid True)
 ›   (FailedUnexpectedly [PlutusFailure \"\\nThe 3 arg plutus script
 ›   (PlutusScript PlutusV1 ScriptHash
 ›   \\\"4d8aa3f72ac815edd554d1f3ecdc708ba0d9e52cd161f3b3a5640042\\\")
 ›   fails.\\nCekError An error has occurred:  User error:\\nThe provided
 ›   Plutus code called 'error'.\\nThe data is: Constr 0 []

Edit 2
Using the curl version of blockfrost transaction submit (https://docs.blockfrost.io/#tag/Cardano-Transactions/paths/~1tx~1submit/post) I get some more info
{
  "error": "Bad Request",
  "message": "\"transaction submit error ShelleyTxValidationError ShelleyBasedEraAlonzo (ApplyTxError
    [UtxowFailure
      (PPViewHashesDontMatch
        (SJust
          (SafeHash \\\"ca6319c1203911911d372c25297cb9d6606b515a9157a5e9d0a5bcec642efd34\\\"
          )
        )
        (SJust
          (SafeHash \\\"a0e5ad883f81c0808f38cfc635e2ede5f760fcb4cb83f8bdcff0491b1f50b30f\\\"
          )
        )
      ),
    UtxowFailure
      (WrappedShelleyEraFailure
        (UtxoFailure
          (UtxosFailure
            (ValidationTagMismatch (IsValid True)
              (FailedUnexpectedly
                [PlutusFailure \\\"\\\\nThe 3 arg plutus script
                  (PlutusScript PlutusV1 ScriptHash \\\\\\\"4d8aa3f72ac815edd554d1f3ecdc708ba0d9e52cd161f3b3a5640042\\\\\\\"
                  ) fails.\\\\n
                  CekError An error has occurred:  User error:\\\\n
                  The provided Plutus code called 'error'.\\\\n
                  The data is: Constr 0 []\\\\n
                  The redeemer is: Constr 0 []\\\\n
                  The context is:\\\\n
                  Purpose: Spending (TxOutRef
                    {txOutRefId = c3850544d66a0eef38326551c35807975c201f25787e8e9a379a306ee6f9c1f3, txOutRefIdx = 0
                    }
                  )\\\\n
                  TxInfo:\\\\n
                    TxId: d0aeeed88977e51047f7d455b5bac47f29c7ae70d9e5313bf504a35b3e56cd29\\\\n
                    Inputs: [ c3850544d66a0eef38326551c35807975c201f25787e8e9a379a306ee6f9c1f3!0
                      -> - Value (Map [(,Map [(\\\\\\\"\\\\\\\",200000000)])]) addressed to\\\\n
                      ScriptCredential: 4d8aa3f72ac815edd554d1f3ecdc708ba0d9e52cd161f3b3a5640042 (no staking credential) ]\\\\n
                    Outputs: [ - Value (Map [(,Map [(\\\\\\\"\\\\\\\",199400000)])]) addressed to\\\\n  ",
  "status_code": "400"
}

The PPViewHashesDontMatch error from Edit #2 is caused by protocol parameters file not having cost models field populated - this is a problem with blockfrost-cardano-cli not having access to cost models via Api resulting in script transactions failing.

Order of parameters is important!!!
From cardano-cli transaction build --help:
Usage: cardano-cli transaction build
            [ --byron-era
            | --shelley-era
            | --allegra-era
            | --mary-era
            | --alonzo-era
            ]
            [ --shelley-mode
            | --byron-mode [--epoch-slots NATURAL]
            | --cardano-mode [--epoch-slots NATURAL]
            ]
            (--mainnet | --testnet-magic NATURAL)
            [--script-valid | --script-invalid]
            [--witness-override WORD]
            (--tx-in TX-IN
              [--tx-in-script-file FILE
                [(--tx-in-datum-file FILE | --tx-in-datum-value JSON VALUE)
                  ( --tx-in-redeemer-file FILE
                  | --tx-in-redeemer-value JSON VALUE
                  )]])
            [--required-signer FILE]
            [--tx-in-collateral TX-IN]
            [--tx-out ADDRESS VALUE
              [ --tx-out-datum-hash HASH
              | --tx-out-datum-hash-file FILE
              | --tx-out-datum-hash-value JSON VALUE
              | --tx-out-datum-embed-file FILE
              | --tx-out-datum-embed-value JSON VALUE
              ]]
            --change-address ADDRESS
            [--mint VALUE
              (--mint-script-file FILE
                [--mint-redeemer-file FILE | --mint-redeemer-value JSON VALUE])]
            [--invalid-before SLOT]
            [--invalid-hereafter SLOT]
            [--certificate-file CERTIFICATEFILE
              [--certificate-script-file FILE
                [ --certificate-redeemer-file FILE
                | --certificate-redeemer-value JSON VALUE
                ]]]
            [--withdrawal WITHDRAWAL
              [--withdrawal-script-file FILE
                [ --withdrawal-redeemer-file FILE
                | --withdrawal-redeemer-value JSON VALUE
                ]]]
            [--json-metadata-no-schema | --json-metadata-detailed-schema]
            [--auxiliary-script-file FILE]
            [--metadata-json-file FILE | --metadata-cbor-file FILE]
            [--genesis FILE | --protocol-params-file FILE]
            [--update-proposal-file FILE]
            --out-file FILE

Pay closer attention to this part:
[--tx-out ADDRESS VALUE
              [ --tx-out-datum-hash HASH
              | --tx-out-datum-hash-file FILE
              | --tx-out-datum-hash-value JSON VALUE
              | --tx-out-datum-embed-file FILE
              | --tx-out-datum-embed-value JSON VALUE
              ]]

Notice how nested parameters are. I think you are basically attaching datum to --tx-out $(cat 01.addr)+789600000 and not transaction to the smartcontract!