text:
Continue to be utterly disoriented as to where these magic words come from and how they might be connected
I continue to be utterly lost as to how to understand the source and ultimately the concrete foundation of this byzantine mass of constructs.
Example. In Lesson 4, in the Contract.hs module (and Trace.hs), there is a reference to EmulatorTrace. Where does that come from? How do I know if it is a Data, or a function? It has no type (using :t), yet it does have a type (* -> *, using :i). How can I study how it is built and what it does? The :i gives me info, but nothing actually useful. If I try to drill down into the components (are those data types, or are those functions? No way to know) I get more useless verbiage, or error messages.
What is freer-simple-1.2.1.2 ? Where does it come from? it's not anywhere in the code, although freer-extras is in the cabal.project file and plutus-pioneer-program-week04.cabal file. If I do a locate in my zsh shell, I find numerous nix/store files with freer-simple-1.2.1.1 in the title, but not with freer-simple-1.2.1.2. Why would that be? So much of this feels like magic fairy dust, or like being trapped under 40 tons of construction material blindfolded being told how to adjust a programmable thermostat before learning how to procure a construction screw.
The reason I ask is because if I am going to build code that manages thousands (or more!) of ADA, I need to understand how to build these things from scratch, and right now I can barely copy and paste and tweak a reference hoping it will compile.
Prelude Plutus.Trace.Emulator Data.Default Week04.Contract> :t EmulatorTrace

<interactive>:1:1: error:
    • Data constructor not in scope: EmulatorTrace
    • Perhaps you meant variable ‘runEmulatorTrace’ (imported from Plutus.Trace.Emulator)
Prelude Plutus.Trace.Emulator Data.Default Week04.Contract> :i EmulatorTrace
type EmulatorTrace :: * -> *
type EmulatorTrace =
  freer-simple-1.2.1.2:Control.Monad.Freer.Internal.Eff
    '[Plutus.Trace.Effects.RunContract.StartContract,
      Plutus.Trace.Effects.RunContract.RunContract,
      Plutus.Trace.Effects.Assert.Assert,
      Plutus.Trace.Effects.Waiting.Waiting,
      Plutus.Trace.Effects.EmulatorControl.EmulatorControl,
      Plutus.Trace.Effects.EmulatedWalletAPI.EmulatedWalletAPI,
      Control.Monad.Freer.Extras.Log.LogMsg String,
      freer-simple-1.2.1.2:Control.Monad.Freer.Error.Error
        EmulatorRuntimeError]
  :: * -> *
    -- Defined in ‘Plutus.Trace.Emulator’
Prelude Plutus.Trace.Emulator Data.Default Week04.Contract> :i Plutus.Trace.Effects.RunContract.RunContract
type role Plutus.Trace.Effects.RunContract.RunContract nominal
type Plutus.Trace.Effects.RunContract.RunContract :: * -> *
data Plutus.Trace.Effects.RunContract.RunContract r where
  Plutus.Trace.Effects.RunContract.CallEndpointP :: (Plutus.Trace.Effects.RunContract.ContractConstraints
                                                       s,
                                                     Plutus.Contract.Request.HasEndpoint l ep s,
                                                     aeson-1.5.6.0:Data.Aeson.Types.ToJSON.ToJSON
                                                       ep) =>
                                                    Data.Proxy.Proxy l -> ContractHandle w s e -> ep
                                                    -> Plutus.Trace.Effects.RunContract.RunContract ()
  Plutus.Trace.Effects.RunContract.GetContractState :: (Plutus.Trace.Effects.RunContract.ContractConstraints
                                                          s,
                                                        aeson-1.5.6.0:Data.Aeson.Types.FromJSON.FromJSON
                                                          e,
                                                        aeson-1.5.6.0:Data.Aeson.Types.FromJSON.FromJSON
                                                          w,
                                                        aeson-1.5.6.0:Data.Aeson.Types.ToJSON.ToJSON
                                                          w) =>
                                                       ContractHandle w s e
                                                       -> Plutus.Trace.Effects.RunContract.RunContract (Plutus.Trace.Emulator.Types.ContractInstanceState
                                                                                w
                                                                                s
                                                                                e
                                                                                ())
    -- Defined in ‘Plutus.Trace.Effects.RunContract’
Prelude Plutus.Trace.Emulator Data.Default Week04.Contract> :i freer-simple-1.2.1.2:Control.Monad.Freer.Internal.Eff

<interactive>:1:6: error: parse error on input ‘-’
Prelude Plutus.Trace.Emulator Data.Default Week04.Contract> :i Control.Monad.Freer.Internal.Eff

<interactive>:1:1: error:
    Not in scope: ‘Control.Monad.Freer.Internal.Eff’
Prelude Plutus.Trace.Emulator Data.Default Week04.Contract>

And yet the CLI seems to be perfectly logical and transparent and I have no doubt I can craft a complete billing system using other tools, built around the CLI. That's why I am so shocked that Plutus is so difficult.

I am very familiar with the Haskell language (of which Plutus is a dialect) but not super familiar with this course.
The message
Data constructor not in scope: EmulatorTrace

means you are using an identifier EmulatorTrace that is a constructor for a value, but that the compiler is not able to find that identifier. This can be because the identifier is spelt incorrectly, but in this case, its more likely that you have not imported the module which defines that constructor.

How do I know if it is a Data, or a function?

In Haskell (and Plutus) types and type constructors always begin with an upper case letter and functions always with a lower case letter. However all type constructors are also functions where they operate from the fields that are needed for the constructor to the type the constructor builds.

What is freer-simple-1.2.1.2 ?

That is a haskell package you can find here.
Sorry, I do not have good answers for the rest of the questions.

*->* is not a type, but a kind, see https://wiki.haskell.org/Kind.

While your answer is intended in the best spirit of helpfulness, I am now convinced that Haskell is a completely foreign language!

If you look in Contract.hs, you'll find things like myTrace :: EmulatorTrace (). The use of :: should tell you that what follows is a type. That type is very similar to IO () that you know from main :: IO (). You just happen to be unlucky here to run into these effects, which are one of the advanced Haskell features that we just use in Plutus without a detailed explanation. Maybe this pointer helps you to some extent: https://reasonablypolymorphic.com/blog/freer-monads/


text:
InvalidWitnessesUTXO
Some transactions I’ve been creating are throwing an InvalidWitnessesUTXO error. Appears to be happening to some specific inputs, and any transaction that includes it fails with this same error.
By the way, those transactions are not being created by cardano-cli, their bytes are manually generated, so probably there’s where the error is. Here are some examples of transactions that are throwing this error:
84A300828258206E653F99BEA970245BF3D9D789506FD5E63F2B2A4477553BC092DB9C6F49B17A00825820AB1F82271CE3BF378967F9990F32D92B15DF619CA7A9DFD31BB23C4653D9B73701018282583901CC2D0DD2B430C73E49CA10BCB69256E2078E09AAA0F25A60EF3505A6F7C259A5CF29BB0439A084B77C918ABA70140943EF5017B68D47597F821A00ABA9C7A9581C3C2CFD4F1AD33678039CFD0347CCA8DF363C710067D739624218ABC0A751576F726C647357697468696E30303038330151576F726C647357697468696E30303039320151576F726C647357697468696E30303236320151576F726C647357697468696E30303637320151576F726C647357697468696E30323939340151576F726C647357697468696E30333332360151576F726C647357697468696E303334353001581C83C0AB67AFC9148BD1571B7A14DE1DF03CD5624F5992D3B8EC84D6FBA44D4164614E696E6A617A30303936014D4164614E696E6A617A32393635014D4164614E696E6A617A36343637014D4164614E696E6A617A3637323201581C83CB87B69639E20D7C99755FCFC310FB47882C3591778A3C869EA34CA34A417473756B6F30363137014A417473756B6F34333231014A417473756B6F3737373701581CAA4F61AF3A968B979B53C5F2CBD9EBC656C172CEF6A49626DB24482DA44F507572706C65466F756E64657233330150507572706C65466F756E6465723239320150507572706C65466F756E6465723933390151507572706C65466F756E6465723130383701581CAF2E27F580F7F08E93190A81F72462F153026D06450924726645891BA144445249501AEE6B1860581CC16777D742784B7ACD3940E0356596D313E141200FE8E48C8DF16BA7A2581942697446696E734861776B66696E556E636F6D6D6F6E32313901581942697446696E7350656E67757068696E45786F74696331343501581C5A46271A9B32A4517CED20BE4BA1F184C2F91B1A5DD480AB639EEE57A14D42726967687450616C3231313301581C7DDC646D0E15B44DB03F0F904E0AB6B72E57AA48D2E579CE66366A3DA4544265617273436C75624D656D626572303137363701544265617273436C75624D656D626572303538323901544265617273436C75624D656D626572303635353801544265617273436C75624D656D626572303639313601581CA4ACDB40F495B61BC98F10C4DF10CA7204F2EFCADDC9E0A2AF9C8E04A153436861726C7A20466F756E64657220233536340183581D7115EEA1EEAB457FB4545F260BFC84506DFF8B5026E82DD1E516A859A3821A001A4EC4A1581C83CB87B69639E20D7C99755FCFC310FB47882C3591778A3C869EA34CA14A417473756B6F333637390158205C1AFDA1752274151ED7EA1E816BD7206076CE0813A23DAF7501E0AD2528DB3E021A0003E785A10081825820FC9FADC1DCDCA0816E59815FE85A0D990FB7F8CF1BD98F3A52D191DA11882BEB58403B11BE2D64A87BB4876677CA7E2E709B9C1699C8038A267E94E514CE68E0ED2D95DC4B69BD1B6A822391EF197C7D9836BFDB218F080EA3D73F171EF1168B9E04F5F6

84A30082825820353AC8FABB2963D9C5FD2160B706973D70333A87F4B9421BF7404A7EB5AC7A420182582039C885AD9B66757B9E2C1B7F2C816FF67B8D56AF857DC451752926C241F9C46F000182825839015E914486736E665A966C010AE54017593F6D69E6E00ACD0DC6531E8D337C746991A49CEE49ED190F2FDEA52887D33F84F1E7E71F3B415515821A1796433FA4581C1CDA8886F4CBAB2217346187A923B3BE670E42EF5778A0AD7D25358CB44F4D7574616E74546F61643032313030014F4D7574616E74546F61643033303330014F4D7574616E74546F61643033323732014F4D7574616E74546F61643033333535014F4D7574616E74546F61643033383038014F4D7574616E74546F61643033383239014F4D7574616E74546F61643033383639014F4D7574616E74546F61643033393434014F4D7574616E74546F61643034303932014F4D7574616E74546F61643034313139014F4D7574616E74546F61643034323236014F4D7574616E74546F61643034343232014F4D7574616E74546F61643034373431014F4D7574616E74546F61643034393439014F4D7574616E74546F61643033303336014F4D7574616E74546F61643033333239014F4D7574616E74546F61643033343031014F4D7574616E74546F61643034343636014F4D7574616E74546F61643034363732014F4D7574616E74546F6164303439343701581CD517F38DD2C5ACC3347C8E933E2C0185FAFE3BA838F8830000A3C95FA14F4D7574616E7443726F63303439323801581C7DDC646D0E15B44DB03F0F904E0AB6B72E57AA48D2E579CE66366A3DA4544265617273436C75624D656D626572303133373501544265617273436C75624D656D626572303137353601544265617273436C75624D656D626572303238303701544265617273436C75624D656D626572303336333301581CF4988F549728DC76B58D7677849443CAF6E5385DC67E6C25F6AA901EA54A506978656C54696C6534014B506978656C54696C653238014B506978656C54696C653532014B506978656C54696C653535014B506978656C54696C6535390183581D7115EEA1EEAB457FB4545F260BFC84506DFF8B5026E82DD1E516A859A3821A001A4EC4A1581C1CDA8886F4CBAB2217346187A923B3BE670E42EF5778A0AD7D25358CA14F4D7574616E74546F61643033393139015820BBE0865A7AF0500E70474074674E8D45E6FDBB2FC37CEE2F12023F2A15BFEA36021A0003BA25A100818258206395B3BA1098D9855AB88FA56D51EF9CFCA792CDD4701561CCE2FE7E00748C0858401CB6F5B2EBF2D8D44FDA986F479163C4E47586ABDDE411CC8E093EB1AF5281F8561E8219DB9C47F3F842E5151DB65C5AA9DC476CF60A08A40E37D478D1054C04F5F6

