text:
Is Ed25519 is EUF-CMA secure?
Is the signature scheme of shelley (Ed25519) is EUF-CMA secure?  The Existential Unforgeability under Chosen Message Attack experiment works like this:

The challenger generates a valid keypair (pk, sk) and gives pk to the attacker.

The attacker may now repeatedly ask for signatures on chosen messages $(M_1, \dots, M_q)$ of its choosing, and receives the valid signatures $(\sigma_1, \dots, \sigma_q)$ in response.

At the conclusion of the experiment, the attacker must output a message and signature $M^$, $\sigma^$ such that (1) the message $M^*$ was not one of the messages requested in the previous step, and (2) the message/signature verifies correctly under the public key (Ref).

Now I guess the used signature scheme by Shelley is EUF-CMA secure since by assuming the contrary it would break the blockchain?

EDIT
The only problem I see with assuming the contraposition of the statement is that the messages $(M_1,\dots, M_q)$ are chosen by the adversary. This is not the case in a public ledger though it could be extracted?

Yes, Ed25519 provides the existential unforgeability property. There is a nice work that studies the different variants of Ed25519 signatures
https://eprint.iacr.org/2020/823.pdf
As specified in that document, the different variants of ed25519 provide different security properties, but all are existentially unforgeable under chosen message attacks.
Indeed, as you point out, if an adversary could forge valid signatures to messages not signed by the key owner, the security of the blockchain could be compromised.

Thank you for that paper! Its quite a "recent" paper and as it states in the abstract "no detailed proofs have ever been given for these security properties for EdDSA". I am glad that these security proofs are given just before shelley was launched :)