Thank you in advance for the help!

This was actually related to the Multiasset sorting. I was creating the transaction and when it got into Emurgo/serialization library code the multiasset was being reordered before the transaction was signed. Therefore, I was receiving a signature that was invalid to the transaction I primarily sent.

You are using a UTXO without including the witness signature of the private key that owns it.
You should sign the raw transaction with the key and include the witness in the final transaction.
If you are using UTXOs from multiple keys, you will need to sign the raw tx with all the keys and include all the corresponding witnesses in the final transaction.

source: Stack Exchange

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

sort: votes


text:
ppp Class 4: What happens when a contract is called while it is not waiting?
The off-chain contract code is recursive, holds and waits until endpoint is called, then executes code (gets busy for a little while), then recurses.
What happens when a endpoint is called while the contract code is "busy" handling another previous call, hence it is not listening.

The endpoint is a Promise - which is asynchronous. When called multiple times with different ContractInstance, it works without any conflicts.
What happens when an endpoint is called twice by the same ContractInstanceId can be found here

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


text:
What is precise calculation algorithm for native asset fees?
I have an application where I want to avoid using 3rd binaries like cardano-cli. I need to calculate what is minimal UTXO size for TX where N different tokens is sent.
Right now cardano-wallet HTTP endpoint returns error 404 with long error string that contains correct value

{
  "code": "utxo_too_small",
  "message": "Some outputs have ada values that are too small. There's a minimum ada value specified by the protocol that each output must satisfy. I'll handle that minimum value myself when you do not explicitly specify an ada value for an output. Otherwise, you must specify enough ada. Here are the problematic outputs:   - Expected min coin value: 1.413762     TxOut:       address: 00064225...d59deacc       coin: 1.400000       tokens:         - policy: 9e87deb6ec1e989f125652b4883728fdd308e4223a0396f45b2023c2           tokens:             - token: 766d3774657374486f736b794361736847726162               quantity: 1 "
}

I want to be able to calculate this value myself. What I do right now is that I take "base min UTXO" size of 1.6ADA for lovelace and 1 token and then add 0.3ADA for each extra token, so if someone is sending 2 tokens it asks for 1.9ADA deposit.
That works but isn't correct and I probably use unnecessarily large deposits (it doesn't matter so much as whole deposit - tx fees is returned back to user) but I'd like to make this correct.
So what is the correct algorithm to calculate precise fee? Mind this is just a simple transaction of ADA and some native assets to single output address, no plutus or other complex things to consider.

Check out this Q/A: https://cardano.stackexchange.com/questions/2545/manual-calculation-of-transaction-size-and-fee
Manual calculation of a cbor is an "involved process", as Andrew puts it. I'm not sure the exact way to do it though.

unfortunatelly that doesn't explain how to calculate it without cardano-cli, eg. how to get TX size without it?

There is documentation to calculate the minimum ADA value for a tx output however it is not only out of date(e.g. coinSize has since increased to 2, asset names now hex-encoded instead of ASCII chars), but also difficult to decipher into working code.
After quite a bit of effort I implemented the particular algorithm in C# which should translate to other languages without much difficulty:
public record struct NativeAssetValue(
    string PolicyId, string AssetNameHex, long Quantity);

public record struct TokenBundle(
    long LovelaceValue, NativeAssetValue[] NativeAssets);

public static long CalculateMinUtxoLovelace(
    TokenBundle txOutBundle,
    int lovelacePerUtxoWord = 34482, // utxoCostPerWord in protocol params (could change in the future)
    int policyIdSizeBytes = 28, // 224 bit policyID (won't change in forseeable future)
    bool hasDataHash = false) // for UTxOs with smart contract datum
{
    const int fixedUtxoPrefixWords = 6;
    const int fixedUtxoEntryWithoutValueSizeWords = 27; // The static parts of a UTxO: 6 + 7 + 14 words
    const int coinSizeWords = 2; // since updated from 0 in docs.cardano.org/native-tokens/minimum-ada-value-requirement
    const int adaOnlyUtxoSizeWords = fixedUtxoEntryWithoutValueSizeWords + coinSizeWords;
    const int fixedPerTokenCost = 12;
    const int byteRoundUpAddition = 7;
    const int bytesPerWord = 8; // One "word" is 8 bytes (64-bit)
    const int fixedDataHashSizeWords = 10;

    var isAdaOnly = txOutBundle.NativeAssets.Length == 0;
    if (isAdaOnly)
        return lovelacePerUtxoWord * adaOnlyUtxoSizeWords; // 999978 lovelaces or 0.999978 ADA

    // Get distinct policyIDs and assetNames
    var policyIds = new HashSet<string>();
    var assetNameHexadecimals = new HashSet<string>();
    foreach (var customToken in txOutBundle.NativeAssets)
    {
        policyIds.Add(customToken.PolicyId);
        assetNameHexadecimals.Add(customToken.AssetNameHex);
    }

    // Calculate (prefix + (numDistinctPids * 28(policyIdSizeBytes) + numTokens * 12(fixedPerTokenCost) + tokensNameLen + 7) ~/8)
    var tokensNameLen = assetNameHexadecimals.Sum(an => an.Length) / 2; // 2 hexadecimal chars = 1 Byte
    var valueSizeWords = fixedUtxoPrefixWords + (
        (policyIds.Count * policyIdSizeBytes)
        + (txOutBundle.NativeAssets.Length * fixedPerTokenCost)
        + tokensNameLen + byteRoundUpAddition) / bytesPerWord;
    var dataHashSizeWords = hasDataHash ? fixedDataHashSizeWords : 0;

    var minUtxoLovelace = lovelacePerUtxoWord
        * (fixedUtxoEntryWithoutValueSizeWords + valueSizeWords + dataHashSizeWords);

    return minUtxoLovelace;
}

Special thanks to Pal's visualisation from his Shelley Stuffs Repository which was of tremendous help

I think the answer is supposed to be extractable from the docs
https://docs.cardano.org/native-tokens/minimum-ada-value-requirement
but its not very clear (to me).
I'm also pretty suspicious
sumAssetNameLengths B = length myAssetNameSBS + length yourAssetNameSBS + length someAssetNameSBS

implies that the blockchain economises when two assets share a token name (but different currency symbol). This is weird.

I found your Q after looking for the same answer ... => I also don't really know yet


text:
How to add multiasset as input to txBuilder?
I'm trying to add lovelaces + native assets to input as multiAsset. However I get Inputs do not conform to this spec or are otherwise invalid.
Here is my code:
    const assetsToSend = this.S.MultiAsset.new();
    const assets = this.S.Assets.new();
    const policyStr = "17830caa477d5eac7a4b6c123d98fa232e6e921368b01b7cd0bdfce6"

    const assetStr = "17830caa477d5eac7a4b6c123d98fa232e6e921368b01b7cd0bdfce641414441";
    const assetName = this.S.AssetName.new(Buffer.from(assetStr.slice(56), "hex"));

    // creating asset value for lovelaces
    const assetsValue = this.S.Value.new(
        this.S.BigNum.from_str('1500000')
    )

    // Inserting Native token
    assets.insert(
        assetName,
        this.S.BigNum.from_str('123')
    );

    // Adding asset to multiasset
    assetsToSend.insert(
        this.S.ScriptHash.from_bytes(Buffer.from(policyStr, "hex")),
        assets
    );
    // Setting value with multiasset
    assetsValue.set_multiasset(assetsToSend)

    txBuilder.add_input(
        this.S.Address.from_bech32("addr_test1qqcula4fd6nr92zx2jyl59eqy574f8uhg98dhfys7zer23p03az6tzlxgrxk5a9ev6taetv6ljkyr7rcx4rljm7qya2syeq06w"),
        this.S.TransactionInput.new(
            this.S.TransactionHash.from_bytes(
                Buffer.from("707c0ad2499b278e48bc8e42b902ec8ccea8e83e87175f57f4349241cd5a8417", "hex")
            ), // tx hash
            0, // index
        ),
        assetsValue
        // this.S.Value.new(this.S.BigNum.from_str('1500000'))
    );

The code I described above is okay to pass multiassets to TX inputs. It have worked for me with cardano-serialization-lib 10.0.1 .


text:
Optimising validators with `BuiltinData -> BuiltinData -> BuiltinData -> ()` and building tx with cardano-cli
In one of your previous classes you said that some teams are optimising their contracts with this type of validator BuiltinData -> BuiltinData -> BuiltinData -> ()  and I'll refer to those contracts as "optimised" (logic inside is the same, other than resolving types from BuiltinData). I've tried doing that even with custom context ctx = PlutusTx.unsafeFromBuiltinData @CustomScriptContext rawContext and when I build scripts and calculate expected memory and CPU budget with this command
writePlutusScript filename scriptSerial scriptSBS =
  do
    case Plutus.defaultCostModelParams of
      Just m ->
        let (logout, e) = Plutus.evaluateScriptCounting Plutus.Verbose m scriptSBS []
         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

and I get info that budget is decreased a lot for "optimised" validators
Non optimised: ExBudget {exBudgetCPU = ExCPU 15184330, exBudgetMemory = ExMemory 51100}
Optimised: ExBudget {exBudgetCPU = ExCPU 8306767, exBudgetMemory = ExMemory 28000}

But when I try to build and submit a batch (via cardano-cli transaction build and cardano-cli submit) with couple of different contacts  utxos and 1  "optimised" contracts utxos I get ExUnitsTooBigUTxO error (on submit) and it says that it exceedes memory by a lot (4000000+)
{unWrapExUnits = ExUnits' {exUnitsMem' = 16000000, exUnitsSteps' = 10000000000}}) (WrapExUnits {unWrapExUnits = ExUnits' {exUnitsMem' = 20120006, exUnitsSteps' = 8471969427}}

and when i use non optimised contract utxo in the same batch (only difference is that one utxo) my transaction goes through.
How could that be? Does cardano-cli submit uses same logic for calculation of units as I've posted above (and as transaction build), Why did transaction build go trough if it has memory issues (when I'm over limit transaction build usually informs me)? And could there be a reason to use build-raw and add custom  (ones I've received from the plutus code) exUnits, and would that help?

The last paragraph is not clear to me. Are you creating a transaction which does evaluate multiple scripts or is it only the one script for which you also calculated the budget?

It's 2 different scripts/validators in one "batch", first one is "LP" script/validator that is used in both cases (optimised and non optimised) and second is "Order" script, which is in the failing case optimised and in successful case non optimised


text:
Understand purpose of tx-out-datum-hash in Lars' lobster NFT minting example
When the Alonzo era started on mainnet, Lars deployed a smart contract example, in which he minted a lobster NFT as part of a lobster naming challenge.
In the policy script used to mint the lobster NFT - link to policy/validator code, the argument inputs for the tokenName and the UTxO are baked into the compiled Plutus script, since it's a parameterized typed policy/validator. By "baked in" I mean the  validator code compiled to plutus already includes the token name and UTxO, so these args do not need to passed as datum when executing the transaction.
However, in the deploy script to mint the lobster NFT - link to deploy script, there is an parameter tx-out-datum-hash set in the cardano-cli transaction build.  What datum does this hashed value represent and how is the hash computed?  In Lars' example code, the value is hard-coded and no explanation is given for what it represents.

That value is the hash value of an empty list. You can calculate it in the repl as follows:
import Ledger qualified
import PlutusTx qualified

emptyListDatum = Ledger.Datum $ PlutusTx.toBuiltinData ([] :: [()])
emptyListDatumHash = Ledger.datumHash emptyListDatum -- 45b0cfc220ceec5b7c1c62c4d4193d38e4eba48e8815729ce75f9c0ab0e4c1c0

Note that the datum selected by Lars is completely arbitrary because it's not used in the validator script.

That's brilliant.  Thanks @kindofdev.

You’re more than welcome. Glad to help!


text:
What is a library stanza?
I deduce what stanza definitions are but I was struggling to find an exact definition and explanation why this is used in Haskell/Plutus.

What exactly is a stanza?
Can you compile code Haskell/Plutus code
without using them?

I recommend you this article:
https://vrom911.github.io/blog/common-stanzas
Take into account that stanzas is a cabal thing (not Haskell, not Plutus). However Plutus projects can be created using cabal. Basically, it's the way a cabal file is organized: Libraries, executables, test-suites, etc.

If you answer someone's question, shouldn't you automatically vote for it?  It had 0 votes when I made this comment :-)

@gRebel, done. Thanks you for the reminder.


text:
I have downloaded deadlus wallet from the testnet and now what?
I have downloaded deadalus wallet for testing with Ada from this link: https://testnets.cardano.org/en/testnets/cardano/get-started/wallet/
I couldn't find a link which helps me to figure out how to install the same on my linux 64 bit machine.
However, I have some questions:

How to install this in my local linux machine?
Do i have to take it online 24*7
Can i use the same wallet if i am going to use the real ada on this particular system.

My intention is to develop a token on the top of cardano block chain.

See IOHK Zendesk article: Installing Daedalus Testnet wallet

Log in to the target Linux or UNIX system.

Go to the directory that contains the installation program.

Launch the installation by entering the following commands:

chmod a+x filename.bin
./filename.bin


text:
Updating NFT metadata when policy unlocked
We're wondering whether there is a convention for updating the metadata related to an nft in the case where a policy has not yet expired. For example, an nft is originally created with 721 metadata showing the twitter url twitter.com/foo. If we 'mint' a new nft with 721 metadata which changes the url to twitter.com/bar, will this be correctly interpreted by clients? If not, is there some other way to accomplish this?

Yes, the process you've outlined is correct. You can simply mint a second NFT with updated metadata into your own wallet (no need to retrieve the original from someone elses) and then burn it immediately. All NFTs that share that token name will be updated regardless of what wallet they are in.


text:
What's the Lars' UTXO diagrams tool?
Maybe this is not a very interesting question but I'd like to know which is the tool that Lars uses in the lectures to draw UTXO's graphs.
Thanks in advance!

The tool can be found here.
Lars himself confirmed it in this Discord message.


text:
Empty TokenName Literal Overloading in Week05 Homework2
This doesn't work
mkPolicy oref () ctx = traceIfFalse "UTxO not consumed"   hasUTxO           &&
                       traceIfFalse "wrong amount minted" checkMintedAmount
  where
    info :: TxInfo
    info = scriptContextTxInfo ctx

    hasUTxO :: Bool
    hasUTxO = any (\i -> txInInfoOutRef i == oref) $ txInfoInputs info

    checkMintedAmount :: Bool
    checkMintedAmount = case flattenValue (txInfoMint info) of
        [(_, tn, amt)]  -> tn == "" && amt == 1
        _               -> False

and throws
GHC Core to PLC plugin: E042:Error: Unsupported feature: Type constructor: GHC.Prim.Char#
Context: Compiling type: GHC.Prim.Char#
Context: Compiling data constructor type: GHC.Types.C#
Context: Compiling type: GHC.Types.Char
Context: Compiling type: GHC.Base.String
Context: Compiling type: GHC.Base.String
                         -> Data.ByteString.Internal.ByteString
Context: Compiling definition of: Plutus.V1.Ledger.Value.$fIsStringTokenName1
Context: Compiling expr: Plutus.V1.Ledger.Value.$fIsStringTokenName1
Context: Compiling expr: Plutus.V1.Ledger.Value.$fIsStringTokenName1
                           ((GHC.Types.[] @ GHC.Types.Char)
                            `cast` (Sym (Nth:2
                                             (((<GHC.Base.String>_R
                                                ->_R Sym (PlutusTx.Builtins.Internal.N:BuiltinByteString[0]) ; Sym (Plutus.V1.Ledger.Value.N:TokenName[0])) ; Sym (Data.String.N:IsString[0]) <Plutus.V1.Ledger.Value.TokenName>_N) ; Data.String.N:IsString[0] <Plutus.V1.Ledger.Value.TokenName>_N))
                                    :: GHC.Types.Coercible GHC.Base.String GHC.Base.String))