text:
How to use plutus script withness in other plutus script
How can we reference the use of other scripts in a plutus validator?. Wat I was trying to making is an validator that only validates if an other predetermined plutus scripts also validates in the same transaction. What I tried is the following naive implementation with a type problem
{-# LANGUAGE DataKinds           #-}
{-# LANGUAGE MultiParamTypeClasses      #-}
{-# LANGUAGE DeriveAnyClass      #-}
{-# LANGUAGE DeriveGeneric       #-}
{-# LANGUAGE FlexibleContexts    #-}
{-# LANGUAGE NoImplicitPrelude   #-}
{-# LANGUAGE OverloadedStrings   #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell     #-}
{-# LANGUAGE TypeApplications    #-}
{-# LANGUAGE TypeFamilies        #-}
{-# LANGUAGE TypeOperators       #-}

{-# OPTIONS_GHC -fno-warn-unused-imports #-}

module Onchain where

import           Control.Monad        hiding (fmap)
import           Data.Aeson           (ToJSON, FromJSON)
import           Data.Map             as Map
import           Data.Text            (Text)
import           Data.Void            (Void)
import           GHC.Generics         (Generic)
import           Plutus.Contract
import           PlutusTx             (Data (..))
import qualified PlutusTx
import           PlutusTx.Prelude     hiding (Semigroup(..), unless)
import           Ledger               hiding (singleton)
import           Ledger.Constraints   (TxConstraints)
import qualified Ledger.Constraints   as Constraints
import qualified Ledger.Typed.Scripts as Scripts
import           Ledger.Ada           as Ada
import           Playground.Contract  (printJson, printSchemas, ensureKnownCurrencies, stage, ToSchema)
import           Playground.TH        (mkKnownCurrencies, mkSchemaDefinitions)
import           Playground.Types     (KnownCurrency (..))
import           Prelude              (IO, Semigroup (..), Show (..), String)
import           Text.Printf          (printf)

data MyDatum = MyDatum
    { pubKey :: Integer
    } deriving (Show, Generic, FromJSON, ToJSON, ToSchema)

data MyRedeemer = MyRedeemer
    { privKey :: Integer
    } deriving (Generic, FromJSON, ToJSON, ToSchema)

data ContractInfo = ContractInfo
    { contractValHash :: ValidatorHash }

contractInfo = ContractInfo { contractValHash =  "67f33146617a5e61936081db3b2117cbf59bd2123748f58ac9678656"}

PlutusTx.makeIsDataIndexed ''MyDatum [('MyDatum, 0)]
PlutusTx.makeLift ''MyDatum
PlutusTx.makeIsDataIndexed ''MyRedeemer [('MyRedeemer, 0)]
PlutusTx.makeLift ''MyRedeemer
PlutusTx.makeLift ''ContractInfo

{-# INLINABLE mkValidator #-}
mkValidator :: ContractInfo -> MyDatum -> MyRedeemer -> ScriptContext -> Bool
mkValidator contractInfo _ _ ctx = traceIfFalse "Signature not there" $ signed
        where
              info :: TxInfo
              info = scriptContextTxInfo ctx

              sigs :: [PubKeyHash]
              sigs = txInfoSignatories info

              pubkeyHash :: ValidatorHash
              pubkeyHash = contractValHash contractInfo

              signed :: Bool
              signed = pubkeyHash `elem` sigs -- THIS IS NOT WELL TYPED AND WILL NOT COMPILE SINCE pubkeyHash is actually of type ValidatorHash.

{-# INLINABLE mkValidator2 #-}
mkValidator2 :: BuiltinData -> BuiltinData -> BuiltinData -> ()
mkValidator2 _ _ _ = ()

data Typed
instance Scripts.ValidatorTypes Typed where
    type instance DatumType Typed = MyDatum
    type instance RedeemerType Typed = MyRedeemer

typedValidator :: Scripts.TypedValidator Typed
typedValidator = Scripts.mkTypedValidator @Typed
    ($$(PlutusTx.compile [|| mkValidator ||]) `PlutusTx.applyCode` PlutusTx.liftCode contractInfo)
    $$(PlutusTx.compile [|| wrap ||])
  where
    wrap = Scripts.wrapValidator @MyDatum @MyRedeemer

validator2 :: Validator
validator2 = mkValidatorScript $$(PlutusTx.compile [|| mkValidator2 ||])

validator :: Validator
validator = Scripts.validatorScript typedValidator

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

scrAddress :: Ledger.Address
scrAddress = scriptAddress validator

scrAddress2 :: Ledger.Address
scrAddress2 = scriptAddress validator2

Where 67f33146617a5e61936081db3b2117cbf59bd2123748f58ac9678656 is the ValidatorHash of the validator2 derived from printing scrAddress2. So the first validator mkValidator will validate only if the transaction also contains a validating consumption of an UTxO at the validator2 address? Now of course this will not validate since a validatorHash is not contained in the signature list of type txInfoSignatories :: [PubKeyHash]. But still this would be desirable to have right? I could use this with some minting policy.
On testnet I tried changing the type of contractValHash to PubKeyHash, but this does not work either since scripts have no signatures in the txInfoSignatories field.

Is it perhaps possible to access the TxInType field?

This contains a reference to a script validator (but not really in its compressed form, only in the lamba calculus form).

I just had to sleep a night on it. Obviously one can look at the incoming addresses and lookup the validatorhash in the credentials there. For example use
filter (\x -> (ScriptCredential . addressCredential . txOutAddress) x == ValHash) $ txInfoInputs ctx

to get the transaction input of that script you want present.

source: Stack Exchange

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

sort: votes


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.

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


text:
Does the plutus playground make all defined function inlinable by defauld?
I noticed that not in all of the examples on the playground the {-# INLINABLE myProgram #-} flag is used. Does the playground natively accept every function as template haskell? Why do some examples not need it?


text:
Committing a database to the ledger without storing it on the ledger?
The Cardano blockchain has no global state, this means that shared state needs to be introduced. Is there a design pattern that lets you commit big sets of data to the ledger without storing it? This while still preserving the ability to later retrieve/change the data via proofs?

Is this a legit question or did you just want to answer your own question? How/why would you want to commit big sets of data and not have them saved on the ledger? I'm not clear on what you mean by 'commit' without storing to ledger.

I wanted to share my knowledge, it is common on SE. I had this question a few weeks ago and did some research on it, wanted to document it for others. With 'commit' I mean: publicly fix the database in a verifiable manner. Example: If I store a hash of a number onchain, and you try to guess my number, I can later reveal that number, and compare your guess. I committed to the number via its hash and cannot change it.

On the topic of why I would want this? Since Cardano only has local state, it is hard to track things, like the number of tokens mint by certain policy. You might want this data onchain for other scripts to use (without the use of oracles). This allows you to introduce such data, its a general design pattern common in crypto.
The core idea of this is to use the Cardano blockchain not as a database, but as a ledger to check if things are done in a valid way.

You can use Merkle tree's for this! This is an inverted tree like data structure that uses hashes to create a root hash that is uniquely defined by its leafs, the leafs are the nodes in the lowest layer here (1). Thus, with this root hash, you can commit a big set of data by only storing the root hash on the ledger (it is just a byte string).
This data structure also allows you to construct a proof that can prove that a leaf is a member of a Merkle tree, given only its root hash and this proof. These proofs are maximally of size log(n) where n is the number of leafs in the tree. A proof that a leaf is in the tree consists of giving a list of hashes for each layer of the tree. The hashes are not arbitrary, for each layer the hash is chosen that is needed for the path of the leaf that is proven to go up the tree. To visualize this,

Here, the data set is represented by the Tₙ, where n is a letter in the range A - H. The hashes of these Tₙ are Hₙ (these are the leafs). We see for example that going up one layer in the graph combines H_C and H_D into the hash H_{CD}. This combining of paired hashes keeps going until the upper layer is reached, this is the root hash H_{ABCDEFGH}. Note that changing any leaf (swapping leafs or change underlying data T) will result in a different root hash. This is because changing the input of a hash function gives in an entirely different output.
Now, to prove that the red leaf is in the green root, you have to provide for each layer two things. The first thing is a hash of the sibling node that together with the leaf you try to prove goes up the tree. The second thing is the position of these hashes relative to each other, left, or right. So, the proof that T_D is in the dataset with root H_{ABCDEFGH} takes the form.
[left H_C, Left H_{AB}, right H_{EFGH}]

To verify this proof, you can combine the hashes while taking note of the hash order (left or right), and compare it to the root hash.
H_{ABCDEFGH}=Hash(Hash(H_{AB},Hash(H_C,Hash(T_D))),H_{EFGH})

To utilize this structure on the ledger and provide a way to update a leaf using plutus, consider storing the root hash in a datum. This datum represents the commitment to the dataset and should be locked at a script with at least the following logic.
To verifiably update say leaf H_i from state T_i to state T'_i, you provide the validator three things in a redeemer when spending the UTxO that holds the root hash datum. These are the old state of that leaf, a proof that this old state is a member of the tree, and, a new root hash H' that is derived from the updated tree (where the old state of T_i is replaced with T'_i).
The validator only needs to check two things to accept the new root hash as the representation of the newly updated dataset,

The old state T_i is a member of the old root.
Given the new root H' and the proof of step 1, this proofs that the new state T'_i is a member of H'.

If these conditions are met, it is safe to update the datum to hold the root hash of the new state. Note that any arbitrary extra logic can be added to this (like mandating that the new output is sent to the same script address). This protocol works since a proof never contains a hash that is derived from the member you need to proof. So, changing the leaf that is being proved, still makes the proof valid for a root hash that is derived with this new leaf. Any change to other leafs renders this proof invalid.

Some last words, this design pattern is pretty cool as it lets you convert storage requirements to computation requirements on the ledger. Do note that this comes at a cost, that is, it obscures the data availability of the dataset since it is captured only in a hash. If the beginning state is publicly published, the current state of the dataset can be derived in a decentralized way by traversing the chain and logging the transaction that changed the state of the chain. This is cumbersome, but worth it for large databases.
With the new Vasil feature of reference inputs coming up, this method opens the door to exciting solutions! This since you only have to provide/verify a log(n) proof to fetch a leaf to use in some other plutus script. A small disclaimer here, a dataset in one UTxO is not a concurrent solution, splitting it over multiple outputs may be desirable. Moreover, the length of the database is fixed (though you could set entries to null).
I hope you liked this in depth post! You can find an implementation of Merkle trees for plutus here (3).


text:
ScriptWitnessNotValidatingUTXOW while trying to mint NFT in preprod testnet
minting script
    "type": "all",
    "scripts":
    [
        {
            "type": "after",
            "slot": 155761
        },
        {
            "type": "sig",
            "keyHash": "e9ce8633aef95b632bfbffc12a83cc4c589132c46cd03f8dae146ec2"
        }

    ]
}

metadata-json-file
    "721": {
        "ca8fc6bf8d698d5752e6c700c8a5818c2abe5a17877121ae99604e24": {
            "cat": {
                "name": "Nikki",
                "image": ["ipfs://QmQQqHaitxGkzNTRCSxJxTU5JaVvSoGGxocBcU246BZA7M"],
                "mediaType": "image/png",
                "description": "remember when?",
                "files": [
                    {
                        "mediaType": "image/png",
                        "src": ["ipfs://QmQQqHaitxGkzNTRCSxJxTU5JaVvSoGGxocBcU246BZA7M"]
                    },
                    {
                        "mediaType": "image/png",
                        "src": ["ipfs://QmYCbn5Nj3Xq28QwDkerMBAXsLBDa26f1k8jruuKn5gzXn"]
                    }

                ],
                "type": "Nadan",
                "color": "white and brown"
            }
        }
    }
}

cardano-cli query tip --testnet-magic 1
{
    "block": 153845,
    "epoch": 19,
    "era": "Alonzo",
    "hash": "789909e77ba308c069b0e09809a6ec7508da0d2c0c474565caed2688afe3618e",
    "slot": 6674546,
    "syncProgress": "100.00"
}

command line variables
POLICYID=ca8fc6bf8d698d5752e6c700c8a5818c2abe5a17877121ae99604e24
TXIN="02a037b9649eb62f17549bf33114763568b59a4be20beba6132f7b996a0825e2#0"
TOKENNAME1="6e696b6b69"
POLICYSCRIPT="ppbl-nft-2.script"
MINTER=addr_test1vr5uap3n4mu4kcetl0luz25re3x93yfjc3kdq0ud4c2xassvq0wsd
METADATA_JSON_FILE="mynft.json"
RECIEVER=addr_test1qzdquurtx940tpyfgt7pu2h8zgrgfepf7quwcqqh3kmacd83z2naq8a2cltaqyxexml30wh77uyu3sll7feyp2nzqgnqfdpnsa

// transaction cardano-cli transaction build \ --alonzo-era \ --testnet-magic 1 \ --tx-in $TXIN \ --tx-out $RECIEVER+1500000+"1 $POLICYID.$TOKENNAME" \ --change-address $MINTER \ --mint "1 $POLICYID.$TOKENNAME" \ --minting-script-file ppbl-nft-2.script \ --metadata-json-file mynft.json \ --protocol-params-file protocol.json \ --out-file nft.raw
//transaction sign
cardano-cli transaction sign \
--signing-key-file payment.skey \
--testnet-magic 1 \
--tx-body-file nft.raw \
--out-file mint-nft.signed

//submit transaction
cardano-cli transaction submit \
--tx-file mint-nft.signed \
--testnet-magic 1

ERROR
Command failed: transaction submit  Error: Error while submitting tx: ShelleyTxValidationError ShelleyBasedEraAlonzo (ApplyTxError [UtxowFailure (WrappedShelleyEraFailure (ScriptWitnessNotValidatingUTXOW (fromList [ScriptHash "c867c502e249d681b35a8df2e3df5e58ec2c16d3df445429484a1793"])))])

You're missing the --invalid-before flag when building the transaction. It sets the lower bound of the transaction's validity interval, which is required for the script to determine whether the interval range is greater than slot 155761. You must use a slot that is lower than the current slot.

You are using,
{
    "type": "after",
    "slot": 155761
}

while the current slot on preprod is ~154042. This policy allows using it only after slot 155761, for more info see (1). Also make sure that,
cardano-cli address key-hash --payment-verification-key-file payment.skey

is equal to e9ce8633aef95b632bfbffc12a83cc4c589132c46cd03f8dae146ec2.

i changes the script ``` {
"type": "all",
"scripts":
[
{
"type": "after",
"slot": 6702243
},
{
"type": "sig",
"keyHash": "e9ce8633aef95b632bfbffc12a83cc4c589132c46cd03f8dae146ec2"
}
]

}``` and key hash is also the same still same error

Hmm, that's weird, I also think I had the slot of preprod wrong (your query is correct).

Can you use the --invalid-after to make the transaction valid even if it is send before the after slot?

--alonzo-era \
--testnet-magic 1 \
--tx-in $TXIN \
--tx-out $RECIEVER+1500000+"1 $POLICYID.$TOKENNAME" \
--change-address $MINTER \
--mint "1 $POLICYID.$TOKENNAME" \
--minting-script-file ppbl-nft-2.script \
--invalid-hereafter 6753799 \
--metadata-json-file mynft.json \
--protocol-params-file protocol.json \
--out-file nft.raw```

still same error


text:
NODE_CONFIG: unbound variable error trying to run inputoutput/cardano-node:1.35.3-new docker container [SOLVED]
I have been trying to set up a docker container running the latest release of Cardano Node to be able to spin up a stake pool operation on Pre-Prod testnet.
I tried using the following command to set this up:
sudo docker run --user 0 -e NETWORK=preprod -v cardano-bpnode-ipc:/ipc -v cardano-bpnode-data:/data -e DATA_DIR=/data -e CARDANO_NODE_SOCKET_PATH=/ipc/node.socket inputoutput/cardano-node:1.35.3-new

NB: I had to force the use of user 0 as a previous issue was that docker was unable to get permissions to create the files within the container on the volumes created for it.
When I tried to run this command to start running my Node I got the following error:
/nix/store/srm7rn76x2db1a6xg0bihz6vngz5a7km-entrypoint/bin/entrypoint: line 228: NODE_CONFIG: unbound variable
I have been attempting to ask on the IOHK Discord for advice on how to handle this error, and have been explicitly referred to Cardano Stackexchange to seek assistance.
So, I am posting the request for assistance here, as I cannot find any mention of this error anywhere else online.
I am hoping someone will be able to point me in the right direction to be able to actually spin up my container.
In fact, I wish to spin up 3. To learn SPO configuration and registration procedures.
Thank you kindly in advance for any support with this issue.

SOLUTION - Requires replacing NETWORK with ENVIRONMENT on the list of options.


text:
Are transaction witnesses stored on the blockchain?
According to Cardano's ledger spec (page 26), the purpose of witnessing is to make sure that the intended action is authorized by the holder
of the signing key, providing replay protection as a consequence. For example, the signature of a transaction and a Plutus script are both witnesses.
Witnesses are used by block producers to validate transactions. After a transaction is validated by a block producer, it will be included in a new block, which is then propagated to the network, and verified by the rest of pools. Obviously, witnesses are required as part of the block validation. However, theoretically, once a transaction is validated and included in a block, is there a strong reason to keep the witnesses in the block? Can witnesses be discarded after being used in transaction validation in order to reduce the size of the blockchain? What does the lifecycle of witnesses look like in Cardano?

A witness is the public key of the signer and the signature of the txbody using that public key. That is attached to the submitted transaction. It is not possible to query witnesses from db-sync at the moment, but the raw CBOR of the transaction submitted contains all witnesses included in the transaction.

Thanks Samuel. If I understand correctly, your answer confirms that witnesses only live inside transaction bodies, but not in blocks. This raises a question of how we can find the source code of a Plutus program, which is considered as a witness. One simple solution I can think of is to build a service that record all transactions on the network, including their witnesses, so a script address could be indexed to a Plutus script easily. I am happy to hear if there is a plan or solution proposed by IOG or the community.

Blocks are made up of signed transactions. Signed transactions are the raw transaction body + the witnesses for that transaction. cardano-db-sync does not expose witnesses, but the blockchain does store them.


text:
How to estimate execution steps and memory units for a Plutus script?
Question
Is there a tool/API that can calculate the number of steps and max consumed memory units for a Plutus script, given all necessary inputs, e.g. datum, redeemer, and script context?
I could be wrong, but it seems like plutus-core provides an evaluation tool that can probably output something useful. However, I don't know how to use the tool. Any instructions of its usage will be extremely helpful.
Background
I am looking for such tool/API to calculate the min fee required for transactions that consume UTxOs locked in Plutus scripts while not depending on Plutus Application Backend (PAB), because I am building a standalone Python library through which users can write entire off-chain codes in Python. It is fine to have plutus-core in the runtime environment, but it is not ideal if I need to write Haskell code or use PAB to solve this problem.
Related questions
How to calculate fees for Plutus Smart Contract?  The answer linked to a fee calculator, but this is not what I am looking for, because the calculator still requires users to provide the number of execution steps and memory units.
How to calculate fees in Plutus It is basically asking the same question, except that usage of PAB is allowed.

Looks like Ogmios just released a new feature that solves this exact problem. Basically, users can now evaluate a transaction through Ogmios's API EvaluateTx and get accurate execution steps and memory from the response.

You can also use the build command in cardano-cli. Specify the --calculate-plutus-script-cost flag and you will get a JSON object formatted as follows:
{
"executionUnits": {
"memory": 1700,
"steps": 476468
},
"lovelaceCost": 133,
"scriptHash": "67f33146617a5e61936081db3b2117cbf59bd2123748f58ac9678656"
}


text:
Are negative values valid quantities in native assets?
In Cardano's Alonzo CDDL (Concise Data Definition Language) specification, it seems that the value of an asset could be negative. Is it correct?
If the above assumption is correct, I am wondering how will the ledger work in the following scenario:
Alice has a native asset named "X" with negative quantity of -1000. Then, she send this asset X=-1000 to Bob, who has the same asset but a positive quantity of 2000. If this transaction is valid and successfully included in the blockchain, does it mean Bob will end up having only 1000 token X (2000-1000=1000) left?
It sounds weird that Alice could burn anybody's token by simply sending a negative quantity of tokens. If I have to guess an explanation for this scenario, it could be that Alice is granted with the power of "burning" by the token issuer, therefore she could burn anybody's token by sending negative values to their addresses. Therefore, token issuers should be extremely cautious about minting and issuing negative quantity tokens to any third party.
Update:
After taking a careful look at the ledger spec, the quantity of an asset can only be uint, specified as multiasset<uint> in this line. Only the minting amount could be negative, specified as multiasset in this line. This also verified Andy's answer below.

The amount of an asset is allowed to be negative because, in the minting field of a transaction, burning tokens is defined as negative minting. This does not mean that you can send negative amounts to an address i.e. that a UTxO is allowed to contain a negative amount of assets. Allowing this would effectively mean that anybody could print tokens by sending a positive amount and simultaneously a negative amount such that in sum no token apparently would be minted. It is clear that this cannot be true.


text:
What is the purpose of use using Cardano-graphql & hasura in the same stack?
I'm in the process of writing some software that will connect to the Cardano networking such as signing transactions & querying historical chain data. During my search for a solution I came across Hasura, which I planned to hook up postgres (using cardano-db-sync as well) to.
Later down the road I found Cardano-graphql in the inputoutput github account & noticed in the reference docker file here that the developers have also chosen to include Hasrua which is also a graphql api.
What is the purpose of this? Do I need both? What is the benifit of using cardano-graphql & hasura as shown in the docker-compose.yml file.

Hasura is a cloud service where you can deploy cardano-graphql in a very easy and straight forward way, since it is oriented to graphql APIs.
So no, you don't need both.
cardano-graphql is very expensive to use in matter of resources so depending on the type of queries you want to do to the blockchain, maybe you need a service like Blockfrost.


text:
Yoroi Chrome plugin wallet is not syncing
My Yoroi wallet is not syncing even after running Resync Wallet. It has been many days and the wallet seems to not have made any progress. Is complete restoration the only way out of this?

This is probably a problem with Emurgo servers. You might want to reach out to their support at their website.
Scam warning: never, never, NEVER trust anyone on social media, always go to the Yoroi official site to reach their suport.


text:
How to check wallet balance using cardano cli?
How does Dedalus know what is my balance on given wallets? Is there a way I can do the same thing using cardano-cli or cardano-wallet?
Edit:
I have found Wallet UTXO Distribution screen that:

When you receive ada to your Daedalus wallet, it simply means Daedalus has identified a UTXO that can be spent with the keys managed by your wallet... Daedalus determines your balance by scanning the Cardano blockchain and aggregating the value of any UTXO the wallet is able to spend with the keys associated to your wallet.

Does that mean that Daedalus checks (has access to keys so can validate if the address belongs to a wallet(?)) all transactions and just sums up the balance?
And given that it's true I would need to somehow scan my copy of the blockchain to get the same information?

Yes, you can query balances with both cardano-cli and cardano-wallet. The developer portal shows this for different languages, but you can also read out the raw command-line query there.
cardano-cli: https://developers.cardano.org/docs/integrate-cardano/listening-for-payments-cli#query-utxo
cardano-wallet: https://developers.cardano.org/docs/integrate-cardano/listening-for-payments-wallet#retrieve-wallet-balance


text:
Can't connect cardano-wallet with the node on testnet: blockedIndefinitelyException = thread blocked indefinitely in an STM transaction
I'm following this guide https://developers.cardano.org/docs/integrate-cardano/creating-wallet-faucet#creating-a-wallet-with-cardano-wallet
to learn about Cardano infra.
I have cardano-node running on port 3001 using this command
    ./cardano-node run \
   --topology ./configuration/cardano/testnet-topology.json \
   --database-path ./configuration/db \
   --socket-path ./configuration/db/node.socket \
   --host-addr 127.0.0.1 \
   --port 3001 \
   --config ./configuration/cardano/testnet-config.json

I used the configs that are suggested in the guide. Testnet magic is 1097911063.
I was able to succesfully generate wallets with cardano-cli and create/sign/submit transactions. Now I'm trying to make cardano-wallet work but I can't connect to the node. Here is my command:

    cardano-wallet serve \
    --port 1337 \
    --testnet configuration/cardano/testnet-byron-genesis.json \
    --database wallets/db \
    --node-socket $CARDANO_NODE_SOCKET_PATH

This is what I see in the wallet logs before it shots down:
[cardano-wallet.main:Info:4] [2021-08-20 06:07:38.48 UTC] Running as v2021-08-11 (git revision: e870e5f05e05e22e4de01672b0e7243b2f907153) on x86_64-darwin
[cardano-wallet.main:Info:4] [2021-08-20 06:07:38.48 UTC] Command line: /usr/local/bin/cardano-wallet serve --port 1337 --testnet configuration/cardano/testnet-byron-genesis.json --database wallets/db --node-socket /Users/[hidden]/[hidden]/cardano-node/configuration/db/node.socket
[cardano-wallet.main:Debug:4] [2021-08-20 06:07:38.48 UTC] ServeArgs {_hostPreference = Host "127.0.0.1", _listen = ListenOnPort 1337, _tlsConfig = Nothing, _nodeSocket = CardanoNodeConn "/Users/[hidden]/cardano-node/configuration/db/node.socket", _networkConfiguration = TestnetConfig "configuration/cardano/testnet-byron-genesis.json", _database = Just "wallets/db", _syncTolerance = SyncTolerance 300s, _enableShutdownHandler = False, _poolMetadataSourceOpt = Nothing, _tokenMetadataSourceOpt = Nothing, _logging = LoggingOptions {loggingMinSeverity = Debug, loggingTracers = Tracers {applicationTracer = Const (Just Info), apiServerTracer = Const (Just Info), tokenMetadataTracer = Const (Just Info), walletEngineTracer = Const (Just Info), walletDbTracer = Const (Just Info), poolsEngineTracer = Const (Just Info), poolsDbTracer = Const (Just Info), ntpClientTracer = Const (Just Info), networkTracer = Const (Just Info)}, loggingTracersDoc = Nothing}}
[cardano-wallet.main:Info:4] [2021-08-20 06:07:38.50 UTC] Wallet databases: Using directory: wallets/db
[cardano-wallet.application:Info:4] [2021-08-20 06:07:38.50 UTC] Wallet backend server starting. Using /Users/[hidden]/Dev/cardano-node/configuration/db/node.socket.
[cardano-wallet.application:Info:4] [2021-08-20 06:07:38.50 UTC] Node is Haskell Node on testnet (1097911063).
[cardano-wallet.token-metadata:Notice:4] [2021-08-20 06:07:38.51 UTC] No token metadata server is configured.
[cardano-wallet.token-metadata:Notice:4] [2021-08-20 06:07:38.51 UTC] No token metadata server is configured.
[cardano-wallet.token-metadata:Notice:4] [2021-08-20 06:07:38.51 UTC] No token metadata server is configured.
[cardano-wallet.token-metadata:Notice:4] [2021-08-20 06:07:38.51 UTC] No token metadata server is configured.
[cardano-wallet.pools-db:Info:4] [2021-08-20 06:07:38.51 UTC] Starting connection pool for wallets/db/stake-pools.sqlite
[cardano-wallet.main:Info:4] [2021-08-20 06:07:38.51 UTC] Wallet backend server listening on http://127.0.0.1:1337/
[cardano-wallet.pools-engine:Info:36] [2021-08-20 06:07:38.53 UTC] Chain following starting. Requesting intersection using 221 checkpoints, the latest being 0ac9b1b6<-[107538a4-213041#211999]
[cardano-wallet.network:Warning:14] [2021-08-20 06:07:38.57 UTC] Connection lost with the node. writev: resource vanished (Broken pipe)
[cardano-wallet.pools-db:Info:4] [2021-08-20 06:07:38.60 UTC] Stopping database connection pool wallets/db/stake-pools.sqlite
[cardano-wallet.pools-db:Info:4] [2021-08-20 06:07:38.60 UTC] Closing single database connection (wallets/db/stake-pools.sqlite)
[cardano-wallet.pools-db:Info:4] [2021-08-20 06:07:38.60 UTC] Closing single database connection (wallets/db/stake-pools.sqlite)
[cardano-wallet.main:Debug:4] [2021-08-20 06:07:38.62 UTC] Logging shutdown.
cardano-wallet: ExceptionInLinkedThread (ThreadId 12) (BlockedIndefinitely {blockedIndefinitelyCallStack = [("wrapBlockedIndefinitely",SrcLoc {srcLocPackage = "io-classes-0.2.0.0-8vqCa9RxYeSIAHkGOEppTU", srcLocModule = "Control.Monad.Class.MonadSTM", srcLocFile = "src/Control/Monad/Class/MonadSTM.hs", srcLocStartLine = 296, srcLocStartCol = 16, srcLocEndLine = 296, srcLocEndCol = 39}),("atomically",SrcLoc {srcLocPackage = "cardano-wallet-core-2021.8.11-9CfWGxilOndlEXObu7PRN", srcLocModule = "Ouroboros.Network.Client.Wallet", srcLocFile = "src/Ouroboros/Network/Client/Wallet.hs", srcLocStartLine = 628, srcLocStartCol = 5, srcLocEndLine = 628, srcLocEndCol = 32})], blockedIndefinitelyException = thread blocked indefinitely in an STM transaction})

And this is cardano-node logs
[MacBook-:cardano.node.LocalErrorPolicy:Error:63] [2021-08-20 06:35:34.08 UTC] IP LocalAddress "" ErrorPolicyUnhandledApplicationException DecoderFailure (LocalStateQuery HardForkBlock (': * ByronBlock (': * (ShelleyBlock (ShelleyEra StandardCrypto)) (': * (ShelleyBlock (ShelleyMAEra 'Allegra StandardCrypto)) (': * (ShelleyBlock (ShelleyMAEra 'Mary StandardCrypto)) ('[] *))))) Query (HardForkBlock (': * ByronBlock (': * (ShelleyBlock (ShelleyEra StandardCrypto)) (': * (ShelleyBlock (ShelleyMAEra 'Allegra StandardCrypto)) (': * (ShelleyBlock (ShelleyMAEra 'Mary StandardCrypto)) ('[] *))))))) ClientAgency TokAcquired) (DeserialiseFailure 7 "EraIndex: invalid index 4")
[MacBook-:cardano.node.LocalErrorPolicy:Error:63] [2021-08-20 06:35:35.15 UTC] IP LocalAddress "" ErrorPolicyUnhandledApplicationException (MuxError (MuxIOException writev: resource vanished (Broken pipe)) "(sendAll errored)")
[MacBook-:cardano.node.LocalErrorPolicy:Error:63] [2021-08-20 06:35:36.15 UTC] IP LocalAddress "" ErrorPolicyUnhandledApplicationException (MuxError MuxBearerClosed "<socket: 34> closed when reading data, waiting on next header True")
[MacBook-:cardano.node.ChainDB:Notice:33] [2021-08-20 06:37:24.22 UTC] Chain extended, new tip: 8900454c4bb70632d558d70421c2c25e12cc0b448ace065f61f14df882f048f4 at slot 35072228

Can anyone help?

Did you find any solution? I am facing a similar error.

Could you try running the wallet with the testnet-alonzo genesis file?

I have a similar problem but on the main net. https://cardano.stackexchange.com/questions/11164/unable-to-connect-wallet-to-node-on-mainnet

I am unsure if this will fix your issue, but try running the wallet with the Alonzo genesis file instead of Byron?


text:
Is the stake pool fixed fee cost once per epoch or per every block won?
Is the stake pool fixed fee cost, or min fee currently 340 ada, once per epoch, or once per block won?

The fixed fee and percentage fee are calculated once per epoch if the pool mints at least one block.
These fees are taken out of the total rewards amount that the pool earned that epoch, and the remainder is distributed to all delegates at amounts proportional to their stake within that pool.

Almost, the remainder is still deducted by the dynamic/ margin fees if those are set to a percent greater than 0 before the delegates receive their proportional rewards.


text:
Sandbox error when running nix build on macOS
I'm trying to get the exercises for week 1 of the plutus pioneer program working. I've installed nix and have set the IOHK caches.
When I try to run nix build -f default.nix plutus.haskell.packages.plutus-core in the plutus repo I get the following error:
 ❮❮❮ nix build -f default.nix plutus.haskell.packages.plutus-core
trace: To materialize project.plan-nix for Agda entirely, pass a writable path as the `materialized` argument and run the 'updateMaterialized' script in 'passthru'.
builder for '/nix/store/gpkkaj0mcs6wxaknfjm0jh389x8l4gwb-plutus-core-0.1.0.0-coverage-report.drv' failed with exit code 65; last 1 log lines:
  sandbox-exec: pattern serialization length 71571 exceeds maximum (65535)
[0 built (1 failed), 0.0 MiB DL]

I'm running this command on commit ea0ca4e9f9821a9dbfc5255fa0f42b6f2b3887c4.
I've looked through the plutus community docs but haven't found any mention of this error.
Has anyone run into this before? What does this mean? Is there a known fix?
EDIT: this also happens on master at commit 8ce0d58c0a169f4c8a1104757502f342e750c863

Figured it out. I'm on MacOS and some docs that I followed mentioned turning on the sandbox feature by adding
sandbox = true
extra-sandbox-paths = /System/Library/Frameworks /System/Library/PrivateFrameworks /usr/lib /private/tmp /private/var/tmp /usr/bin/env

to /etc/nix/nix.conf.
Removing these two lines eliminated the error.

I am in the Cohort 3, and following multiple guides as well, macOS i7 Monterey.  Do you still recommend removing those?  I see here it recommends adding, but no others do... https://github.com/input-output-hk/plutus-apps#nix-on-macos . I had issues building the client.

I found this /etc/nix/nix.conf to work for my macOS i7 Monterey (v12.1).
It was recommended to turn the sandbox FALSE because 'not recommended' per Ref #1 below.
    build-users-group = nixbld

    substituters        = https://hydra.iohk.io https://iohk.cachix.org https://cache.nixos.org/
    trusted-public-keys = hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ= iohk.cachix.org-1:DpRUyj7h7V830dp/i6Nti+NEO2/nhblbov/8MW7Rqoo= cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=volume

    sandbox = false
    extra-sandbox-paths = /System/Library/Frameworks /System/Library/PrivateFrameworks /usr/lib /private/tmp /private/var/tmp /usr/bin/env
    experimental-features = nix-command
    extra-experimental-features = flakes

References:

CSE, @angerman, on macOS Monterey i7, what is the best nix.conf file to use?
Github: Status of macOS support in Nixpkgs

https://github.com/Til-D/cardano-plutus
https://github.com/renzwo/cardano-plutus-apps-install-m1/blob/main/README.md

Answer could be improved by following these guidelines: How to reference material written by others

tracked down reference source and updated per comment.

Well done, you get a whole upvote from me!  Sorry I can't do more.

on debian distro, it works fine with all the details mentioned in developers forum. I built it on VS code debian distro with WSL2.  its tricky as sometime u need to execute chmod command as it wont let u access it.


text:
nix-shell stuck on Building library for hnix
I'm just gonna post a problem that I've been experiencing for a few days (and having a hard time searching for the answer on the internet) and the solution, so that future questions can refer to this solution.
Hardware
I'm using Macbook Pro Intel 2020, macOS Monterrey Beta 6
Problem
So the problem was when I was running nix-shell in the plutus repository for the first time, and after downloading all the dependencies, the nix-shell stuck at Building library for hnix-#.#.# and [1 of 50] Compiling Nix.Atoms.
What I did before compiling was installing Nix from the official documentation https://nixos.org/download.html
I also did configure the binary cache from https://github.com/input-output-hk/plutus#iohk-binary-cache
Also tried to start with and without https://github.com/input-output-hk/plutus#nix-on-macos
All to no success, still stuck at Building library for hnix-#.#.# and [1 of 50] Compiling Nix.Atoms

can I ask how you installed nix-darwin ?
I have the same issue as you had (Building library for hnix-#.#.# and [1 of 50] Compiling Nix.Atoms.)
I get this error when I try to install it: ~ % nix-build https://github.com/LnL7/nix-darwin/archive/master.tar.gz -A installer
./result/bin/darwin-installer error: file 'nixpkgs' was not found in the Nix search path (add it using $NIX_PATH or -I), at /nix/store/v1rhxl3ln24zlx8dbmhcrwbwydfmzj6a-master.tar.gz/default.nix:1:13
zsh: no such file or directory: ./result/bin/darwin-installer

So the solution was simply to install nix-darwin
https://github.com/LnL7/nix-darwin
simply follow the instruction on the github page above, and now I can access my nix-shell

What is nix-darwin and why does installing it fix this issue?

@runeks it's like a driver or plugin to make nix compatible with macos

where did read this? As far as I can see it's a way to configure macOS using a declarative configuration (similar to NixOS).
I don't see the connection between this and fixing nix-build hanging when building hnix.

I've installed nix-darwin but still have the same behavior.

@DanielCukier which terminal application and CPU architecture do you use? On my MacBook Pro M1, I just experienced the compilation of Nix.Atoms hang in iTerm2 running with Rosetta emulation (so that the command arch run in this terminal outputs i386). Then I tried to compile using the built-in Terminal app without Rosetta emulation (so that the command arch run in this terminal outputs arm64) and this successfully compiled Nix.Atoms. Given that OP is on Intel hardware it may, somehow, be the terminal application that causes the hang...

I had the same problem on my Mac M1 Pro and my issue had to do with my ghc installation. I had installed version 8.10.7 through nix-darwin and when I switched from that installation to the same version of ghc installed using ghcup the problem disappeared (as a side note, when you're in the nix-shell, make sure you're using the shell's version of ghc and not your own, should be 8.10.4.20210212).
If that still doesn't solve your problem, I would suggest downloading the repo that broke and try running cabal build --verbose inside of it, that's how I figured out what the problem was.
Check what the src is of the nix derivation that breaks:
$ nix show-derivation /nix/store/kkjbrl5bbpmirwfhhs89k1q7ahm7zqih-hnix-lib-hnix-0.14.0.5.drv

{
   ...
   "src": "/nix/store/ymkyz2z612zsi183x5mjqbn65vy1a6li-hnix-0.14.0.5.tar.gz",
   ...
}

The problem I had was that the cabal build gave me a Clang error due to some missing library (libz).


text:
cardano-cli: Network.Socket.connect: <socket: 11>: does not exist
I'm at this part of the docs. The node is running (left terminal in the image below), but now I'm trying to query the blockchain from another terminal and receive the error:
cardano-cli: Network.Socket.connect: <socket: 11>: does not exist (No such file or directory)

I'm running the cardano node on a windows laptop inside an ubuntu terminal that I downloaded from the windows store (as recommended in the cardano docs here):

I think that maybe the two Ubuntu terminals are completely independent from each other and that's why the right terminal can't find the socket? I tried to install the cardano node on a raspberry Pi 4 also, so that I have a native environment, but the raspberry was just to slow for it...
EDIT:
I have set the socket path now like this at the bottom of my ~/.bashrc file:

then restarted the terminal, but still I receive the same error.

have you mentioned the socket location when starting the node?

I have set the same socket path as I used in the cardano-node run command:
export CARDANO_NODE_SOCKET_PATH="~/cardano-src/cardano-node/db/node.socket"
My cardano-node run command looks like this:
cardano-node run --topology ~/cardano-src/cardano-node/config-files/testnet-topology.json --database-path ~/cardano-src/cardano-node/db --socket-path ~/cardano-src/cardano-node/db/node.socket --host-addr 127.0.0.1 --port 3001 --config ~/cardano-src/cardano-node/config-files/testnet-config.json
and the query command: cardano-cli query tip --testnet-magic 1097911063

when I run echo $CARDANO_NODE_SOCKET_PATH in my terminal, it gives me the correct path back: ~/cardano-src/cardano-node/db/node.socket

But when I run ls -al $CARDANO_NODE_SOCKET_PATH I receive the error: ls: cannot access '~/cardano-src/cardano-node/db/node.socket': No such file or directory

Alright, the problem were the quotation marks. In the docs they use quotation marks too:
export CARDANO_NODE_SOCKET_PATH="/home/user/cardano/db/node.socket"
But here the guy didn't use quotation marks: https://forum.cardano.org/t/cardano-cli-network-socket-connect-socket-11-does-not-exist/38987/7
So I tried it without it in my ~/.bashrc file:

and it worked after re-starting the cardano-node and the second terminal:

I have found the solution for myself on a Coincashew tutorial.
https://www.coincashew.com/coins/overview-ada/guide-how-to-build-a-haskell-stakepool-node#2-build-the-node-from-source-code
Basically i executed this:
echo export CARDANO_NODE_SOCKET_PATH="$NODE_HOME/db/socket" >> $HOME/.bashrc
source $HOME/.bashrc

That rewired the node path to socket (on the place of node.socket). Don't know what is the real difference but this way worked while the 'node.socket' path don't.

I was having this issue while trying to get the Plutus PAB to connect to the node. I tried lots of solutions but didn't get it to work until I changed the "testnet/node.sock" in the config (testnet/pab-config.yml). Perhaps it needed to be relative?
plutus-apps/plutus-pab/test-node/testnet/pab-config.yml
...
nodeServerConfig:
  pscSocketPath: testnet/node.sock
...

When you are specifying CARDANO_NODE_SOCKET_PATH in these formats:
"$NODE_HOME/db/socket" you must use double quotes around it
~/cardano/db/node.socket you don't need to give double quotes around it


text:
How to prevent economic DOS attacks against Plutus contracts
Many people wrote about the eUTXO model and the benefits it brings compared to Ethereum.
However, eUTXO also comes with some challenges.
In particular, eUTXO is susceptible to "economic denial of service (DOS) attacks".
Let me give you an example of an economic DOS attack.
Consider the following NFT-auction from the Plutus pioneer program: https://plutus-pioneer-program.readthedocs.io/en/latest/pioneer/week1.html
This contract is a simple auction where anybody can bid for an NFT until a specified deadline has passed.
However, this contract is vulnerable to an economic DOS attack where a malicious bidder creates a sequence of low bids that prevent other people from placing their bids (e.g. 0.001 ADA, 0.002 ADA and so on).
Such an attack is possible because each eUTXO can be spent only once, and if the attacker is faster than you, then you fail to place your bid on the Cardano blockchain.
It requires some technical sophistication to execute an economic DOS attack, but an average (non-technical) wallet-user cannot defend against it.
Although economic DOS attacks are also possible on Ethereum, it is much harder to execute them successfully within Ethereum's account model.
See the following paper for more details about economic DOS attacks:
https://docs.google.com/document/u/0/d/12atK0oEME0y1GHo_HmqhrcZ3pQeEqB_0tFKknhsjsLY/mobilebasic
So my question is:
(1.) How would you implement a Plutus-NFT-auction that defends against economic DOS attacks and (2.) how would you generalize a defense-pattern for other Plutus-contracts?

These types of attacks are inherent to the auction model and are not dependent on the technology used. To protect against these, auctions have a minimum bid increase. Other solutions would be (i) a whitelist of known wallets making sure that every participants has at most one wallet, or (ii) bidding fees making DoS attacks expensive.
If you want to run an auction without identity control opened to the general public, minimum bid increases would be the way to go, in my opinion.

My point is that those attacks are much easier with eUTXO/Cardano than on Solidity. It is incredibly expensive to "stall" the Ethereum-mainnet for multiple blocks, whereas it is much cheaper to re-generate a single Cardano-UTXO over multiple blocks. So the defense becomes more important because the attack-tresholds are lower.

Minimum bid increases are doable, but I still find it problematic if you compare it with Ethereum. I strongly believe that there should be a more general solution which increases the cost of conducting DOS attacks. Those attacks will always be theoretically possible, but we need to think about the cost of performing the attacks.

Many of the people complaining about the UTxO model only think that Ethereum has less problems because they don't understand what happens there behind the scenes. I personally think that the issues of Ethereum are unfixable. The fact that you can write your question above shows how transparent the Cardano model is and how it allows developers to reason about it and think about what could go wrong and what can be done about it. The only way to prevent DoS in open networks is to make them expensive or difficult. UTxO are not more vulnerable than other models.

I am definitely not a chain maximalist since different models have different tradeoffs. I would not claim that Ethereum is better, but I am interested in this particular concurrency-attack.

One important thing to consider is the 'why'. What does an attacker gain from such an attack? Blocking other people from placing a bid doesn't gain the attacker anything. The attacker will just pay fees each block. So while this is theoretically possible, it's not worth it. At least not in your example.

He would gain by winning the auction when the deadline is reached.

You are right, you would need a pretty valuable NFT to make this attack profitable. Nevertheless, the attack would be much cheaper than a comparable attack on EVM-chains. Moreover, the NFT auction is just one example of the larger problem.

@Jey This class of attack, contention of a shared resource, is something I believe can only happen on a UTxO chain. So I believe it's not correct to say that "These types of attacks are inherent to the auction model and are not dependent on the technology used." Within a global-state system like the EVM, nearly an entire block could be filled up with bids to a particular contract and it still wouldn't prevent someone else from posting a bid. No whitelist system or bidding fee would be necessary.

One solution as proposed by Minswap and others are batching bots. Basically you split the bidding process in two steps. First transaction is a b as tch request to add your bid to the contract. Batching bots will compete to collect as many batch requests as possible and construct the actual bidding transaction. Their incentive is that they get a small fee for each processed batch request. Anyone can run auch a bot.

@Xiaofei This resolves the concurrency issue but does not protect agains DoS attacks as a malicious user could monopolise the bottleneck UTxO by continuously batching only his requests. @ Maximilian You have a point here but only if you don't take Ethereum's flaws into account. I think Ethereum trades its concurrency model for the MEV issue which is at least as bad. It is like a rug that is too large to fit into a room. Cardano and Ethereum each pull the rug to fit into a different corner.

@jey multiple batchers will compete to get their transactions on the block. Stake pools have an incentive to append large transactions to the block to increase the reward pool, so they'd prefer the honest batcher's transaction bundle over the other.

@Xiaofei Very good point! I think this is the answer to the question. If stake pools have an incentive to choose the honest batches, the DoS attack problem is solved.

I can think of a different way to structure the contract to avoid this attack.
If you allow all the bidders to lock up their funds at the same time, in separate UTxOs, the auctioneer could just choose which to accept when the deadline has past. This works in Plutus because you can redeem multiple datums in a single transaction, and have the validators check that the other UTxO is being spent, i.e. the PickWinner redemption path for a Auction datum would requires a Bid datum get redeemed as well, and vice-versa.
And say someone wants to update their bid, the Bid datum would have a redeemer of Update, otherwise your funds are locked until after some grace-period has passed.
This might come with some drawbacks, like the opportunity cost of all the losing bids being locked up, but I can think of ways to minimize those pain. In many cases, it seems like a reasonable cost to pay regardless.

People are talking about how order-book style DEXs are going to be more popular on Cardano because it fits the UTxO model better than the Ethereum accounts model. It would work similarly to what I just explained, however a DEX has a Many-to-Many market, unlike an auction which is Many-to-One. So a DEX is a little more difficult to architect than an auction.

Thanks for your detailed answer. I see several drawbacks with separate UTXOs. Firstly, the need of longer locking periods. Secondly, the highest bider does not automatically win, which might lead to more corruption. Sure, all of this can be solved, but I don‘t know whether all those eUTXO troubles are worth the effort.

I don't see the eUTxO model as a problem to be solved. I see it as a way to move the complexity of safety to a lower level. There have been billions of dollars lost in Solidity contracts that could have been prevented with the restrictions Plutus has. And those Solidity contracts aren't less complex, Solidity just has a lower barrier to entry to Plutus. Best of all, it gives an dApp developer options.

I agree that Solidity has too many bugs right now, but those can be solved. For example, reentrancy bugs can be prevented with compiler-inserted locks, although those locks have some gas-cost-overhead. For Plutus, however, we still need to ask the feasibility question: Is it even feasible to build an atomically composable DeFi-ecosystem with Plutus? I mean not only a DEX, but a composition of complex protocols like flash-loans

One more sidenote: Just because someone like SundaeSwap has a workaround for the concurrency-problem does not mean that the problem is solved. In contrast, the following "Scooper model" questions the ability of eUTXO to run a truly decentralized DEX without any off-chain-sequencer or sidechain: https://sundaeswap-finance.medium.com/sundaeswap-labs-presents-the-scooper-model-678d6054318d

"Is it even feasible to build an atomically composable DeFi-ecosystem with Plutus?" Oh. Absolutely. All the smart contracts I've looked at are compositions of multiple scripts. Plutus actually is great for composition.

I'm familiar with SundaeSwap's proposed architecture. I hope it meets their needs. From a first principles perspective I don't get this allergy to "off-chain-sequencer or sidechain". Ethereum is expensive, so they're looking for layer 2 solutions. I'm excited for those. I'm excited for Cardano to have them too. Luckily the Cardano devs took the usefulness of layer 2, sidechannels, and side chains into account when designing the system. Sounds like we're getting Hydra in the Spring. That's pretty soon. I know there is an arms race going on within DeFi, but I'm hoping for sustainable solutions.

I agree that layer 2 solutions are necessary, however this should not come at the cost of increased centralization. If SundaeSwap is forced to run a semi-centralized sequencer because of eUTXO-limitations, then this is a cause for concern. Remember that SundaeSwap's sequencer is not even a layer 2 solution, instead it is a traditional webservice that works around their concurrency problems.

Yeah. For sure, there are trade-offs. The blockchain is an awesome tool, but just because we have it doesn't mean that everything needs be completely decentralized to achieve a useful/compelling product. On the other hand, SundaeSwap's model might fail due to too much centralization/bad game theory, and then we can learn from it. Still lots to learn.

In my view, a good layer 2 solution should provide not only decentralization, but also the capability of running a smart contract forever, without any monitoring or additional infrastructure. For example, If I deploy a smart contract on a layer 2 solution, then I don't want to run my own sequencing-services, and neither do I want to incentivize other actors to run sequencing-services for me. Of course there might be solutions for decentralized sequencing, but I wonder what research the Cardano-team has done during the last 5 years if they have not even thought about basic eUTXO-sequencing.

I think it boils down to the concurrency issue that's been floating around recently. When that's solved (which some projects claim they did), this problem goes away.

Yes it is related to the concurrency issue, but it's not exactly the same. For example, I could imagine a DEX that solved the regular concurrency issue with a decentralized auction-order-book, but is still vulnerable to economic DOS attacks within its order-book.

How would you implement a Plutus-NFT-auction that defends against
economic DOS attacks?

My approach is a little bit complex, since it involves thinking about the problem in a very different way, so sorry for that.
Instead of having a unique UTxO to handle bids, you could create an "account" script. So each user that want's to be part of an auction would need to create an "account", sending the bid value (e.g. 100 ADA) or the auction value (e.g. random NFT) to this account address (creating a new UTxO).
The datum would also be important, since we don't have a way of looking at the value and knowing if it's an auction or a bid and, if it is a bid, we don't know what auction is it bidding on. Therefore the datum could hold a special data type that, if it's an auction, should indicate what is being auctioned and what the deadline is and, if it's a bid, should indicate the value being offered and the auction which it's part of.
Example
data AccountDatum = Auction Value POSIXTime | Bid Value Auction

One problem you could see is that we are still not able to identify who is offering what (since we only have values inside the datum and not public keys). Also, anyone can create any arbitrary Datum in a newly created UTxO. Therefore, we need a way of "authenticating" these UTxOs and "stamp" them, signalizing who the owner of the account is.
This can easily be done with minting policies, as they can execute arbitrary logic without consuming any UTxOs (preserving concurrency). In our case, our policy should make sure that the datum is not corrupted, that the token name it is minting corresponds to the user's public key hash (since we want to identify the owner) and that the minted amount is being transferred (and locked) to the right script (our account script).
After all this is done, the account script can handle transactions however you want. For example, the auction bidders shouldn't be able to change their bid for a smaller amount or retrieve it before the auction deadline is passed. Also, no DOS would be doable since only the owner of this account and the owner of the auction he is bidding on could consume this UTxO (and only if certain conditions are met).
Bidders would be able to compare their bids with other by verifying (off-chain) what other valid accounts are offering. The auction seller would, after the deadline, be able to consume one account UTxO from a bidder by giving it the desired NFT or token of any sort.

how would you generalize a defense-pattern for other Plutus-contracts?

I believe this "account model" (unfortunate name lol) is very general, I'm using it in a project I'm working on that has nothing to do with auctions. The main idea you should keep in mind when designing a validator script is to create multiple UTxOs that can only be consumed by the people interested, so if a DOS would happen, it would only affect the attacker him-self.

Thanks for the detailed proposal. One more question about your proposal: How can you withdraw a losing bid very fast? It would not be good to lock all losing bids until the the entire auction is finished


text:
Interpreter Error (error CallStack (from HasCallStack))
Im getting an interpreter error on the Plutus playground commit 3f84ea4fe3924cb7ee614da2b22c64c02c1177e6. I get it whenever I run the purchase endpoint.
This is the error
Main.hs: This must be replaced by the core-to-plc plugin during compilation: error CallStack (from HasCallStack): error, called at src/PlutusTx/Utils.hs:7:26 in plutus-tx-0.1.0.0-I9Dln998VX1LKsuzHCjcJz:PlutusTx.Utils

Do I need to upgrade versions or is there something wrong with my code?
    import           Control.Monad          hiding (fmap)
import           Data.Aeson             (ToJSON, FromJSON)
import           Data.Text              (Text)
import           Data.Void              (Void)
import           GHC.Generics           (Generic)
import           Data.Map              as Map hiding (foldl)
import           Plutus.Contract
import           Plutus.Contract        as Contract
import           Ledger.Address         as Add
import           Plutus.Trace.Emulator  as Emulator
import qualified PlutusTx
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           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           PlutusTx.Prelude     hiding (Semigroup(..), unless)
import           Prelude              (IO, Semigroup (..), String, Show(..))
import qualified Prelude              as Haskell
import           Cardano.Api hiding (Value, TxOut,Address)
import           Cardano.Api.Shelley hiding (Value, TxOut, Address)
import           Codec.Serialise hiding (encode)
import           Plutus.ChainIndex as Chain

minADA :: Value
minADA = Ada.lovelaceValueOf 2000000

price :: Value
price = Ada.lovelaceValueOf 12000000

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 i x 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
    { 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) (nameOfToken contractInfo) (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
        tx  =   foldl
                (\acc i -> acc <> (Constraints.mustPayToTheScript (i) $ v))
                (TxConstraints [] [] [])
                [1..1000]

    void (submitTxConstraints lootBox tx)

purchase :: () -> Contract w SignedSchema Text ()
purchase _ =  do
    utxos <- utxosAt valAddress

    let outputs = Map.toList utxos
        r      = Redeemer $ PlutusTx.toBuiltinData ()
        (oref, o) = head outputs
        ppkh     = walletOwner contractInfo
        lookups = Constraints.unspentOutputs utxos <>
                  Constraints.otherScript validate
        tx      = mustPayToPubKey (Add.PaymentPubKeyHash ppkh) price <> mconcat [Constraints.mustSpendScriptOutput oref unitRedeemer ]
    ledgerTx <- submitTxConstraintsWith @Void lookups tx
    void $ awaitTxConfirmed $ getCardanoTxId ledgerTx
    logInfo @String $ "loot box used"

-- Sort through the Utxos so that it only collect the right one

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 []

With tag: 62efdd2bfab3e076d40e07f8f4d7864a7f2ccc9  (week05) also fails.

I don't see the pragmas at the beginning of the module in your code...

After debugging your code I've found that the issue comes from lock contract which it's not minting nor transferring funds to the script. So when you try to purchase there's no utxo sitting at the script address. I guess that the weird error comes from this line:
(oref, o) = head outputs

takeaway 1: never use head because if the list is empty you'll get an exception
If in the purchase contract you check whether the list is not empty before continuing (like in purchase below), the weird error will disappear. However, the purchase is not going to work because there's nothing purchase.
purchase :: () -> Contract w SignedSchema Text ()
purchase _ =  do
    utxos <- utxosAt valAddress
    unless (Haskell.null utxos) $ do   -- HERE checks whether there's any utxo.
        let outputs = Map.toList utxos
            r      = Redeemer $ PlutusTx.toBuiltinData ()
            (oref, o) = head outputs
            ppkh     = walletOwner contractInfo
            lookups = Constraints.unspentOutputs utxos <>
                    Constraints.otherScript validate
            tx      = mustPayToPubKey (Add.PaymentPubKeyHash ppkh) price <> mconcat [Constraints.mustSpendScriptOutput oref unitRedeemer ]
        ledgerTx <- submitTxConstraintsWith @Void lookups tx
        void $ awaitTxConfirmed $ getCardanoTxId ledgerTx
        logInfo @String $ "loot box used"

You can check all of this reducing your scenario to only lock and then wait. You'll see no funds going to the script.
Ok, now the FIX.
Why doesn't lock contract work ? Basically, because it's uncompleted. You missed the lookups for the validator and the minting policy script, and also the constraint for mint values. (I think you copied-pasted from other thread (takeaway 2)). I've implemented the following code which locks funds properly.
lock :: MintParams -> Contract w SignedSchema Text ()
lock mp =  do
-- make a recusive function that allows for the creation of a 100 utxos of diffrent datums from a wallet (cheap if implemented correctly)
    pkh <- unPaymentPubKeyHash <$> Contract.ownPaymentPubKeyHash
    let n            = 10  -- If you need 100 you must use a custom configuration different to the default one (1000 ADAS per wallet)
        symbol       = curSymbol pkh
        tn           = nameOfToken contractInfo
        tokenPerUtxo = Value.singleton symbol tn (mpAmount mp)
        adaPerUtxo   = minADA
        valuePerUtxo = tokenPerUtxo <> adaPerUtxo
        tx           = foldl
                         (\acc i -> acc <> Constraints.mustPayToTheScript i valuePerUtxo)
                         (TxConstraints [] [] [])
                         [1..(Haskell.fromIntegral n)]
                    <> Constraints.mustMintValue (mconcat (Haskell.replicate n tokenPerUtxo ))
        lookups = Constraints.typedValidatorLookups lootBox
                <> Constraints.mintingPolicy (policy pkh)

Your code might have more issues (I haven't tested the full workflow), but at least now you can lock funds in the script address, and hopefully you'll be able to purchase. Good luck!
As a side note if I were you, I'd use traces (Emulator.Trace) with different scenarios instead of the playground. Errors are more meaningful and you'll debug the code faster (takeaway 3).
Hope this will be useful.


text:
Can a smart contract only be interacted with once
Im confused if a eUTXO can only be interacted with and used up once how can you do a NFT sale? If I were to make a smart contract to distribute NFT's from a wallet can that be interacted with by multiple people?

I think I understood the context of your question, but could you add more details to what you mean by "if a eUTXO can only be used once how can you do a NFT sale?" Others might not have as much context and there are many ways to implement an "NFT sale."

You can require a new datum be created as part of the validation.
Validator scripts simply validate transactions that spend UTxOs at the script address. They are able to look at the entire context of the transaction, including the outputs. It is true that a EUTxO can only be spent once, but you can add the requirement that an updated datum be returned to the script address after the old datum is spent, thus allowing the next person to interact with the script.

Additionally, CIP-33 (Reference Scripts) is currently being worked on by Cardano Foundation.
In a nutshell, it would establish a standard for attaching commonly used scripts to outputs that will never be spent; allowing all subsequent transactions to reference said outputs instead of resubmitting the same script every time. This would drastically reduce TX size for such commonly used scripts, making them cheaper and mitigating chain bloat.

CIP-31 is also worth calling out. It would allow read-only UTxOs, where you wouldn’t need to consume the datum on read.

Yes, I believe CIP-33 actually relies on CIP-31,as the former is more of a standard whereas the latter is an actual protocol.


text:
Problem with Lesson 5 code on newer version
I am trying to get signed token up and running on the Plutus playground from lesson 5 and I'm running into an issue with I believe is a depreciated variable of PubKeyHash does any body know the solution to this problem. Im using version v2022-01-13.

Please provide the plutus-app version being used. The last time I checked, a PaymentPubKeyHash type has been introduced.


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:
How to make a PubKeyHash into a PaymentPubKeyHash
Im reading through old Plutus code and it seems to be that you could use in the past
pubKeyHash with the mustPayToPubKey function now it asks for a PaymentPubKeyHash. How do you get around this if you want to send a value to an owners paymentPubKeyHash from a plutus script considering that there is no byte string implementation of a PaymentPubKeyHash?
I cant use PubKeyHash anymore in the mustPayToPubKey is there a way to convert this format?

you can get own PymentPubKeyHash with ownPaymentPubKeyHash inside Contract.  Or that is not your case?

no its not I had previously manually typed in a pubKeyHash as a data type to reference the owners pubKeyHash

This is a simple newtype https://playground.plutus.iohkdev.io/doc/haddock/plutus-ledger/html/Ledger-Address.html#t:PaymentPubKey
you can import Ledger.Address and convert it with something like PaymentPubKeyHash myPubKeyHash, you can convert in the opposite direction with unPaymentPubKeyHash

thanks a ton it worked I've been trying to figure that out for days


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:
Transaction memory and cpu usage limits
Let's imagine I have AlwaysSucceeds Plutus validator script, which is:
mkValidator :: Params -> Datum -> Redeemer -> ScriptContext -> Bool
mkValidator _ _ _ _ = True

I locked many different utxos at the script address in the testnet. Let's image 15 in total. Now I want to spend all of those utxos at once from the script using cardano-cli.
Building transaction as usual, and providing those utxos as --tx-in:
--tx-in "abcdef#1" \
--tx-in-script-file alwaysSucceeds.plutus \
--tx-in-datum-value 420 \
--tx-in-redeemer-file redeemer.json \
--tx-in "abcdef#2" \
--tx-in-script-file alwaysSucceeds.plutus \
--tx-in-datum-value 420 \
--tx-in-redeemer-file redeemer.json \
...
...
--tx-in "abcdef#15" \
--tx-in-script-file alwaysSucceeds.plutus \
--tx-in-datum-value 420 \
--tx-in-redeemer-file redeemer.json \

I am pretty sure, that script is included only once in the transaction (is it?). Then submitting transaction to the testnet, I get the following error:
Command failed: transaction submit  Error: Error while submitting tx: ShelleyTxValidationError ShelleyBasedEraAlonzo (ApplyTxError [UtxowFailure (WrappedShelleyEraFailure (UtxoFailure (ExUnitsTooBigUTxO (ExUnits {exUnitsMem = 12500000, exUnitsSteps = 10000000000}) (ExUnits {exUnitsMem = 31256460, exUnitsSteps = 14103266205}))))])

This basically means that I exceeded memory limit by 3 times and CPU by 1.5.
When lowering utxo count to 14,13... it scales down pretty much linearly:
15 utxos: {exUnitsMem = 31256460, exUnitsSteps = 14103266205}
14: {exUnitsMem = 28008316, exUnitsSteps = 12629952076}
13: {exUnitsMem = 24926512, exUnitsSteps = 11232794573}
12: {exUnitsMem = 22011048, exUnitsSteps = 9911793696}
11: {exUnitsMem = 19261924, exUnitsSteps = 8666949445}
10: {exUnitsMem = 16679140, exUnitsSteps = 7498261820}
9: {exUnitsMem = 14262696, exUnitsSteps = 6405730821}
8: Transaction successfully submitted.

The validator script itself has no logic, it should not inflate memory and CPU usage (even though unfortunately it will be executed same amount of times as there are utxos).
My questions:

Does this really mean that somewhat around 10 inputs are the maximum possible to spend from the script?
Is there any way to overcome this, and allow way more inputs from the script to be spent at once?
Are exUnitsMem and exUnitsSteps the same on the mainnet?
Maybe there is a way to increase those parameters to be able to submit the transaction?
Is script really included only once then submitting/Am I building transaction correctly?
As I am validating multiple utxos at once, is it possible to run validator only once and not for each utxo?
If this is really the limit, how we are supposed to build something useful? When and by how much are those units are planned to increase?
Is there any plans, regarding running validator only once for all utxo set, instead of executing it for each utxo?

EDIT:
after updating node version to 1.32.1, error is thrown on the build step also, then utxo count is increased even further. Result is pretty much the same, only the error message is different:
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 budget was overspent. Final negative state: ({ cpu: 5931879314
| mem: -1199
})

You could deserialise the transaction and check how many times the script is included and how large it is. This would be interesting. I read that SundaeSwap struggled with the size of its scripts and had to do some low level optimisations. But unfortunately there are no details on this to be found.

I am pretty sure that it is included only once, as signed transaction size is basically the same with either 1 or 15 utxos, and raw transaction size increases dramatically with each utxo. I can't think of any possible optimizations, as this seems to be lmited by design/architecture itself..

I understand now. It is not the transaction size constraint but the memory constraint that is hit here. I read in an article on iohk.io that the needed execution memory increases with every script-UTxO. I wondered on Twitter if the memory could not be cleared after each UTxO as they are independent of each other. I got no answer though and I don't know if this a yet unused optimisation or if something else is preventing this.

Out of curiosity, how large is the transaction-cbor, though ?

In my mind, the easiest solution for this would be to introduce some flag to allow executing validator script only once for the whole utxo input set and not for each utxo individually, as ScriptContext is aware of all of the utxos, and validation can be done in one iteration for all of them at once

transaction with my script (not AlwaysSuceeds), containing 10 utxo inputs, (and some other stuff) - {exUnitsMem = 19785600, exUnitsSteps = 8451556350}, built transaction - 104553 bytes, signed - 12619 bytes

found here: https://forum.cardano.org/t/max-number-of-transaction-inputs/60023/3, that each --tx-in generally uses about 38 bytes, so transaction size is not the main problem here, even though the utxo input limit is still somewhere in the hundreds for that limitation.

A script that always succeeds is a very special case. Optimisation this is certainly possible but I doubt if it is worthwhile.

Well it's the simplest possible script. Any further logic would additionally increase memory and CPU. From transaction building side, what else can we really do? And in general, I don't think this should be solved by optimizing individually, rather addressed by Cardano themselves, as this will be a blocker for many just a little bit more complicated use cases

I don't think we can do anything here. It looks to me like these memory and cpu consumptions are the result of some overhead to set up script execution (load redeemer, datum, and context). It is difficult to tell. Maybe it is possible to simplify the compiled Plutus code further and reduce resource consumption.

This is a known issue: https://github.com/input-output-hk/cardano-node/issues/3360
Out of curiosity, how many NFT's do you have per --tx-in? I've seen this increase memory usage dramatically with users on jpg.store who store a lot of NFT's in there wallet.
I have a few suggestions, knowing practically nothing about how this stuff works :P I'll share these in the Github issue as well.

Can we remove these limits entirely? Is there any reason why a user can't just pay more to execute a tx with higher mem/CPU requirements?

If #1 isn't possible, what is the reason for keeping the limits as low as they are currently?

Are there any efforts to optimize the Plutus compiler here? Surely adding a few more --tx-in's shouldn't blow up memory like this?

Thanks for the answer! well, these issues are only related. In the link you posted, I believe it is a simple transaction. This one is a transaction involving validator script. Also it is not NFT's. It's utxo's containing ADA or other CNT's, the main difference being the script inclusion in the transaction.

If the network had no computational bounds and was run on nuclear energy sure, but a lot of the nodes are people struggling to keep up with the current, ever increasing minimum requirements, and a lot of that energy is spinning turbines with steam from burning stuff. I don't understand why the contracts can't be iterated through... The network parameters are always known. If you can move them out in piecemeal then while it's a bug, it's not a blackhole.


text:
How to correctly build transaction using PubKeyHash or CurrencySymbol as Datum parameter in cardano-cli?
My validator script expects PubKeyHash and Currency symbol parameters in Datum.
I wrote a script that compiles validator script to plutus and also forms Datum JSON parameters, as well as Redeemer parameters.
In validator script:
data Datum = Datum
    { owner  :: PubKeyHash
    , symbol :: CurrencySymbol
    }

data Redeemer = ActionOne | ActionTwo

Compilation script uses this same Datum object structure imported from Validator, as well as Actions from Redeemer (note that I pass these values as parameters to this script and correctly form Datum object):
writePlutusScript :: Datum -> Redeemer -> Redeemer -> FilePath -> PlutusScript PlutusScriptV1 -> SBS.ShortByteString -> IO ()
writePlutusScript datum rOne rTwo filename scriptSerial scriptSBS =
  do
  case Plutus.defaultCostModelParams of
        Just m ->
          let
            pData = Plutus.toData datum
            (logout, e) = Plutus.evaluateScriptCounting Plutus.Verbose m scriptSBS
                              [ pData
                              , Plutus.toData ()
                              , Plutus.toData dummyContext ]
          in do print ("Log output" :: String) >> print logout
                case e of
                  Left evalErr -> print ("Eval Error" :: String) >> print evalErr
                  Right exbudget -> print ("Ex Budget" :: String) >> print exbudget
                let datumData = encode (scriptDataToJson ScriptDataJsonDetailedSchema $ fromPlutusData pData)
                print $ "Datum value: " <> datumData
                let rOneData = encode (scriptDataToJson ScriptDataJsonDetailedSchema $ fromPlutusData (PlutusTx.toData rOne))
                print $ "One redeemer value: " <> rOneData
                rTwoData = encode (scriptDataToJson ScriptDataJsonDetailedSchema $ fromPlutusData (PlutusTx.toData rTwo))
                print $ "Two redeemer value: " <> rTwoData

The output is like this for Datum:
{
"constructor":0,
"fields":[
{"bytes":"6137356337356661467362633764353365663731356436343734356137613031633263316637363533623261653936323431336163353231"},
{"bytes":"6266636539643063643512345635636537356632356632323835346161373635396239633766323733633866643666623238393235623563"}
]
}

And this for Redeemer:
{"constructor":1,"fields":[]}

But then I am trying to get Datum hash with Cardano-cli, using the very same JSON:
cardano-cli transaction hash-script-data --script-data-value INSERT_JSON_HERE

it fails with error:
Value out of range within the script data: INSERT_JSON_HERE
Byte strings in script data must consist of at most 64 bytes, but it consists of 112 bytes.

Then changing 'bytes' values to corresponding 'string' values, this datum hash command worked.
When I am trying to build the transaction using these values (providing  --tx-in-datum-value SAME_DATUM_JSON_VALUE, --tx-in-redeemer-value SAME_REDEEMER_JSON_VALUE) with cardano-cli transaction build, it fails with:
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 provided Plutus code called 'error'.

The command I use:
cardano-cli transaction build --alonzo-era ${MAGIC} --tx-in SOMETHING --tx-in-script-file SOMETHING --tx-in-datum-value SOMETHING --tx-in-redeemer-value SOMETHING --tx-in-collateral SOMETHING --change-address SOMETHING --protocol-params-file pparams.json --out-file SOMETHING

THE QUESTION: Any ideas why is it failing to build, and maybe how to get clearer error message?

Check out my question I have made with similar problem.
My guess would be, you need to index redeemer as 0, instead of 1 and most important of all Datum bytes fields are too big. They take up 114 bytes of space while the most you can provide is 64!