... (a lot of lines skipped here)
Context: Compiling definition of: Week05.Homework2.mkPolicy
Context: Compiling expr: Week05.Homework2.mkPolicy
Context: Compiling expr: Week05.Homework2.mkPolicy oref'_axTu
Context: Compiling expr: PlutusTx.Base.$
                           @ (() -> Plutus.V1.Ledger.Contexts.ScriptContext -> GHC.Types.Bool)
                           @ Ledger.Typed.Scripts.MonetaryPolicies.WrappedMintingPolicyType
                           (Ledger.Typed.Scripts.MonetaryPolicies.wrapMintingPolicy
                              @ () PlutusTx.IsData.Instances.$fUnsafeFromData())
                           (Week05.Homework2.mkPolicy oref'_axTu)
Context: Compiling expr: \ (oref'_axTu :: Plutus.V1.Ledger.Tx.TxOutRef) ->
                           PlutusTx.Base.$
                             @ (() -> Plutus.V1.Ledger.Contexts.ScriptContext -> GHC.Types.Bool)
                             @ Ledger.Typed.Scripts.MonetaryPolicies.WrappedMintingPolicyType
                             (Ledger.Typed.Scripts.MonetaryPolicies.wrapMintingPolicy
                                @ () PlutusTx.IsData.Instances.$fUnsafeFromData())
                             (Week05.Homework2.mkPolicy oref'_axTu)
Context: Compiling expr at "plutus-pioneer-program-week05-0.1.0.0-inplace:Week05.Homework2:(55,8)-(55,85)"

but this works
mkPolicy oref () ctx = traceIfFalse "UTxO not consumed"   hasUTxO           &&
                       traceIfFalse "wrong amount minted" checkMintedAmount
  where
    info :: TxInfo
    info = scriptContextTxInfo ctx

    emptyToken :: TokenName
    emptyToken = TokenName ""

    hasUTxO :: Bool
    hasUTxO = any (\i -> txInInfoOutRef i == oref) $ txInfoInputs info

    checkMintedAmount :: Bool
    checkMintedAmount = case flattenValue (txInfoMint info) of
        [(_, tn, amt)]  -> tn == emptyToken && amt == 1
        _               -> False

I assumed that {-# LANGUAGE OverloadedStrings   #-} would work as TokenName is just a newtype for PlutusTx.Builtins.Internal.BuiltinByteString. From the repl
Prelude Week05.Homework2> :t Plutus.V1.Ledger.Value.TokenName
Plutus.V1.Ledger.Value.TokenName
  :: PlutusTx.Builtins.Internal.BuiltinByteString
     -> Plutus.V1.Ledger.Value.TokenName
Prelude Week05.Homework2> :i Plutus.V1.Ledger.Value.TokenName
type Plutus.V1.Ledger.Value.TokenName :: *
newtype Plutus.V1.Ledger.Value.TokenName
  = Plutus.V1.Ledger.Value.TokenName {Plutus.V1.Ledger.Value.unTokenName :: PlutusTx.Builtins.Internal.BuiltinByteString}
    -- Defined in `Plutus.V1.Ledger.Value'
instance Eq Plutus.V1.Ledger.Value.TokenName
  -- Defined in `Plutus.V1.Ledger.Value'
instance Ord Plutus.V1.Ledger.Value.TokenName
  -- Defined in `Plutus.V1.Ledger.Value'
instance Show Plutus.V1.Ledger.Value.TokenName
  -- Defined in `Plutus.V1.Ledger.Value'

Edit #1
On reading this doc I realised that maybe TokenName is not an instance of IsString. I tried to implement it using:
instance IsString TokenName where
        fromString = unTokenName

but I got this error
src/Week05/Homework2.hs:32:10: error:
    Duplicate instance declarations:
      instance IsString TokenName
        -- Defined at src/Week05/Homework2.hs:32:10
      instance IsString TokenName -- Defined in `Plutus.V1.Ledger.Value'
   |
32 | instance IsString TokenName where
   |          ^^^^^^^^^^^^^^^^^^

Edit #2
The complete Homework file is here.

In plutus docs I see that TokenName is an instance of IsString.  http://0.0.0.0:8002/haddock/plutus-ledger-api/html/Plutus-V1-Ledger-Value.html#t:TokenName

After digging into Plutus source, I think I've found why tn == "" crashes at runtime.
The problem might be that the instance of TokenName IsString doesn't use the INLINABLE pragma in the function fromString. Due to this, Plutus core crashes. (As a reminder, every function in order to compiles to Plutus core must have the INLINABLE pragma).
[source: Plutus.V1.Ledger.Value]
instance IsString TokenName where
    fromString = fromText . Text.pack

On other hand, for example traceIfFalse "UTxO not consumed" hasUTxO is resolved properly because the function fromString in IsString BuiltinString uses the INLINABLE mechanism.
[source: PlutusTx.Builtins.Class]
-- We can't put this in `Builtins.hs`, since that force `O0` deliberately, which prevents
-- the unfoldings from going in. So we just stick it here. Fiddly.
instance IsString BuiltinString where
    -- Try and make sure the dictionary selector goes away, it's simpler to match on
    -- the application of 'stringToBuiltinString'
    {-# INLINE fromString #-}
    -- See Note [noinline hack]
    fromString = Magic.noinline stringToBuiltinString

{-# INLINABLE stringToBuiltinString #-}
stringToBuiltinString :: Haskell.String -> BuiltinString
-- To explain why the obfuscatedId is here
-- See Note [noinline hack]
stringToBuiltinString str = obfuscatedId (BuiltinString $ pack str)

Why don't Plutus team use INLINABLE mechanism in the function fromString for TokenName? I don't know, it might be a bug.
EDIT 1
I've raised an issue on Plutus repo.
https://github.com/input-output-hk/plutus/issues/4404
EDIT 2
The issue is (see Plutus team's answer https://github.com/input-output-hk/plutus/issues/4404)

Unfortunately, due to the technical reasons plutus plugin doesn't
support OverloadedStrings with newtypes.

Notice the same thing happens with PubKeyHash (it's a newtype)

The problem is you don't have IsString in scope. If you add import Data.String should work. Here you can see it in the repl.

EDIT 1
( First part of the answer referred to how to bring into scope IsString for TokenName in the repl. )
Additionally, I've tried to compile your code with the imports and pragmas that you can see in the following code snippet and the result of compiling has been successful. Probably, you have something wrong with imports.
{-# LANGUAGE NoImplicitPrelude  #-}
{-# LANGUAGE OverloadedStrings  #-}

module Plutus.Contracts.Currency( mkPolicy ) where

import Ledger.Value ( flattenValue )
import Ledger.Contexts
    ( ScriptContext(scriptContextTxInfo),
      TxOutRef,
      TxInfo(txInfoInputs, txInfoMint),
      TxInInfo(txInInfoOutRef) )
import PlutusTx.Prelude
    ( Bool(False), Eq((==)), ($), (&&), any, traceIfFalse )

mkPolicy :: TxOutRef -> () -> ScriptContext -> Bool
mkPolicy oref () ctx = traceIfFalse "UTxO not consumed"   hasUTxO           &&
                       traceIfFalse "wrong amount minted" checkMintedAmount
  where
    info :: TxInfo
    info = scriptContextTxInfo ctx

    hasUTxO :: Bool
    hasUTxO = any (\i -> txInInfoOutRef i == oref) $ txInfoInputs info

    checkMintedAmount :: Bool
    checkMintedAmount = case flattenValue (txInfoMint info) of
        [(_, tn, amt)]  -> tn == "" && amt == 1
        _               -> False

But in week01 here there was no such import yet it still overloaded the string. Is there a special case for BuiltinByteString? I remember this because I didn't about the Overloaded String pragma ({-# LANGUAGE OverloadedStrings          #-}).

@Roofi, you are right, maybe for BuiltinByteString is different. Just curious, Does it work your code by importing Data.String?

Sorry, it doesn't.
At line 30 I changed
import           Data.String( IsString(..) )
to
import           Data.String and then tried the first code block in my question.
Also in my previous comment, I meant "didn't know about" instead of "didn't about".

@Roofi, I've just edited my answer. Please, take a look.

I think the code you provided may not raise that error as the error stems from the usage of wrapMintingPolicy. I inferred this by looking at the last line of the error block. I just edited my question to add a link to the complete code.

@Roofi, I've just added a new answer instead of  editing again my first question. (I think it will be more readable for the future)


text:
Error while syncing with Testnet, Invalid block

I have tried node version 1.30.01, 1.29. 1.29rc-2 .1.33 - latest
They all encounter this invalid block here.
I'm using config file for the testnet here https://hydra.iohk.io/build/7654130/download/1/index.html

Try using the latest node and the latest configuration files.
The latest release can be found here: https://github.com/input-output-hk/cardano-node/releases
The config files for this release are here: https://book.world.dev.cardano.org/environments.html


text:
Write a policy script with a custom redeemer type, but do NOT use `Plutus.liftCode`
I'd like to write a policy script that receives a custom data type for the Redeemer argument, but does not use Plutus.liftCode to "bake the argument value" into the compiled Plutus script.  Instead, I want to be able to compile the policy script with no redeemer value upfront and just declare the type of the argument (e.g. my custom data type) that will be received when the transaction is executed.  This will mean that the custom redeemer data will be submitted with the transaction instead.
There are examples of this for Validator, e.g. TypedValidator example from PPP, but I cannot figure out how to do the equivalent thing for a PolicyScript.  All the policy script examples I've seen use Plutus.liftCode.
Here's the starting point of the code I'm trying to write.  I put brackets around the places in the code that I need an equivalent idea for PolicyScript.
data CustomRedeemer = CustomRedeemer
    { txOut :: TxOutRef
    , nftName :: String
    } deriving Show

PlutusTx.unstableMakeIsData ''CustomRedeemer

{-# INLINABLE mkNftPolicy #-}
mkNftPolicy :: CustomRedeemer -> ScriptContext -> Bool
mkNftPolicy custom ctx = traceIfFalse "UTxO not consumed"   hasUTxO           &&
                         traceIfFalse "wrong amount minted" checkMintedAmount
  where (...)

data MyTypedInstance
instance <equivalent-of: Scripts.ValidatorTypes> MyTypedInstance where
    type instance RedeemerType MyTypedInstance = CustomRedeemer

typedPolicy :: <equivalent-of: Scripts.TypedValidator> MyTypedInstance
typedPolicy =  <equivalent-of: Scripts.mkTypedValidator> @MyTypedInstance
    $$(PlutusTx.compile [|| mkNftPolicy ||])
    $$(PlutusTx.compile [|| wrap ||])
  where
    wrap = <equivalent-of: Scripts.wrapValidator> @CustomRedeemer

Thanks!

It's pretty simple:

Define the redeemer with the proper types (they must be part of UnsafeFromData typeclass in order to use PlutusTx.unstableMakeIsData (2))

Do PlutusTx.unstableMakeIsData ''CustomRedeemer.

Define the policy with mkMintingPolicyScript $$(PlutusTx.compile [|| Scripts.wrapMintingPolicy mkPolicy ||]) where mkPolicy doesn't have any lifted parameters.

Have fun.

Important: If you define the custom redeemer along with PlutusTx.unstableMakeIsData in the same module as your minting policy script, the compiler complains in Scripts.wrapMintingPolicy saying that PlutusTx.UnsafeFromData CustomRedeemer must be imported, not defined locally. SOLUTION: Define it in a separate module. This must be Template Haskell stuff...

Additionally, I share a simple example of all of this:
[custom redeemer types module]
{-# LANGUAGE TemplateHaskell     #-}
{-# LANGUAGE NoImplicitPrelude   #-}

module Week05.WithCustomRedeemerTypes where

import           PlutusTx.Prelude
import           Prelude          (Show (..))
import qualified PlutusTx
import           Ledger           (TokenName)

data CustomRedeemer = CustomRedeemer
    { nftName     :: TokenName
    , description :: BuiltinByteString
    } deriving Show

PlutusTx.unstableMakeIsData ''CustomRedeemer

[minting policy module]
{-# LANGUAGE DataKinds           #-}
{-# LANGUAGE DeriveAnyClass      #-}
{-# LANGUAGE DeriveGeneric       #-}
{-# LANGUAGE FlexibleContexts    #-}
{-# LANGUAGE NamedFieldPuns      #-}
{-# LANGUAGE NoImplicitPrelude   #-}
{-# LANGUAGE OverloadedStrings   #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell     #-}
{-# LANGUAGE TypeApplications    #-}
{-# LANGUAGE TypeFamilies        #-}
{-# LANGUAGE TypeOperators       #-}

module Week05.WithCustomRedeemer where

import           Control.Monad          hiding (fmap)
import           Data.Aeson             (ToJSON, FromJSON)
import           Data.Text              (Text)
import           GHC.Generics           (Generic)
import           Plutus.Contract        as Contract
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           Prelude                (IO, Show (..), String)
import           Text.Printf            (printf)
import           Wallet.Emulator.Wallet

import           Week05.WithCustomRedeemerTypes

{-# INLINABLE mkNftPolicy #-}
mkNftPolicy :: CustomRedeemer -> ScriptContext -> Bool
mkNftPolicy CustomRedeemer{nftName} _ =
    let expected = TokenName "kurt"
    in traceIfFalse "Kurt is sad because the nft is not called kurt :(" $ nftName == expected

policy :: Scripts.MintingPolicy
policy = mkMintingPolicyScript $$(PlutusTx.compile [|| Scripts.wrapMintingPolicy mkNftPolicy ||])

curSymbol :: CurrencySymbol
curSymbol = scriptCurrencySymbol policy

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

type FreeSchema = Endpoint "mint" MintParams

mint :: MintParams -> Contract w FreeSchema Text ()
mint mp = do
    let tn = mpTokenName mp
        redeemer = Redeemer $ PlutusTx.toBuiltinData $ CustomRedeemer tn "a description"
        val      = Value.singleton curSymbol (mpTokenName mp) (mpAmount mp)
        lookups  = Constraints.mintingPolicy policy
        tx       = Constraints.mustMintValueWithRedeemer redeemer val
    ledgerTx <- submitTxConstraintsWith @Scripts.Any lookups tx
    void $ awaitTxConfirmed $ getCardanoTxId ledgerTx
    Contract.logInfo @String $ printf "forged %s" (show val)

endpoints :: Contract () FreeSchema Text ()
endpoints = mint' >> endpoints
  where
    mint' = awaitPromise $ endpoint @"mint" mint

happyKurt :: IO ()
happyKurt = runEmulatorTraceIO $ do
    let tn = "kurt"
    h1 <- activateContractWallet (knownWallet 1) endpoints
    callEndpoint @"mint" h1 $ MintParams
        { mpTokenName = tn
        , mpAmount    = 555
        }
    void $ Emulator.waitNSlots 1

sadKurt :: IO ()
sadKurt = runEmulatorTraceIO $ do
    let tn = "bob"
    h1 <- activateContractWallet (knownWallet 1) endpoints
    callEndpoint @"mint" h1 $ MintParams
        { mpTokenName = tn
        , mpAmount    = 555
        }
    void $ Emulator.waitNSlots 1

You can find the previous code integrated with week05 in my plutus-pioneer-program repo:
https://github.com/kindofdev/plutus-pioneer-program-iter3/blob/main/code/week05/src/Week05/WithCustomRedeemer.hs

Lol!  "Kurt is happy" because you've given him a concrete example of how to do this!  You are right, too-- it looks simple enough.  I actually ran into that error you described "must be imported", but I didn't know how to interpret it.  Now, I see what the resolution is.  I highly appreciate this complete answer!

Any security/exploitation problems with an untyped Redeemer? I ask that question under the assumption that unstableMakeIsData is allowing transactions with arbitrary Redeemers for this script.

@jerome, I'd say no, because a Redeemer (Typed or BuiltinData (untyped)) is just data.


text:
Where are the bech32 binaries?
Hi I am trying to convert from hex to bech32.
This repo says that there is a tool which can do this and that the binaries can be found at cardano-wallet releases, however I cannot find them there.  The readme also gives no instructions on how to build the binaries from source. https://github.com/input-output-hk/bech32#usage  Where can I find these binaries?

Hi guys. For anyone who is a dingus like me (unlikely).  they are in the .tar.gz file.  I was confused because they are not present in the zip file

bech32 binaries/cli commands come preinstalled with cardano-wallet software. If you follow the instructions to install cardano-wallet, you'll be able to use bech32 commands from the same executable path (the same is true for cardano-addresses).
Alternatively, if you really don't want to install cardano-wallet, you can download the bech32 binaries here.

so I found the binaries, but jsuk  I have cardano-wallet installed.  v2022-01-18 (git revision: a5085acbd2670c24251cf8d76a4e83c77a2679ba).
i can call cardano-wallet, but the binaries were not automatically added


text:
Please explain types with multiple outputs
I understand basic type signatures like
myFunction :: Int -> String
myFunction a = "Always produce this string"

But in the week 5 lesson, in Free.hs (and similar in the other hs files), I see this type signature (with implementation)
mint :: MintParams -> Contract w FreeSchema Text ()
mint mp = do
    let val     = Value.singleton curSymbol (mpTokenName mp) (mpAmount mp)
        lookups = Constraints.mintingPolicy policy
        tx      = Constraints.mustMintValue val
    ledgerTx <- submitTxConstraintsWith @Void lookups tx
    void $ awaitTxConfirmed $ getCardanoTxId ledgerTx
    Contract.logInfo @String $ printf "forged %s" (show val)

It appears that the function produces multiple different outputs. I cannot reproduce this structure on my own using simple code such as
myAttempt :: Int -> String String
myAttempt a = "Make this" "Make that"

This causes the compiler to complain as follows
*JWB2> :l JWB2.hs
[1 of 1] Compiling JWB2             ( JWB2.hs, interpreted )

JWB2.hs:48:21: error:
    • Expected kind ‘* -> *’, but ‘String’ has kind ‘*’
    • In the type signature: myAttempt :: Int -> String String
   |
48 | myAttempt :: Int -> String String
   |                     ^^^^^^^^^^^^^
Failed, no modules loaded.

Is this a capability added thru one of the LANGUAGE declarations? Or Plutus modules? A partial function? Unique to do blocks? Related to Monads?
Various searches have not provided an explanation, but I'm sure someone here can!

String is a type all by itself so that a type String String does not actually make sense.
However, you can return a tuple of values so that your function would be:
myAttempt :: Int -> (String, String)
myAttempt _a = ("Make this", "Make that")

I added the underscore to _a so that the compiler will not give an "unused parameter" warning.

I think you are misunderstanding the meaning of Contract w FreeSchema Text (). This is one single Contract type. w, FreeSchem, Text, and () are like parametrisation of the type.

That makes sense. But I tried to create parallel syntax using more common data types and my own defined data types and I generate syntax errors. Is this because Contract is a Monad?

What about this example:
f :: Integer -> Maybe Integer
f x = if odd x then Nothing else Just x

Just like here you have Maybe a and you replace a with Integer, in your case you have the (rather complicated) type Contract w s e a where some of the type variables have been replaced with values.
You tried to do String String but String has no variables that you can replace with String - therefore the error about the appropriate kinds:
String :: *, i.e. String is a type, while Maybe :: * - * i.e. you get a type by applying Maybe to a type.


text:
How can I grant an NFT holder a one time action in a web app?
I would like users to be able to perform a one time action on a web app, i.e. claiming one physical item per NFT owned, what would be the best way to keep track of tokens that have already claimed ownership? I have thought of constructing a list of addresses in the web app code but think this may have security issues. Is it possible to do it in a public way so that users can verify themselves?
Thank you!

Integrate with a browser wallet (Nami, ccvault, ...) so users can log in with their wallet on your web-app.
Let the users sign a message to prove they really own the wallet. Check on server side if the signature is correct.
Get all NFTs owned by the wallet from the blockchain. Don't trust the user input here as it could be manipulated. You can run your own node, use https://blockfrost.io or something similar.
Keep track of which NFTs have already been used to claim your physical goods. The address of the owner is not relevant, since the NFT can be sold after redeeming. You can do this in a simple database if you want. Or you could do it on-chain, e.g. by minting a "redeemed" token for each NFT or even updating the NFT metadata (if the policy is not locked yet).

The only two ways would be to keep a database of tokens and their redemption status, or an easier way to do it would be to update a data attribute inside of the NFTs metadata directly. That way everyone can know (even on the secondary market) whether the redemption has been spent or not. This, however, would require an open policy ID.

interesting, i had not considered modifying the nft its self, i will definitely be taking a look at this !


text:
Using `void` vs using `>>` (then) operator
Given a do block which contains these expressions:
void $ submitTx tx
payContract

Would it be feasible to reformat this lines using the then operator, and thus telling the compiler to do something, ignore the output and proceed to do something else? Something like:
submitTx tx >> payContract

If so, what are the benefits of using one over the other? Is any option considered a good or bad practice?

I would say that it’s a matter of taste.

Usually you don't see >>= (bind) and >> (then) inside do blocks--do gives you a more flexible interface with monads and lets you weave in other logic, as you can see in the function you're referring to:
payContract :: Contract () PaySchema Text ()
payContract = do
    pp <- awaitPromise $ endpoint @"pay" return
    let tx = mustPayToPubKey (ppRecipient pp) $ lovelaceValueOf $ ppLovelace pp
    void $ submitTx tx
    payContract

The advantage of a do block is having a more imperative and readable view into the monad.
I usually associate >>= and >> with monad combination outside of do blocks, but I guess there is no reason you couldn't use them inside the block. Feels like mixing and matching, but maybe that's just me; if you're already inside a do block, you might as well use void, <-, etc

There are no benefits of using one over the other. They are equivalent and its simply a matter of choice.

This is an opinion rather than a factual response.  I guarantee that one is more 'readable' than the other and expresses the logic more clearly.  I have always written for clarity first and optimized later.  One may also cost fewer cycles than the other.

That there is no benefit of one over the other is a factual response. The compiler desugars the >>  version to the other so there is zero difference in performance.
Yes, you might find one more readable than the other, but that is an opinion.


text:
How to mint a token on testnet?
Now I am experimenting to mint a token on cardano testnet I have installed the followings like deadalus wallet for testnet and cli tools as well.Then I recived ada from the testnet to the testnet deadalus wallet  Then I have followed thease Instructions over here.
cardano-cli address key-gen \
--verification-key-file payment.vkey \
--signing-key-file payment.skey

cardano-cli address build \
--payment-verification-key-file payment.vkey \
--out-file payment.addr \
--mainnet

cat payment.addr

From the last command which i have executed given me an ada address when I am pasting that address on deadalus wallet it is showing me the address is invalid. I couldnt find much about this from official documentation as well. What should i do now? Where am i going wrong?

Anytime you do things on testnet, you need to replace the --mainnet flag in your CLI commands with the --testnet-magic 1097911063 flag. The address you built above is a mainnet address, which is incompatible with testnet.

Can You give an example script I am seeing this error on my terminal Invalid option --testnet'`

sorry, forgot to include the "magic" option. Edit was applied above ^


text:
Where is the txValidRange default value set?
In lecture 3 of the Plutus Pioneer Program Vesting.hs, I noticed that the example vesting give/ grab endpoints work by waiting a number of slots after the deadline. The script then checks deadlineReached = contains (from $ deadline dat) $ txInfoValidRange info.
However, these docs for txInfoValidRange say that the default range is infinite. In the lecture video and in the playground, I don't see that we set the txInfoValidRange explicitly, so I assumed it was infinite, but that means a from range would never contain it.
I must be misunderstanding the linked documentation. At some point, the txValidRange must be getting set on the transactions submitted through the playground, otherwise, deadlineReached would always be false. I can't find where this default is being set though.
Is this set by Plutus clients? In this case, the Playground?
There is a related question here, but I understand the contains function. What I don't understand is how the txInfoValidRange is set.

This is the flow from Playground to the onchain validator:
Playground (grab) --> endpoints --> grab (offchain contract) --> validator (onchain).
txInfoValidRange is set by grab (offchain contract) in the following expression:
[line 115-117]
tx :: TxConstraints Void Void
tx = mconcat [Constraints.mustSpendScriptOutput oref unitRedeemer | oref <- orefs] <>
             Constraints.mustValidateIn (from now)

where Constraints.mustValidateIn (from now) specifically establishes that the transaction being built must validate from now to the eternity. If you don't set this Constraint, the default txInfoValidRange (all the time) will set.

Ahh, that was the gap in my understanding. The off chain code runs first and sets the TxInfo ValidRange. The validator run onchain and validates the transaction submitted by the offchain code.


text:
How to setup carndano node-socket?
I am executing the following query and then I am getting the following error.
The query I am executing.
cardano-cli query utxo --address $(cat payment.addr) --testnet-magic 1097911063

And the error I am getting.
Command failed: query utxo  Error: Error while looking up environment variable: CARDANO_NODE_SOCKET_PATH  Error: "CARDANO_NODE_SOCKET_PATH"

How do i debug this?

Ensure that cardano-node is running.
open a new terminal window, and enter nano ~/.bashrc
Scroll to the bottom of the file and add the following line:

EXPORT CARDANO_NODE_SOCKET_PATH=/home/user/cardnao/db/socket (or whatever the path is to the socket in your db folder)

Save the file and exit, then in the same terminal window, type: source ~/.bashrc and hit enter.
Now things should work. To check if the socket path is recognized, run:

cardano-cli query tip --testnet-magic 1097911063, and you should receive a sync status update. Comment if you're still getting an error.

How do i know the path of socket?

when you run cardano-node, one of the mandatory flags is to specify a db folder. When you do that, a socket file is automatically created in that folder. CARDANO_NODE_SOCKET_PATH in your ~/.bashrc folder must then be pointed to that socket (following the instructions above)

EXPORT CARDANO_NODE_SOCKET_PATH=/home/user/cardnao/db/socket How do i know /home/user/cardnao/db/socket With what I have to replace this with?


text:
Updating counter on the extended UTXO
I would like to be able to update state on the token that is locked in the smart contract address.
My assumption was that using below code
    getLockingDatum :: Maybe LockingDatum
    getLockingDatum = let os = [ o | o <- txInfoOutputs info, valueOf (txOutValue o) cs tn == 1 ] in
        case os of
        [o] -> lockingDatum o (`findDatum` info)
        _   -> Nothing

    checkIfCounterWasUpdated :: Bool
    checkIfCounterWasUpdated = case getLockingDatum of
        Nothing -> False
        Just ld -> owner     ld      == owner    dat &&
                   currency ld       == currency dat &&
                   token    ld       == token    dat
            -- &&   (counter  ld) + 1 == (counter  dat)

I should be able to take old datum and compared with the incoming one.
However if I uncomment line
-- &&   (counter  ld) + 1 == (counter  dat)
I'm getting this exception:
EvaluationError [\"counter was updated by more than one\",\"PT5\"]
{-# LANGUAGE DataKinds             #-}
{-# LANGUAGE DeriveAnyClass        #-}
{-# LANGUAGE DeriveGeneric         #-}
{-# LANGUAGE FlexibleContexts      #-}
{-# LANGUAGE NoImplicitPrelude     #-}
{-# LANGUAGE OverloadedStrings     #-}
{-# LANGUAGE ScopedTypeVariables   #-}
{-# LANGUAGE TemplateHaskell       #-}
{-# LANGUAGE TypeApplications      #-}
{-# LANGUAGE TypeFamilies          #-}
{-# LANGUAGE TypeOperators         #-}
{-# LANGUAGE NumericUnderscores    #-}
{-# LANGUAGE MultiParamTypeClasses #-}

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

module Week04.Homework where

import           Control.Monad.Freer.Extras as Extras
import           Control.Monad        hiding (fmap)
import           Data.Aeson           (ToJSON, FromJSON)
import           Data.Map             as Map
import           Data.Text            (Text)
import           Data.Default
import           Data.Void            (Void)
import           GHC.Generics         (Generic)
import           Plutus.Contract            as Contract
import           PlutusTx             (Data (..))
import qualified PlutusTx
import           PlutusTx.Prelude     hiding (Semigroup(..), unless)
import           Ledger               hiding (singleton)
import           Ledger.Constraints   (TxConstraints)
import           Ledger.TimeSlot
import qualified Ledger.Constraints   as Constraints
import qualified Ledger.Typed.Scripts as Scripts
import           Ledger.Ada           as Ada
import           Ledger.Value         as Value
import           Playground.Contract  (printJson, printSchemas, ensureKnownCurrencies, stage, ToSchema)
import           Playground.Contract
import           Playground.TH        (mkKnownCurrencies, mkSchemaDefinitions)
import           Playground.Types     (KnownCurrency (..))
import           Prelude              (IO, Semigroup (..), Show (..), String)
import           Text.Printf          (printf)
import           Plutus.Trace.Emulator as Emulator
import           Wallet.Emulator.Wallet
import           Wallet.Emulator.Wallet (Wallet(..))
import           Plutus.V1.Ledger.Value
import           Plutus.Trace.Emulator (EmulatorTrace, EmulatorConfig(..), runEmulatorTraceIO',
                              activateContractWallet)
-- import           Plutus.ChainIndex.Tx ( ChainIndexTx(_citxData) )
import Plutus.ChainIndex.Tx
data BreedAction = Grab | Update
    deriving (Generic, ToJSON, FromJSON)
PlutusTx.makeIsDataIndexed ''BreedAction [ ('Grab,      0)
                                         , ('Update,    1)
                                        ]
PlutusTx.makeLift ''BreedAction

data LockingDatum = LockingDatum
    { owner       :: PaymentPubKeyHash
    , deadline    :: POSIXTime
    , currency    :: CurrencySymbol
    , token       :: TokenName
    , counter     :: Integer
    } deriving Show

PlutusTx.unstableMakeIsData ''LockingDatum

{-# INLINABLE lockingDatum #-}
lockingDatum :: TxOut -> (DatumHash -> Maybe Datum) -> Maybe LockingDatum
lockingDatum o f = do
    dh <- txOutDatum o
    Datum d <- f dh
    PlutusTx.fromBuiltinData d

{-# INLINABLE mkValidator #-}
mkValidator :: LockingDatum -> BreedAction -> ScriptContext -> Bool
mkValidator dat ba ctx = case ba of
        Grab ->
            traceIfFalse "owner's signature missing" signedByowner &&
            traceIfFalse "deadline not reached" deadlineReached
        Update ->
            traceIfFalse "owner's signature missing" signedByowner &&
            traceIfFalse "counter was updated by more than one" checkIfCounterWasUpdated &&
            traceIfFalse "NFT left the script" checkContinuingNFT
  where
    info :: TxInfo
    info = scriptContextTxInfo ctx

    signedByowner :: Bool
    signedByowner = txSignedBy info $ unPaymentPubKeyHash $ owner dat

    deadlineReached :: Bool
    deadlineReached = contains (from $ deadline dat) $ txInfoValidRange info

    tn :: TokenName
    tn = token dat

    cs :: CurrencySymbol
    cs = currency dat

    getLockingDatum :: Maybe LockingDatum
    getLockingDatum = let os = [ o | o <- txInfoOutputs info, valueOf (txOutValue o) cs tn == 1 ] in
        case os of
        [o] -> lockingDatum o (`findDatum` info)
        _   -> Nothing

    checkIfCounterWasUpdated :: Bool
    checkIfCounterWasUpdated = case getLockingDatum of
        Nothing -> False
        Just ld -> owner     ld      == owner    dat &&
                   currency ld       == currency dat &&
                   token    ld       == token    dat
            -- &&   (counter  ld) + 1 == (counter  dat)

    checkContinuingNFT :: Bool
    checkContinuingNFT = let cos = [ co | co <- getContinuingOutputs ctx, valueOf (txOutValue co) cs tn == 1 ] in
        case cos of
            [_] -> True
            _   -> False

data Locking
instance Scripts.ValidatorTypes Locking where
    type instance DatumType Locking = LockingDatum
    type instance RedeemerType Locking = BreedAction

typedValidator :: Scripts.TypedValidator Locking
typedValidator = Scripts.mkTypedValidator @Locking
    $$(PlutusTx.compile [|| mkValidator ||])
    $$(PlutusTx.compile [|| wrap ||])
  where
    wrap = Scripts.wrapValidator @LockingDatum @BreedAction

validator :: Validator
validator = Scripts.validatorScript typedValidator

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

scrAddress :: Ledger.Address
scrAddress = scriptAddress validator

data LockParams = LockParams
    { lpOwner :: !PaymentPubKeyHash
    , lpDeadline    :: !POSIXTime
    , lpAmount      :: !Integer
    , lpCurrency    :: !CurrencySymbol
    , lpToken       :: !TokenName
    , lpCounter     :: !Integer
    } deriving (Generic, ToJSON, FromJSON, ToSchema)

type LockingSchema =
            Endpoint "lock" LockParams
            .\/ Endpoint "grab" ()
            .\/ Endpoint "updcntr" LockParams

lock :: AsContractError e => LockParams -> Contract w s e ()
lock lp = do
    Contract.logInfo @String $ printf "starting"
    let dat = LockingDatum
                { owner       = lpOwner lp
                , deadline    = lpDeadline lp
                , currency    = lpCurrency lp
                , token       = lpToken lp
                , counter     = lpCounter lp
                }
        val = Ada.lovelaceValueOf (lpAmount lp) <> Value.singleton (lpCurrency lp) (lpToken lp) 1
        tx  = Constraints.mustPayToTheScript dat val
    ledgerTx <- submitTxConstraints typedValidator tx
    void $ awaitTxConfirmed $ getCardanoTxId ledgerTx
    Contract.logInfo @String $ printf "locked %d lovelace by %s with deadline %s"
        (lpAmount lp)
        (show $ lpOwner lp)
        (show $ lpDeadline lp)

grab :: forall w s e. AsContractError e => Contract w s e ()
grab = do
    now   <- currentTime
    pkh   <- ownPaymentPubKeyHash
    utxos <- Map.filter (isSuitable pkh now) <$> utxosAt scrAddress
    if Map.null utxos
        then Contract.logInfo @String $ "nothing is locked " ++ show scrAddress
        else do
            let orefs   = fst <$> Map.toList utxos
                lookups = Constraints.unspentOutputs utxos  <>
                          Constraints.otherScript validator
                tx :: TxConstraints Void Void
                tx      = mconcat [Constraints.mustSpendScriptOutput oref $ Redeemer $ PlutusTx.toBuiltinData Grab | oref <- orefs] <>
                          Constraints.mustValidateIn (from now)
            ledgerTx <- submitTxConstraintsWith @Void lookups tx
            Contract.logInfo @String $ "[Grab redeemer] collected locked tokens: " ++ show scrAddress
            void $ awaitTxConfirmed $ getCardanoTxId ledgerTx
  where
    isSuitable :: PaymentPubKeyHash -> POSIXTime -> ChainIndexTxOut -> Bool
    isSuitable pkh now o = case _ciTxOutDatum o of
        Left _          -> False
        Right (Datum e) -> case PlutusTx.fromBuiltinData e of
            Nothing -> False
            Just d  -> owner d == pkh && deadline d <= now

updcntr :: forall w s e. AsContractError e => LockParams -> Contract w s e ()
updcntr lp = do
    tkn   <- findLocked (lpCurrency lp, lpToken lp)
    case tkn of
        Nothing -> Contract.logError @String "No token was locked"
        Just (oref, o, lockedDat) -> do
            let r       = Redeemer $ PlutusTx.toBuiltinData Update
                val     = Value.singleton (currency lockedDat) (token lockedDat) 1 <> Ada.lovelaceValueOf (lpAmount lp)
                newCounter  = (counter lockedDat) + 1
                lockedDat'   = lockedDat { counter = newCounter }
                lookups = Constraints.typedValidatorLookups typedValidator <>
                          Constraints.otherScript validator                    <>
                          Constraints.unspentOutputs (Map.singleton oref o)
                tx      = Constraints.mustSpendScriptOutput oref r <>
                          Constraints.mustPayToTheScript lockedDat' val
            Contract.logInfo $ "Updating counter old datum: " ++ show lockedDat ++ " new datum: " ++ show lockedDat'
            ledgerTx <- submitTxConstraintsWith lookups tx
            void $ awaitTxConfirmed $ getCardanoTxId ledgerTx
            Contract.logInfo @String "Counter was updated"

findLocked :: forall w s e. AsContractError e => (CurrencySymbol, TokenName) -> Contract w s e (Maybe (TxOutRef, ChainIndexTxOut, LockingDatum))
findLocked (cs, tn) = do
    utxos <- Map.filter f <$> utxosTxOutTxAt scrAddress
    return $ case Map.toList utxos of
        [(oref, (o, citx))] -> do
            bd <- lockingDatum (toTxOut o) $ \dh -> Map.lookup dh $ _citxData citx
            Just (oref, o, bd)
        _           -> Nothing

  where
    f :: (ChainIndexTxOut, Plutus.ChainIndex.Tx.ChainIndexTx) -> Bool
    f (o, _) = valueOf (txOutValue $ toTxOut o) cs tn == 1

endpoints :: Contract () LockingSchema Text ()
endpoints = awaitPromise (lock' `select` grab' `select` updcntr') >> endpoints
  where
    lock' = endpoint @"lock" lock
    grab' = endpoint @"grab" $ const grab
    updcntr' = endpoint @"updcntr" updcntr

mkSchemaDefinitions ''LockingSchema

myToken :: KnownCurrency
myToken = KnownCurrency (ValidatorHash "f") "Token" (TokenName "T" :| [])

mkKnownCurrencies ['myToken]

testTrace :: Integer -> EmulatorTrace ()
testTrace lov = do
    end <- activateContractWallet (knownWallet 1) endpoints
    let ownWallet = knownWallet 1
        ownPkh       = mockWalletPaymentPubKeyHash ownWallet
        d           = slotToEndPOSIXTime def 10
        pp  = LockParams {
                      lpOwner = ownPkh
                    , lpDeadline = d
                    , lpAmount = lov
                    , lpCurrency = CurrencySymbol { unCurrencySymbol = "f"}
                    , lpToken    = TokenName { unTokenName = "T" }
                    , lpCounter  = 0
                    }

        pp1  = LockParams {
                      lpOwner = ownPkh
                    , lpDeadline = d
                    , lpAmount = lov
                    , lpCurrency = CurrencySymbol { unCurrencySymbol = "f"}
                    , lpToken    = TokenName { unTokenName = "T" }
                    , lpCounter  = 1
                    }

    Extras.logInfo $ "ownerPkh: " ++ show ownPkh ++ " wallet: " ++ show ownWallet ++ " params: "

    callEndpoint @"lock" end pp
    void $ Emulator.waitNSlots 12

    Extras.logInfo @String "calling updcntr for first time"
    callEndpoint @"updcntr" end pp1
    void $ Emulator.waitNSlots 1
    Extras.logInfo @String "called updcntr for first time"

    -- Extras.logInfo @String "calling updcntr for second time"
    -- callEndpoint @"updcntr" end pp2
    -- void $ Emulator.waitNSlots 1
    -- Extras.logInfo @String "calling updcntr for second time"

testLock :: IO ()
testLock = do
    let curr = CurrencySymbol { unCurrencySymbol = "f"}
        tok  = TokenName { unTokenName = "T"}
        dist = Map.fromList [ (knownWallet 1, Ada.lovelaceValueOf 100_000_000 <> Value.singleton curr tok 1)
                             , (knownWallet 2, Ada.lovelaceValueOf 25_000_000)]
        emCfg = EmulatorConfig (Left dist) def def
    runEmulatorTraceIO' def emCfg (testTrace 15_000_000)

any idea what I'm doing wrong?

From what I see in your code I understand that you want to check that the new datum increases the counter of the old datum in 1. If this statement is correct, the fix is easy.
checkIfCounterWasUpdated :: Bool
checkIfCounterWasUpdated = case getLockingDatum of
    Nothing -> False
    Just ld -> owner ld   == owner    dat &&
        currency ld       == currency dat &&
        token    ld       == token    dat &&
     -- (counter  ld) + 1 == (counter  dat)
     -- (counter  ld)     == (counter  dat) + 1  -- This works
        counter  ld       == succ (counter dat)  -- This works and it's more idiomatic

I've tested it and it works.
As a side note, I'd say that your use case fits great with the Plutus.Contract.StateMachine library.


text:
How can I establish the communication between my Flutter App and Cardano Blockchain?
Did anybody succeed with building a Flutter App that can communicate with the Cardano Blockchain? I would be happy if I could get some more guidance.
I'm trying to build a cross-platform Dapp, so I do not want to rely on running a full node. So Blockfrost.io comes in handy. Unfortunately there seems to be no official Dart Package.
I've already tried with this blockfrost package but somehow I did not manage to put everything together correctly. Did it work for any of you?
I wanted to reach out before I try to build Flutter-Plugins for Android and iOS using the official Java-/Kotlin-/Swift-SDKs provided by Blockfrost.

It appears that blockfrost is having a few issues atm. A blockfrost dev commented on my question here https://cardano.stackexchange.com/questions/6934/ppviewhashesdontmatch-and-unspendableutxonodatumhash-error-on-redeeming-funds-fr?noredirect=1#comment3186_6934.

That's not what I'm facing. It's not that I get errors from Blockfrost API. I'm struggling to setup the communication in the first place. I might have to ask that question in a Flutter-specific forum maybe.
Anyway I thought maybe someone can help. If not I will update this post and let others know.

I would check out this package, https://pub.dev/packages/blockfrost.  I know this package is being used in at least one place for the Manzano app which can be found here, https://manzano.studio/#/

This is the correct answer. Use the library. I just struggled with the setup. If others struggle with Flutter/Cardano aswell I'm answering what I've been doing to get things going.

I got it working for me, these steps may work for you.

Work through this tutorial from flutter.dev
Afterwards it should be easy for you to change the code. Instead of class Album you want to have class CurrentBackendTime. Instead of the function <Future>Album fetchAlbum() you want to have <Future>CurrentBackendTime fetchCurrentBackendTime() and so on. From the API-Docs for GET /health/clock you can learn how to parse data from JSON, which datatypes are required and what data you will get.
Since GET /health/clock requires authentication (see API-Docs again) you need to create an HTTP-Header within your <Future>CurrentBackendTime fetchCurrentBackendTime() function:
final Map<String, String> authHeader = Map<String, String>();
authHeader['project_id'] = 'PUT YOUR BLOCKFROST API KEY IN HERE!'

and then you just add the header to your http.get()-Call:
final response = await http.get(
 Uri.parse('https://cardano-mainnet.blockfrost.io/api/v0/health/clock'),
 headers: authHeader,
);

You could now create more classes like class AccountRewardHistory, class AddressDetails for all the objects you want to GET from blockfrost's API. Or you just use what you've learnt, and apply it when using a library like blockfrost.


text:
Question - is there a simple example end-to-end dApp on Cardano
as the title says... is there any example of a simple application built on cardano? I tried to find one but apparently there is none. I want to start learning by interacting directly through code and learn on the way.
If someone already wrote a "hello world" application with a front and back end interacting with cardano's blockchain, please share your github repo.
Thanks for your help!!

Check out the Plutus Pioneer's lecture notes. It is a whole series of lectures and exercises to help beginners get started with Cardano smart contracts. There is even one exercise titled "HelloWorld Script". In addition to this there are video supplements by Lars Brunjes, IOHK's director of education.


text:
Documentation for filtering through the inputs of a Plutus Script
I Have 1000 utxo's sitting at a script address with unique datums is there documentation for a validator so that when collectFromScript is called it only pulls 1 utxo based on the user input matching with the datum of one of the utxo's sitting at the script?

Do you want to filter by datum in offchain code?

I want to filter by off-chain code preferably

Did my answer solve your doubt?

yes for sure thank you so much could another way to do this also be mustSpendScriptOutput

You can achieve the same thing in 2 steps: filter the map and then use mustSpendScriptOutput like in the following code snippet I've created for you: https://gist.github.com/kindofdev/47cf9e650fbd6a651e471a5e67462a9a
Don't forget up vote the answer ;)

In order to collect and filter by datum in offchain code you can use collectFromScriptFilter from Plutus.Contract. I've implemented a simple example showing the use case.
{-# LANGUAGE DataKinds           #-}
{-# LANGUAGE DerivingStrategies  #-}
{-# LANGUAGE DeriveAnyClass      #-}
{-# LANGUAGE DeriveGeneric       #-}
{-# LANGUAGE FlexibleContexts    #-}
{-# LANGUAGE NoImplicitPrelude   #-}
{-# LANGUAGE NumericUnderscores  #-}
{-# LANGUAGE OverloadedStrings   #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell     #-}
{-# LANGUAGE TypeApplications    #-}
{-# LANGUAGE TypeFamilies        #-}
{-# LANGUAGE TypeOperators       #-}
{-# LANGUAGE RecordWildCards     #-}

module Week05.OffchainFilterByDatumAndCollect where

import           Control.Monad        hiding (fmap)
import           Data.Aeson           (FromJSON, ToJSON)
import           Data.Text            (Text)
import           GHC.Generics         (Generic)
import           Plutus.Contract
import           Ledger               hiding (singleton)
import           Ledger.Ada           as Ada
import           Ledger.Constraints   as Constraints
import qualified Ledger.Typed.Scripts as Scripts
import           Plutus.Trace.Emulator  as Emulator
import qualified PlutusTx
import           PlutusTx.Prelude     hiding (Semigroup(..), unless)
import           Prelude              (IO, Semigroup (..), String, Show(..))
import qualified Prelude              as Haskell
import           Text.Printf          (printf)
import qualified Ledger.Tx            as Tx
import           Wallet.Emulator.Wallet ( knownWallet )

type Field1 = Integer
type Field2 = Integer

data MyParams = MyParams
    { mpField1 :: Field1
    , mpField2 :: Field2
    } deriving stock (Haskell.Eq, Haskell.Show, Generic)
      deriving anyclass (ToJSON, FromJSON)

data MyDatum = MyDatum
    { mdField1 :: Field1
    , myField2 :: Field2
    } deriving Show

PlutusTx.unstableMakeIsData ''MyDatum

{-# INLINABLE mkValidator #-}
mkValidator :: MyDatum -> () -> ScriptContext -> Bool
mkValidator _ _ _ = True

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

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

validator :: Validator
validator = Scripts.validatorScript typedValidator

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

scrAddress :: Ledger.Address
scrAddress = scriptAddress validator

type GiftSchema =
            Endpoint "give" (Integer, MyParams)
        .\/ Endpoint "grab" MyParams

give :: AsContractError e => (Integer, MyParams) -> Contract w s e ()
give (amount, MyParams{..}) = do
    let dat = MyDatum mpField1 mpField2
        lookups = Constraints.typedValidatorLookups typedValidator
        tx      = mustPayToTheScript dat $ Ada.lovelaceValueOf amount
    utx  <- mkTxConstraints lookups tx
    txid <- getCardanoTxId <$> submitUnbalancedTx (Constraints.adjustUnbalancedTx utx)
    void $ awaitTxConfirmed txid
    logInfo @String $ printf "made a gift of %d lovelace" amount

grab :: forall w s e. AsContractError e => MyParams -> Contract w s e ()
grab MyParams{..} = do
    utxos <- utxosAt scrAddress
    let dat     = MyDatum mpField1 mpField2
        flt _ ciTxOut = either id Ledger.datumHash (Tx._ciTxOutDatum ciTxOut) == Ledger.datumHash (Datum (PlutusTx.toBuiltinData dat))
        lookups = Constraints.unspentOutputs utxos <>
                  Constraints.typedValidatorLookups typedValidator
        tx      = collectFromScriptFilter flt utxos ()
    utx  <- mkTxConstraints lookups tx
    txid <- getCardanoTxId <$> submitUnbalancedTx (Constraints.adjustUnbalancedTx utx)
    void $ awaitTxConfirmed txid
    logInfo @String $ "collected gifts"

endpoints :: Contract () GiftSchema Text ()
endpoints = awaitPromise (give' `select` grab') >> endpoints
  where
    give' = endpoint @"give" give
    grab' = endpoint @"grab" grab

-- w1 gives 10 (datum1) + 20 (datum2)
-- w2 grab  10 (datum1)
-- script locks 20 (datum2)
test :: IO ()
test = runEmulatorTraceIO $ do
    let params1 = MyParams 1 1
        params2 = MyParams 2 2
    h1 <- activateContractWallet (knownWallet 1) endpoints
    h2 <- activateContractWallet (knownWallet 2) endpoints
    callEndpoint @"give" h1 (10_000_000, params1)
    void $ Emulator.waitNSlots 1
    callEndpoint @"give" h1 (20_000_000, params2)
    void $ Emulator.waitNSlots 1
    callEndpoint @"grab" h2 params1
    void $ Emulator.waitNSlots 1

In plutus-use-cases repo you can find more interesting examples:

https://github.com/input-output-hk/plutus-apps/blob/main/plutus-use-cases/src/Plutus/Contracts/Crowdfunding.hs

https://github.com/input-output-hk/plutus-apps/blob/main/plutus-use-cases/src/Plutus/Contracts/Escrow.hs


text:
How Cardano is going to be more digital inclusive in sub Saharan Africa
what API's is Cardano RealFi  going to use and how do we also integrate local languages on the Plutus platform

There are many different developments at the moment that could help with inclusion in Africa. While this is one of the main missions for Cardano, it doesn't mean it is going to be in the short term.
Keep in mind Cardano is not ready yet: the full roadmap includes 5 different stages, of which we are currently between Goguen (smart contracts) and Basho (scaling). Although some milestones from other phases, like decentralization and governance, keep happening in parallel.
I identify the following features and research as key for the development of Cardano in Africa and many other underdeveloped continents:

Decentralized identity: https://atalaprism.io/app
Light wallets: https://summit.cardano.org/sessions/light-wallets-the-path-to-accessibility-for-all
Offline solutions for areas with connectivity issues: https://forum.cardano.org/t/cardano-can-give-crypto-a-cash-like-experience/33499

And in addition to all this, there is also room for the community to propose its own ideas and projects through Project Catalyst: there is a specific challenge for Africa called "Grow Africa, Grow Cardano".

Also check Cardano Catalyst https://cardano.ideascale.com for projects being worked on. There has been a lot of focus and funding towards African based projects. Feel free to propose your own projects if you see a gap or an opportunity.

Thanks for the comment. I will add this to the answer.

The very APIs that are live today and growing from providers like BlockFrost.

Plutus Platform is a living project and so will not only require a capable multilingual/internationalisation team but also one that is well trained in the technical aspects, to keep up with changes across board.


text:
Properly (safely) verify that transaction contains an Cardano Native Token or NFT
All the available on-chain validator programs that limit certain redeemer actions to transactions containing an NFT use
hasToken :: TxOut -> Bool
hasToken txOut = assetClassValueOf (txOutValue txOut) (AssetClass{unAssetClass = ("something", TokenName "somename")}) == 1

Including Plutus Pioneer week 6
Is there anything preventing a malicious user from minting a token with a currency symbol "something" and TokenName "somename" and then just performing the transaction? (edited)
How can on-chain validators make sure that the redeemer action can only be completed by a transaction containing a Cardano Native Token or NFT with the given CurrencySymbol, TokenName AND PolicyId so that we can make sure that the asset was not minted by a malicious party.

The currency symbol is the hash of a minting policy script. This includes data like the paymentpubkey hash that can burn and mint. If someone wanted to use the same currency symbol as you, they would need the keys to the address that can mint or burn. Without those keys, they wouldn't be able to sign minting or burning transactions. Keep those keys safe.
I believe in the previous week (week 5), there was a lecture on a more realistic minting policy that specifies a paymentpubkey hash to allow minting.


text:
Why is the eUTxO model more amenable to static and formal analysis?
I've heard that the eUTxO model is more amenable to static and formal analysis than the account model. If true, why is that?
I understand that the account model makes formal and static analysis difficult because of the nature of global state. For example, if smart contract a interacts with smart contracts b and c, a formal analysis of smart contract a requires formal analysis of contracts b and c (and all of their dependencies). Is that correct?
If the above is correct, don't similar ideas apply to the eUTxO model?
How exactly does the local nature of UTxOs make this model more amenable (if at all) to static and formal analysis?

The interactions between the different contracts are simpler and stateless. In a stateful model like Ethereum's, you can have contract a call contract b and contract b call contract c, and then contract c can call back contract b while, at the same time, b is still waiting for contract c to answer. And during the calls, the state of each of the contracts may change.
So reasoning about this kind of interactions is more complicated than reasoning about pure predicates (functions that return a boolean value, like validators) that only depend on the contents of the transaction that is being validated. In other words, the computation that the different validators require does not produce side-effects that affect each other

Ah! That's seems like the core insight I was missing, that validators in eUTxO are pure predicates without side effects. As a follow up, can/do smart contracts in the eUTxO model "call out" to other smart contracts? I have a strong feeling that they can't but I'm still not confident in my understanding of the technology.

Another follow up question, you say The interactions between the different contracts are simpler and stateless - I thought the datum is used to track state. From the paper: and a datum δ, where δ contains arbitrary contract-specific data and datum δmsc stores the machine state. Do you mind clarifying?

As a follow up, can/do smart contracts in the eUTxO model "call out"
to other smart contracts?

A smart contract (plutus script) can only be triggered by a transaction from a wallet.

Another follow up question, you say The interactions between the different > contracts are simpler and stateless

A Plutus script can see the whole transaction (all inputs of txn, all outputs, redeemer and datum). Arbitrary data (state) can be stored within the datum. But the context is restricted and so the only way the script can persist state or pass data (state) to another script is via a EUTxO which has a datum.


text:
Re-Delegation Smart Contract
Prelude: I have a micro-cardano-pool ,less than 10K include 3 deligators (my friends). Despite the sike of the pool, I would like my pool be an active element in the mainnet network. Therefore I decided to participate in the  interesting small-pools cooperative where all participants delegates their stake to a certain pool (from the programm) for several epochs. The number of epochs that allocated to the current active pool is a function of the stake contributed by that pool to the program in the recent past.
Current state : My friends and me delegate our stakes eccording to the program schedule (each one his stake).
Proposal : My proposal is to create a smart contract where few delegators  will move their stake to this contract and only one (contract manager) could delegate the whole stake of the smart contract to a certain pool. Every participant (include contract manager) can pull  only his part from the contract .
Question : Is it possible to delegate a smart contract’s stake ?
What are the alternatives to the above smart contract?

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

If staking rights are being managed by a single trusted entity, then smart contracts are not necessary for your schema. Rather, you can use "franken-addresses", which are addresses built using multiple payment keys, but a single staking key.
In short, you and your peers may generate your own payment key pairs using cardano-cli, cardano-wallet, or whatever derivation path(s) you prefer. Your "staking manager" then generates their staking key-pair using similar methods. Finally, addresses are built with cardano-cli address build for each participant using their payment.vkey and the manager's stake.vkey.
Now, every participant gets their own wallet that they can deposit/withdraw from themselves, while all the wallets' staking rights are controlled by a single keyholder.

Note: if implemented, the cohort must agree on a scheme as to who will be paying fees. As it stands, each wallet will require it's own staking certificate, which costs 2 ADA, plus standard tx-fee costs for delegation/redelegation.
Pro tip: you can save on some tx-fees if you submit the staking certificates all in single transaction.

On a slightly tangential note, check out the Conclave Paper by IOHK - really cool idea for collective pool management.

Yes, a smart contract (script address) can delegate.
An example plutus script address from week 2 in the pioneers course is shown below:
Address {addressCredential = ScriptCredential 67f33146617a5e61936081db3b2117cbf59bd2123748f58ac9678656, addressStakingCredential = Nothing}

Note the parameter addressStakingCredential which allows a script address to be staked against a pool.

Check out this article - it's pretty well written and explains the inner workings of how delegation works using Plutus!
Liqwid Labs Stake Validators


text:
What do we currently know about the Hydra tail protocol?
The Hydra version that has already been published in the Hydra and Interhead Hydra papers requires all participants to be online at all times. According to this IOHK blog post and this presentation the so-called tail protocol is supposed to make Hydra usable for low-availability clients such as mobile phones.
Beyond a few mentions I couldn't find any explanation on how the Hydra tail protocol will actually work. Do we have an approximate idea how this protocol is going to work or any similar protocols from other blockchains?

Charles Hoskinson mentioned Plasma here in the context of Hydra so maybe the tail protocol will work similarly to Plasma.

There is some information about the Hydra tail protocol on the GitHub repo Wiki

Tail
In a head, all participants must be online - a symmetric construction. In contrast to that, tails are asymmetric: there is a server, which is always online and responsive, with many clients, which are typically offline (e.g. apps on smartphones). The challenge of the tail is, that servers could cheat on the clients (especially when they are offline). The Hydra Tail protocol tries to solve this using two mechanisms: (1) the server needs to put a collatoral on the mainchain, which he could lose when he cheats and (2) a Challenge-Response-Protocol on the mainchain with which clients can dispute claims by a server.

Head-Tail communication
When multiple Tail servers form a Hydra Head together, we can enable clients of one Tail to communicate with clients of another Tail.

We will have a much better sense of the Hydra Tail protocol once the research paper(s) come out. For now, we can infer its functionality based on some of the design patterns of projects currently building on the Hydra family. For example, SingularityNET's HyperCycle sidechain whitepaper discusses CSL, Plutus, and Hydra integrations, including some talk of Hydra Tail.
In short, Hydra Head is a protocol for validator rings - synchronous, permissioned, high-speed execution environments with CSL snapshots. This is a good way for certain sidechains to interface with Cardano, though others like Hypercycle require that some consensus agents may be partially or completely offline (semi-synchronous or asynchronous). Additional protocols - Hydra Tail - are necessary to account for such agents.
Do note however: the authors of the Hypercycle whitepaper mention that the Hydra Tail protocol is "not yet publicly well specified", and further state the intention "to create a custom version of the Hydra tail protocol
that suits Hypercycle’s needs, incorporating mechanisms and ideas beyond
those that have previous occurred in the Cardano sphere."
TBE when Hydra Tail paper comes out


text:
How to get the return type of a contract
I was reviewing the code from https://github.com/input-output-hk/plutus-pioneer-program/blob/main/code/week05/src/Week05/NFT.hs and I don't understand why this section does not cause a compile error.
utxos <- utxosAt $ npAddress np
    case Map.keys utxos of
        []       -> Contract.logError @String "no utxo found"
        oref : _ -> do

utxosAt :: forall w s e. AsContractError e => Address -> Contract w s e (Map TxOutRef ChainIndexTxOut)

keys :: Map k v -> [k]

My expectation is that the variable utxos has type Contract w s e (Map TxOutRef ChainIndexTxOut). This should cause an error on Map.keys utxos, but it doesn't.
Edit:
My code:
getNFT :: Wallet -> Value
        getNFT w = do
            utxos <- utxosAt $ mockWalletAddress w
            case getValue utxos of
                Just v -> v
                Nothing -> Ada.lovelaceValueOf 1000000

The type of getValue is getValue :: Map.Map TxOutRef ChainIndexTxOut -> Maybe Value
The errors I am getting are:
 error:
    • Couldn't match expected type ‘Value’
                  with actual type ‘Contract w0 s0 e0 b0’
    • In a stmt of a 'do' block: utxos <- utxosAt $ mockWalletAddress w
      In the expression:
        do utxos <- utxosAt $ mockWalletAddress w
           case getValue utxos of
             Just v -> v
             Nothing -> lovelaceValueOf 1000000
      In an equation for ‘getNFT’:
          getNFT w
            = do utxos <- utxosAt $ mockWalletAddress w
                 case getValue utxos of
                   Just v -> v
                   Nothing -> lovelaceValueOf 1000000
    |
179 |             utxos <- utxosAt $ mockWalletAddress w
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Compilation Error, Line 181, Column 27 (jump)
 error:
    • Couldn't match expected type ‘Contract w0 s0 e0 b0’
                  with actual type ‘Value’
    • In the expression: v
      In a case alternative: Just v -> v
      In a stmt of a 'do' block:
        case getValue utxos of
          Just v -> v
          Nothing -> lovelaceValueOf 1000000
    |
181 |                 Just v -> v
    |                           ^
Compilation Error, Line 182, Column 28 (jump)
 error:
    • Couldn't match expected type ‘Contract w0 s0 e0 b0’
                  with actual type ‘Value’
    • In the expression: lovelaceValueOf 1000000
      In a case alternative: Nothing -> lovelaceValueOf 1000000
      In a stmt of a 'do' block:
        case getValue utxos of
          Just v -> v
          Nothing -> lovelaceValueOf 1000000
    |
182 |                 Nothing -> Ada.lovelaceValueOf 1000000
    |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^

The entire computation is in the Contract monad and we use the do notation. Thus when we write utxos <- utxosAt $ npAddress np, the type of utxos is Map TxOutRef ChainIndexTxOut, so everything typechecks.
A simpler example:
import Text.Read
plusOne :: String -> Maybe Integer
plusOne s = do
 x <- readMaybe s :: Maybe Integer
 return $ x + 1

The type of readMaybe is (here) String -> Maybe Integer, but since we are after do, x is of type Integer, not Maybe Integer. So plusOne "3" is Just 4.

Thank you for taking the time to help me. I verified your response, read up on do notation and decided to try using this concept in my own project. I'm not getting the results I expected and edited my original post in hopes you could take a look for me.

The problem is that getNFT :: Wallet -> Value and Value is not a Monad, so you can't use the do notation there. Also,utxosAt is a computation in the Contract monad, so maybe you want to change to getNFT :: Wallet -> Contract w s e Value, where you might have concrete types for the variables w, s, e. Then you should also have return v on one case branch, and accordingly return on the other branch.

I'm not sure this is the right place, but I'll explain a bit more: if you write a function f :: String -> Integer you can't use do - it's just for instances of the Monad class. Also, you can't mix the monads: in a function g :: a -> Maybe b you can use do but you can't write x <- h y where h :: y -> m x and m is another monad than Maybe - note that I use y both for a type and a value of that type, to simplify matters.

through your advice I was able to fix my functions and gain a better understanding of how Monads work. Having my function getNFT return a Contract monad causes another problem for me because I need to pass the Value in Contract w s e Value into mustPayToPubKey :: forall i o. PaymentPubKeyHash -> Value -> TxConstraints i o

If you share your whole code with me, I'll try to help. I would guess you must replace a let v = getNFT ... with v <- getNFT ..., as mint is in the Contract monad already.

https://github.com/DappDeveloper1/Royalty/blob/main/Royalty.hs ---- you'll find that it currently doesn't compile because getNFT returns a Contract and the nft variable in SellParams expects a Value. If I change SellParams to expect a Contract Value, it creates another problem because Contract does not support Show, Generic, FromJSON, and ToJSON

You shouldn't have  a Contract in SellParams, it's not how it's done. And you also can't have nft = getNFT ... there because you expect a Value and get a Contract ... Value. You also can't say ǹft <- getNFT ... before the callEndpoint because you are in the EmulatorTrace monad and this computation is in the Contract monad. It seems to me you should make getNFT  a part of sell - this is where it conceptually belongs.


text:
Details on Mamba?
I've heard Charles mention that Mamba is being actively worked on and might be released in 2022 but I haven't been able to find much information about it.
This reddit post suggests that Mamba will be powered by IELE. This blog post by IOHK suggests that Mamba is in the 2022 roadmap.
Where can I learn more about Mamba? Do they have documentation similar to Milkomeda? I've tried searching for this information but haven't been successful (maybe I have searched hard enough?).

Was just recently mentioned in one of the videos, made by Charles:
https://youtu.be/H9wAyW_EcDA?t=484

looking forward to the blog post he said they'll be releasing!


text:
How to add 'ToSchema' to Address (in Playground)?
I'm doing homework2 of week05 (cohort3). My contract runs fine in the repl, but when I try it in the playground, I'm running into an issue. It fails on this line:
mkSchemaDefinitions ''NFTSchema

I changed the schema a bit, so that the mint endpoint takes an NFTSchema, not an Address:

data NFTParams = MintParams
  {
    mpAddress :: !Address
  } deriving (Generic, ToJSON, FromJSON, ToSchema)

type NFTSchema = Endpoint "mint" NFTParams

However, it seems Address cannot (automatically) be turned to a schema:
Compilation Error, Line 67, Column 42 (jump)
 error:
    • No instance for (ToSchema Address)
        arising from the 'deriving' clause of a data type declaration
      Possible fix:
        use a standalone 'deriving instance' declaration,
          so you can specify the instance context yourself
    • When deriving the instance for (ToSchema NFTParams)
   |
67 |   } deriving (Generic, ToJSON, FromJSON, ToSchema)
   |

How can one make the Address parameter in a schema work in the playground? (Stated another way: How can one make ToSchema address work?)
Failing code: https://gitlab.com/moment-4/courses/plutus-pioneer/plutus-pioneer-program/-/tree/homework05.2_ToSchema_Failure (with ToSchema)
Working code: https://gitlab.com/moment-4/courses/plutus-pioneer/plutus-pioneer-program/-/tree/week05.homework2 (without ToSchema)
Thx

I have the same issue.