text:
How to Deploy / Write NFT Minting Plutus Script?
I am following through the third cohort PPP. With a week of course break, I wish to consolidate my understanding through practice. One exercise is to go through the deployment process of an NFT:

Construct the plutus script (e.g. homework of week 5)
Test it on the plutus playground / run the EmulatorTrace
Write the plutus file through a script like week 3's Deploy.hs.
Build & Submit the transaction on testnet

Following through Lars's lecture, there is no problem for step 1-2. However, I got stuck at step 3. The two relevant lines from week 3's Deploy.hs should be:
writeValidator :: FilePath -> Ledger.Validator -> IO (Either (FileError ()) ())
writeValidator file = writeFileTextEnvelope @(PlutusScript PlutusScriptV1) file Nothing . PlutusScriptSerialised . SBS.toShort . LBS.toStrict . serialise . Ledger.unValidatorScript

writeVestingValidator :: IO (Either (FileError ()) ())
writeVestingValidator = writeValidator "/Users/whatever/Desktop/Plutus-Pioneer-Program/testnet/vesting.plutus" $ validator $ VestingParam
    { beneficiary = Ledger.PaymentPubKeyHash "0d26b900ffa6a3234166ed76467e80fbd8e1f6bad938f75cb884ef6b"
    , deadline    = 1645113135000
    }

The logic should be calling the validator function from the Parameterized.hs at writeVestingValidator, then put it in writeValidator to output the plutus file. However, it cannot directly copy and paste for week 5's NFT haskell scripts as the Ledger.unValidatorScript takes in a Validator as parameter while there is no Validator type inside the NFT policy script.
I have found unMintingPolicyScript in the haddock to replace unValidatorScript, but to no avail. My final attempt is like below:
writeValidator :: FilePath -> Ledger.Validator -> IO (Either (FileError ()) ())
writeValidator file = writeFileTextEnvelope @(PlutusScript PlutusScriptV1) file Nothing . PlutusScriptSerialised . SBS.toShort . LBS.toStrict . serialise . Ledger.unMintingPolicyScript

writeNFTValidator :: IO (Either (FileError ()) ())
writeNFTValidator = writeValidator "/Users/whatever/Desktop/Plutus-Pioneer-Program/testnet/nft/mint-TokenWithMeta.plutus" $ (policy (Ledger.TxOutRef "f79a3a51ecc200b6ccfdb5d083652787fc3c389a30d9d5b75bcd883428b9c9d5#0") (TokenName "TestNFT"))

Sorry its kind of a mess, But somehow I get stuck here.
I have tried to look at different guides, the first is from official Cardano documentation https://developers.cardano.org/docs/native-tokens/minting-nfts/. It doesn't solve my doubt as it seems not using plutus script to mint the NFT.
Another guide (Is there a good tutorial to mint Cardano NFT using plutus script?) has a walk through on deploying NFT plutus script, however, it uses a cabal command link cabal run create-nft-script -- PlutusScriptNFT 6c1160302bff7c84b347e6c9c1cf78cbafc8821efc730f6271589fcd848635f7#0 to serve the purpose. However, I want to perform the write script through haskell script so it can be more repeatable when I start building more complex validator or policy.

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


text:
Is there an open source plutus voting dapp?
I am interested in holding decentralized votes for a DAO like system. I am wondering if an audited standard has been put in place that enables users to place votes on the blockchain or if anyone could share some resources with me regarding the topic.
I feel like this is quite an important topic and building a secure, straight forward to use infrastructure for DAO's to implement votes would definitely encourage more building on Cardano!
Many thanks!

IOG provide examples of various common things.
https://github.com/input-output-hk/plutus-apps/tree/main/plutus-use-cases
This includes multisig type functionality which can be used akin to voting depending on the use case.
Also there is a module entitled governance.
They should provide a starting point

At the current time I have found no implementation of a voting dapp for DAO's. But of course you could make one yourself. As Waalge suggested you could use some multisig functionality to to vote with a group of people.
Another and perhaps better option is to implement a Mixing net, here's  a paper about it. In this protocol a per-selected group of parties form a group of mixing nodes. The voting participants can post their vote via encryption anonymously on the blockchain. These mixing nodes than shuffle the votes and decrypt them together. The result is a verifiable anonymous immutable voting system.
The security of the protocol is fully determined by the chosen mixing nodes. Each of the nodes has a piece of the shuffle and if they share/combine that knowledge the anonymity could be broken. Now if every voter is also a mixer node the protocol is completely secure since only if all parties agree to publish their shuffle the anonymity is broken. But note that in this case if a 1000 people vote and all parties need to mix its quite expensive and cumbersome to perform.
That said, both the mixing net and the multisig voting systems are implementations where all voters have exactly the same voting power. One could extend this by allowing some voters to vote multiple times with other signatures.
Hope this helps!

source: Stack Exchange

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

sort: votes


text:
unable to start plutus-playground-server after full rebuild --> /bin/plutus-playground-server: No such file or directory
After having to completely re-install an OS and setup a development environment. attempting to run the plutus-playground-server after building it wiht nix-build -A plutus-playground.server once in nix-shell I get the error:
[nix-shell:~/plutus-apps/plutus-playground-server]$ plutus-playground-server
plutus-playground-server: for development use only
/nix/store/fm77y43lzpgnay4pyc48jwpln0lnmrk3-plutus-playground-server/bin/plutus-playground-server: line 3: nix-build: command not found
/nix/store/fm77y43lzpgnay4pyc48jwpln0lnmrk3-plutus-playground-server/bin/plutus-playground-server: line 10: nix-build: command not found
/nix/store/fm77y43lzpgnay4pyc48jwpln0lnmrk3-plutus-playground-server/bin/plutus-playground-server: line 10: /bin/plutus-playground-server: No such file or directory

What ive tired:
completely deleting /nix/store
deleting plutus-apps and clonging.
various tags:
ea0ca4e9f9821a9dbfc5255fa0f42b6f2b3887c4
week01:
41149926c108c71831cfe8d244c83b0ee4bf5c8a
week05:
62efdd2bfab3e076d40e07f8f4d7864a7f2ccc91
OS: Ubuntu 20.04,
nix (Nix) 2.6.1

what is to 'to source the nix profile.'

Ok turns out im loosing my mind. I had forgotten to source the nix profile.

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


text:
Script Witness Not Validating for Multisig
I'm getting the following error when trying to consume a UTxO sitting in a multisig script address:
[
  {
    "scriptWitnessNotValidating": [
      "74947280b4d63d1051d319d700e21dac50ee858c089378ccc410b568"
    ]
  }
]

This is the script I created for requiring 4 of 6 signatures to consume the UTxO:
const jsonScript = {
    type: 'atLeast',
    require: 4,
    scripts: [
        {
          type: 'sig',
          keyHash: '6bccf3fc71642dbc8f34deb976784ca636665043ef1384b31cab2524'
        },
        {
          type: 'sig',
          keyHash: 'acfdc19b3081ef21301f76eee0e5e35411b9d2c2b5624e580f36bac4'
        },
        {
          type: 'sig',
          keyHash: 'f03009eb94e1d4a208ccc64bde7e91dc3f6a6c1d8660199fc2f120b8'
        },
        {
          type: 'sig',
          keyHash: '3c76bbfc8af2b0862c3aca122a1d5a4493ee8b2aa2cfb7aadcfdcbc5'
        },
        {
          type: 'sig',
          keyHash: '52a09a992dfbe55f9ec80bc73fecf1bf7f42434c73e8bb79067aaf30'
        },
        {
          type: 'sig',
          keyHash: 'dd31fc7bf8d266eb08f840361ff528108d6689eeb3af96cfa77d8547'
        }
    ]
};

I'm using this function to provide each of the signing keys to the transaction I want to execute:
tx.addKeyWitnesses(signingKeys[0]);
tx.addKeyWitnesses(signingKeys[1]);
tx.addKeyWitnesses(signingKeys[2]);
tx.addKeyWitnesses(signingKeys[3]);
tx.addKeyWitnesses(signingKeys[4]);
tx.addKeyWitnesses(signingKeys[5]);

Is there something I'm missing?
Thank you

Are you sure you are trying to consume the right UTxO? Check the index, maybe you are trying to consume the wrong output of that transaction.

I tried all over again and it worked. I'm not sure if it was that or not but at least I have it right now. Thanks for your reply.

Finally I was able to sort this out.
You can use this library to create the multisig: https://github.com/tango-crypto/cardano-wallet-js
The code I ran was the following:
multisig.js
const { WalletServer , Seed } = require('cardano-wallet-js');

const data = {
    "type":  "atLeast", //requires at least 4 keys to sign the tx
    "require": 4,
    "scripts":
    [
        {
            "type": "sig"
        },
        {
            "type": "sig"
        },
        {
            "type": "sig"
        },
        {
            "type": "sig"
        },
        {
            "type": "sig"
        },
        {
            "type": "sig"
        },
    ]
};
// generate the native script
const script = Seed.buildScript(data);

const jsonScript = Seed.scriptToJson(script);

console.log(jsonScript);

// get native script private keys (all them will be needed to sign the final tx)
const keys = Seed.getScriptKeys(script).map(k => k.to_bech32());
console.log("keys:", keys);

//Generate script address
const address = Seed.getScriptAddress(script, 'testnet').to_bech32();
console.log("address:", address);

The code to sign the transaction is this one (you need to replace every 'XXXX' on scriptKeys with your signing keys, and every 'YYYY' on jsonScript.scripts with the key hashes of each signature - all this is output of multisig.js):
tx-sign.js
const { WalletServer , Seed , Config, Bip32PrivateKey } = require('cardano-wallet-js');

const scriptKeys = [
    'XXXX',
    'XXXX',
    'XXXX',
    'XXXX',
    'XXXX',
    'XXXX'
];

const signingKeys = scriptKeys.map(key => Bip32PrivateKey.from_bech32(key).to_raw_key());

// get native script (this is the SAME SCRIPT, we're just "loading" it back)
const jsonScript = {
    type: 'atLeast',
    require: 4,
    scripts: [
      {
        type: 'sig',
        keyHash: 'YYYY'
      },
      {
        type: 'sig',
        keyHash: 'YYYY'
      },
      {
        type: 'sig',
        keyHash: 'YYYY'
      },
      {
        type: 'sig',
        keyHash: 'YYYY'
      },
      {
        type: 'sig',
        keyHash: 'YYYY'
      },
      {
        type: 'sig',
        keyHash: 'YYYY'
      }
    ]
};

// set network configuration
let buildOpts = {
    startSlot: 0,
    config: Config.Testnet,
};

const ttl = 52399446; // slot before the tx should be processed

const CoinSelectionWallet = {
    "withdrawals": [],
    "inputs": [
        {
            "amount": {
                "quantity": 10000000,
                "unit": "lovelace"
            },
            "address": "addr_test1xr20j5t970ssz0323tzqqvp3pp02s96yf64zmzj83kksyvx5l9gktulpqylz4zkyqqcrzzz74qt5gn429k9y0rddqgcq2yupvs", // script address
            "id": "d48f256aea384066756be0c11c6e6b8baef8f7ad25ba92b76d1ae3c294443400",
            "assets": [],
            "index": 0
        },
    ],
    "deposits": [],
    "change": [
        {
            "amount": {
                "quantity": 8800000, // fee of 200000 initially
                "unit": "lovelace"
            },
            "address": "addr_test1xr20j5t970ssz0323tzqqvp3pp02s96yf64zmzj83kksyvx5l9gktulpqylz4zkyqqcrzzz74qt5gn429k9y0rddqgcq2yupvs",
            "assets": []
        }
    ],
    "outputs": [
        {
            "amount": {
                "quantity": 1000000,
                "unit": "lovelace"
            },
            "address": "addr_test1qpypxf9jma2lkmzwn6nhypmynqpmus7x0ekwp2jfdrxqgm8vecdcssszlmywlyn7h0nkqp9jyk8p7dhjecglhu9m75xq4mwl9v",
            "assets": []
        }
    ]
};

const script = Seed.buildScript(jsonScript);
// for the script witnesses we only need to specify the native script root
const scripts = [script.root];

// build the tx (you can include scripts/signingkeys here, eg: let tx = Seed.buildTransactionMultisig(selection, ttl, scripts, null, sigingKeys, buildOpts);)
let tx = Seed.buildTransactionMultisig(CoinSelectionWallet, ttl, [], null, [], buildOpts);
// add script
tx.addScriptWitness(...scripts);
// add witness
tx.addKeyWitnesses(signingKeys[0]);
tx.addKeyWitnesses(signingKeys[1]);
tx.addKeyWitnesses(signingKeys[2]);
tx.addKeyWitnesses(signingKeys[3]);
tx.addKeyWitnesses(signingKeys[4]);
tx.addKeyWitnesses(signingKeys[5]);

const signed = tx.build();
console.log(signed)

When you do :
tx.addKeyWitnesses(signingKeys[0]);
tx.addKeyWitnesses(signingKeys[1]);
tx.addKeyWitnesses(signingKeys[2]);
tx.addKeyWitnesses(signingKeys[3]);
tx.addKeyWitnesses(signingKeys[4]);
tx.addKeyWitnesses(signingKeys[5]);

You are signing with all 6 signatures. You can sign with any 4 you want and the UTxO will be consumed as well. On the contrary, if you provide less than 4 signatures, then the validation will fail.


text:
How to derive non-extended skey from mnemonic phrase?
See title. I've tried using https://github.com/input-output-hk/cardano-addresses to derive the skey, but it only gives an extended version that I'm unable to sign transactions with using the CLI.
Trying to figure out how to get the standard non-extended signing key.

Let's say your extended signing key is named payment.xkey, in the following format:
{
    "type": "PaymentExtendedSigningKeyShelley_ed25519_bip32",
    "description": "",
    "cborHex": "5880687fda2ea05211f09e1544efd4e2da4f5c607dddd06051e6471a754a7efe02411ca42fca7e8e17821485144ba42a12a9814279caf665cb9026faaaf85dffeceb8f206b4eaec7ee07722deab4f17e8705afa7fce7d58b347e1e24ff4f031cdc8ce0c1e06e4934512cc678314402f6c04a7cb999d4efdb324f03a416dfcbda498f"
}

Run the following command:
cat payment.xkey | cardano-address key inspect
It will output a 64 byte chain code, and a 128 byte extended signing key. The first 64 bytes of this extended key is what you are looking for. You can manually create the non-extended signing key by copy-pasting these first 64 bytes (exactly half) of the "extended_key" section into an appropriately formatted normal signing-key file. For example, if I run the above command and I get the following:
{
    "chain_code": "e0c1e06e4934512cc678314402f6c04a7cb999d4efdb324f03a416dfcbda498f",
    "extended_key": "687fda2ea05211f09e1544efd4e2da4f5c607dddd06051e6471a754a7efe02411ca42fca7e8e17821485144ba42a12a9814279caf665cb9026faaaf85dffeceb",
    "key_type": "private"
}

The string you're looking for would be: 687fda2ea05211f09e1544efd4e2da4f5c607dddd06051e6471a754a7efe0241
Now, use cardano-cli to generate a random, normal signing key file:
cardano-cli address key-gen --signing-key-file payment.skey --verification-key-file payment.vkey
Now, discard the vkey (it is irrelevant), open the payment.skey in an editor, and delete everything in the cborHex field following the 5820, replacing it with the first 64 bytes of the xprv above. This is your non-extended signing key. Final result should look like:
{
    "type": "PaymentSigningKeyShelley_ed25519",
    "description": "Payment Signing Key",
    "cborHex": "5820687fda2ea05211f09e1544efd4e2da4f5c607dddd06051e6471a754a7efe0241"
}

Repeat the same process for stake-keys, as well as for any other key indexes that are needed.

Thanks for this. However, what worked for me was to pass my root private key (the value starting with "root_") to cardano-address key inspect and not the extended key file you make reference to in payment.xkey.  In other words:
cat root.prv | cardano-address key inspect. This is the command that gave me the JSON with "chain_code", "extended_key" and "key_type".


text:
How to use Endpoints and Schema
I doing the PPP but Lars does not cover Endpoints or schema declarations in sufficient detail. I imagine that this is a problem that Plutus devs must overcome, but I cannot find suitable documentation on this topic.
Can you please explain how to use Endpoints and Schema in a contract, and possibly provide a few links for further reading.
Thankyou.


text:
How can you use Ledger.Constraints in the Validator?
Hi i have noticed that you can get the unspent UTxOs in an wallet address using the Ledger. Constraints module. I want to know can I use it the same in the mkValidator as in the Endpoints?
The general form of the question is can I query the CLI node inside the validator, and make custom validation logic using the received information?

Okay After some studying and testing on the playground the answer is a yes.
Whilst the Ledger.Constraints can not be taken as an input to the smart contract, it can be called from the validator part of the code, not just the Endpoints.
The exception is that if you have multiple smart contracts in a single Dapp the output of the first could be the input to the second. This would allow you to call Ledger.Constraints from the first contract and have the data readily available in the second.
You can use the Ledger.Contract module to query the chain, but it's limited and unstable. I am currently writing the CIP to fix this, so you may be able to do this easily and efficiently at the time of reading, but not writing.
Below is a link to a conversation with the plutus team on this topic: https://github.com/input-output-hk/plutus-apps/issues/339

In short: no.
Validator has three arguments:

datum, from the utxo considered
redemeer, supplied in the tx
script context, which is a collection of data about the tx.

Nothing else.
Any information the validator needs must be supplied somehow in the arguments.
Some Ledger.Constraints can be used in validator logic.
(Here)
These are used in some of the examples provided. For example
https://github.com/input-output-hk/plutus-apps/blob/13836ecf59649ca522471417b07fb095556eb981/plutus-use-cases/src/Plutus/Contracts/MultiSigStateMachine.hs#L225

Can i call the function to check the UTxOs at the address signing the transaction?

No. Not unless they are used in the Tx.


text:
How can I execute a SundaeSwap transaction from the Cardano-CLI?
Goal
I want to be able to use the cardano-cli to swap some tokens on SundaeSwap.
What I have

Working local cardano-node
cardano-cli

What is missing
If I understood this correctly (please correct me if I'm wrong), I need to get the source code of the SundaeSwap smart contract, compile it somehow and then send a transaction with the correct data (datum) to the contract address. But I'm not sure how to do this and where to find the contract source code. Any help is much appreciated!

The contract code is not open source.

Do I need the source code of the contract to call it from the CLI?

You need the compiled version, but without the source you will not know how to use it, I assume.

All compiled plutus scripts are on-chain, the nodes need something to run the code. You can view the compiled plutus core via almost any blockchain explorer. For example, cardanoscan.io provides this. Given a transaction that uses a smart contract you can view the tab contract (for the plutus core) and the used datum/redeemer. All this data is in CBOR encode to save space onchain. You can decode it via cbor.me. Good luck hacking/reverse engineering a way to post swap request via the client! It is possible :)


text:
Can Queries To the Chain be made From Plutus Smart Contracts?
Considering that Plutus Smart Contracts have two parts (on chain and off chain) is there a way to make Queries to the Cardano Chain in the onchain part of the contract considering that the SC is actually already on the chain?
I want to be able to look up the transaction history of an address and check its balance.
I know I can do this via the Cardano Node, but considering that the contract must run on the node this should be possible how do I do it?

After reaching out to the Plutus-core team I got the answer and paraphrased it here.
They can but the functionality is quite limited right now, as the module is still under development. This means that it is likely unsafe for real applications.
I suggest waiting for the next stable update to plutus.
EDIT:
As per @kindofdev request, the module is the request module. I offered to help the team improve and build it out. Hope they agree. Anyone reading this is advised to urge them to let me build part of it.

Can you please pinpoint the module?

where's the proposal/issue?

The way I understood things from last Q&A session with Lars, no, you can't. You can only see the current transaction, not the history of an address.

This is incorrect the module call exist. See nest post, but its all in monads.


text:
Cardano DB Sync as Service (running on background) on Ubuntu
Linux/Ubuntu - Cardano newbie, want to ask things around! :)
At the moment, I'm successfully installed cardano-node and can make it run as a service (pulling data automatically on the background), by following some of these instruction. I only follow some / few steps.
I tried to replicate it into cardano-db-sync version, so I can do cardano-db-sync automatically on the background. But, it gives some error / issue.
I already make, .sh and .service file.
Below is the code for, .sh file
#!/bin/bash
PGPASSFILE=/cardano/cardano-db-sync/config/pgpass-mainnet
CONFIG=/cardano/cardano-db-sync/config/mainnet-config.yaml
SOCKET_PATH=/cardano/db/node.socket
STATE_DIR=/cardano/cardano-db-sync/ledger-state/mainnet
SCHEMA_DIR=/cardano/cardano-db-sync/schema/
PGPASSFILE=${PGPASSFILE} cabal run cardano-db-sync -- --config ${CONFIG} --socket-path ${CARDANO_NODE_SOCKET_PATH} --state-dir ${STATE_DIR} --schema-dir ${SCHEMA_DIR}

And for .service file
# The Cardano DB Sync service (part of systemd)
# file: /etc/systemd/system/cardano-db-sync-run.service

[Unit]
Description     = Cardano DB Sync service
Wants           = network-online.target
After           = network-online.target

[Service]
User            = root
Type            = simple
WorkingDirectory= /cardano/cardano-db-sync
ExecStart       = /bin/bash -c '/cardano/cardano-db-sync-run.sh'
KillSignal=SIGINT
TimeoutStopSec=300
LimitNOFILE=32768
Restart=always
RestartSec=5
SyslogIdentifier=cardano-db-sync

[Install]
WantedBy        = multi-user.target

When I test to manually run /bin/bash -c '/cardano/cardano-db-sync-run.sh' it's working well and I can see some data get into database.
BUT, when I tried to run it as a service, it gives and error.
Here's what I did to make it run as a service
> sudo systemctl enable cardano-db-sync-run
> sudo systemctl start cardano-db-sync-run

And then, checking its log by
> journalctl --unit=cardano-db-sync-run --follow

And it shows an error - line 7: cabal: command not found.
I tried to see and one of my colleague advise me, to use full path of "cabal", since it isn't on /bin, so I change a bit .sh file to be
...
...

PGPASSFILE=${PGPASSFILE} /root/.ghcup/bin/cabal run cardano-db-sync -- --config ${CONFIG} --socket-path ${CARDANO_NODE_SOCKET_PATH} --state-dir ${STATE_DIR} --schema-dir ${SCHEMA_DIR}

Notice, that I change cabal into /root/.ghcup/bin/cabal. But, by doing so, it also gives an error message, as shown below
Feb 28 06:40:44 systemd[1]: Started Cardano DB Sync service.
Feb 28 06:40:44 cardano-db-sync[20548]: /cardano/cardano-db-sync
Feb 28 06:40:45 cardano-db-sync[20548]: Warning: Requested index-state 2021-07-02T00:00:00Z is newer than
Feb 28 06:40:45 cardano-db-sync[20548]: 'hackage.haskell.org'! Falling back to older state (2021-07-01T22:06:28Z).
Feb 28 06:40:45 cardano-db-sync[20548]: Resolving dependencies...
Feb 28 06:40:45 cardano-db-sync[20548]: cabal: Could not resolve dependencies:
Feb 28 06:40:45 cardano-db-sync[20548]: [__0] trying: Win32-network-0.1.0.0 (user goal)
Feb 28 06:40:45 cardano-db-sync[20548]: [__1] trying: base-4.9.1.0/installed-4.9.1.0 (dependency of Win32-network)
Feb 28 06:40:45 cardano-db-sync[20548]: [__2] next goal: base-deriving-via (user goal)
Feb 28 06:40:45 cardano-db-sync[20548]: [__2] rejecting: base-deriving-via-0.1.0.0 (conflict:
Feb 28 06:40:45 cardano-db-sync[20548]: base==4.9.1.0/installed-4.9.1.0, base-deriving-via => base>=4.14)
Feb 28 06:40:45 cardano-db-sync[20548]: [__2] fail (backjumping, conflict set: base, base-deriving-via)
Feb 28 06:40:45 cardano-db-sync[20548]: After searching the rest of the dependency tree exhaustively, these were the
Feb 28 06:40:45 cardano-db-sync[20548]: goals I've had most trouble fulfilling: base, Win32-network, base-deriving-via
Feb 28 06:40:45 systemd[1]: cardano-db-sync-run.service: Main process exited, code=exited, status=1/FAILURE
Feb 28 06:40:45 systemd[1]: cardano-db-sync-run.service: Failed with result 'exit-code'.

Again, I already try to run it manually, using /bin/bash -c '/cardano/cardano-db-sync-run.sh' and it works well, BUT, only when I make it run as a service, it shows that error.
My guess is that "cabal" isn't really recognized.
Any suggestion on why it failed?

PS --

I built cardano-node by follow this docs precisely. So, even the ghc --version and/or cabal --version is same
cardano-db-sync that I built is using Cabal (ghc stuffs), not using Nix / docker.

Thanks in advance!

*Edit #1 - after read the comments and replies from Eric de Castro Lopo and George - APEX Stake Pool, I got question
Do I need to wait this part to be done? So, I can make cardano-db-sync as a service?

PGPASSFILE=config/pgpass-mainnet cabal run cardano-db-sync --
--config config/mainnet-config.yaml
--socket-path ../cardano-node/state-node-mainnet/node.socket
--state-dir ledger-state/mainnet
--schema-dir schema/

*It's written on the docs

*Edit #2 - after checking more
Question from *Edit #1 - can be ignored, but for someone who looking for the answer, the answer is didn't need to. Detail can be seen on comment / replies by others.
Anyway, finally I can make it work as service. And as per guidance from Eric de Castro Lopo and George - APEX Stake Pool, seems I mistakenly put the syntax/command on .sh file as mentioned. Thanks!
In-case someone need, the workaround I did is to make a symlink of the executable file of cardano-db-sync

Do find . -name cardano-db-sync -executable -type f to find its location
Then, I did symlink (register cardano-db-sync) into /usr/local/bin (or wherever suitable for you), using sudo ln -s  ... (or other similar syntax / command).
And finally, on .sh file, I change this part ... cabal run cardano-db-sync -- ... into ... cardano-db-sync -- ...

Anyway, I will mark George - APEX Stake Pool's answer as it's the closest hint for me.
And, sorry Eric de Castro Lopo that I couldn't upvote your comment, as it's helpful too for me! Need +15 rep to upvote your comment :(
Thanks for your time! :)

As the main dev on cardano-db-sync I would recommend that you avoid building it every time you run it.
Build it once and then install it (will probably need to be manually, as root) and then it should all work (the reason it does currently work is that the service is running as root, and root does not have access to the cabal executable).

Hi @ErikdeCastroLopo - thanks for your explanation! Do you mind to explain a bit more about this sentences of yours "I would recommend that you avoid building it every time you run it" - I still not really understand, which part that "build" every time I run which? *sorry, I kinda lost on that part.

cabal build ... builds the executable. Every time you run that command the executable gets build.

Gotcha! Thanks for your kind explanation! :)

Why are you running cardano-db-sync with cabal? You should just run cardano-db-sync or cardano-db-sync-extended.
And another question, more important: why are you running the service as root? This is always a security issue. You should never run a service as root (unless really needed, which is not the case here) or as an user with sudo rights. And cardano-db-sync should be in /usr/local/bin, for example.
I'm posting here my service file and my shell script executed by the service:
# cat /etc/systemd/system/cardano-db-sync.service
# The Cardano db-sync service (part of systemd)
# file: /etc/systemd/system/cardano-db-sync.service

[Unit]
Description      = Cardano db-sync service
Wants            = network-online.target
After            = network-online.target

[Service]
User             = cardano
Type             = simple
WorkingDirectory = /home/cardano/cardano-node
ExecStart        = /bin/bash -c '/home/cardano/cardano-node/bin/db-sync.sh'
KillSignal       = SIGINT
TimeoutStopSec   = 120
LimitNOFILE      = 32768
Restart          = always
RestartSec       = 5

[Install]
WantedBy         = multi-user.target

# cat /home/cardano/cardano-node/bin/db-sync.sh
PGPASSFILE=/home/cardano/cardano-node/config/pgpass-mainnet cardano-db-sync-extended \
    +RTS -N -RTS \
    --config /home/cardano/cardano-node/config/mainnet-db-sync-config.json \
    --socket-path /home/cardano/cardano-node/db/node.socket \
    --state-dir /home/cardano/cardano-node/ledger-state/mainnet \
    --schema-dir /home/cardano/cardano-node/schema/

Hi! Thanks for your explanation and sample codes. It kinda gives me more explanation. About your question "Why are you running cardano-db-sync with cabal? You should just run cardano-db-sync or cardano-db-sync-extended - it seems I kinda misunderstood the documentation. And, because its last step, I kinda confuse on where can I found the "cardano-db-sync-exe", so, I follow the previous step where it says "... cabal run cardano-db-sync .... "

--continue-- About your concern, why I run it as root, it's because the server is a test server, and I still learn things around since I super newbie! Anyway, thanks a lot for that! really means a lot for me to learn! || And "And cardano-db-sync should be in /usr/local/bin" - I don't see that on that folder. I just follow their docs.

You are welcome. I am keeping all cardano-related binaries in /usr/local/bin, it's probably the best location for them.

ohh! I see! I thought it supposed to be there after installation. Thanks for your tips!


text:
How to get a base 16 hex BuiltinString from getTxId
I am trying to find a way to inspect the base16 hash from a Tx on-chain using plutus.
I get a BuiltinByteString from the txInputs here:
getTxIdBBS :: TxInInfo -> BuiltinByteString
getTxIdBBS txInfo' = getTxId(txOutRefId (txInInfoOutRef txInfo'))

but then I need to get the base16 representation so I can compare and inspect the hex digits.

Ideally, I would like to use a function similar to below, but this only works off-chain (due to conversion to non-builtin).
import qualified Data.ByteString.Base16 as B16 (encode)

txId    = getTxIdBBS (txInfo)
txId'   = fromBuiltin(txId)
txIdHex = toBuiltin(B16.encode txId')

I've also tried the following, but this does not work either.
import Data.Text.Encoding qualified as E
import PlutusTx.Builtins.Internal qualified as BI

{-# INLINABLE txEncodeUtf16 #-}
txEncodeUtf16 :: BI.BuiltinString -> BI.BuiltinByteString
txEncodeUtf16 (BI.BuiltinString s) = BI.BuiltinByteString $ E.encodeUtf16BE s

txHash = txEncodeUtf16(decodeUtf8(txId))

I am not able to use decodeUtf8 on a BuiltinByteString generated by sha2_256 and get the following error:
decodeUtf8*** Exception: Cannot decode byte '\xc6': Data.Text.Internal.Encoding.decodeUtf8: Invalid UTF-8 stream

I also can’t use encodeUtf16BE due to the following compiler error:
GHC Core to PLC plugin: E042:Error: Unsupported feature: Type constructor: GHC.Prim.ByteArray#

Any help or suggestions on how to convert the BuiltinByteString from getTxId into a BuiltinString  "on-chain" where I can inspect the hex digits would be awesome.
Thanks,
Lawrence

What is BuiltinByteString ?

I was able to resolve this issue by converting (encoding) the BuiltinByteString from getTxId into a hex format.   From there I was able to inpsect the hex digits.   Below is an onchain encodeHex function that I used (thanks Minswap!).
-- Convert from a byte string to its hex (base16) representation. Example: [2, 14, 255] => "020eff"
{-# INLINEABLE encodeHex #-}
encodeHex :: BuiltinByteString -> BuiltinByteString
encodeHex input = go 0
  where
    len = lengthOfByteString input
    go :: Integer -> BuiltinByteString
    go i
      | i == len = emptyByteString
      | otherwise =
        consByteString (toChar $ byte `quotient` 16) $
          consByteString (toChar $ byte `remainder` 16) (go $ i + 1)
      where
        byte = indexByteString input i

        toChar :: Integer -> Integer
        toChar x
          -- 48 is ASCII code for '0'
          | x < 10 = x + 48
          -- 97 is ASCII code for 'a'
          -- x - 10 + 97 = x + 87
          | otherwise = x + 87

You might just need to use the fromBuiltin fn to get a ByteString:
...
import Data.ByteString.Char8 as C
import Prelude as Haskell
...

converted :: BuiltinByteString -> BuiltinString
converted bbs' = let b = C.unpack( fromBuiltin bbs' ) :: Haskell.String
                              -- in toBuiltin b
                              in stringToBuiltinString b

Update: I'm not sure I've figured out how to set up the toBuiltin fn. It's not compiling in my test project.
Update: the actual fn is stringToBuiltinString

This does not work on-chain

@Mateus  is correct, this doesn't work onchain. I'll add another answer with what I've found.

but then I need to get the base16 representation so I can compare and
inspect the hex digits.

Not sure this is correct, I was able to inspect the txId directly with getTxId, take a look at the following code
import           Data.Aeson           hiding (Value)
import           GHC.Generics
import           Ledger               hiding (singleton)
import           Ledger.Scripts
import           Ledger.Typed.Scripts as Scripts
import           Ledger.Value
import           Plutus.ChainIndex
import qualified PlutusTx
import PlutusTx.Builtins
import qualified PlutusTx.AssocMap    as PlutusMap
import           PlutusTx.Prelude
import qualified PlutusTx.Ratio       as R
import qualified Prelude

...

{-# INLINEABLE mkNFTPolicy #-}
mkNFTPolicy :: Integer -> TxOutRef -> ScriptContext -> Bool
mkNFTPolicy size oref ctx =
    nftPolicyTraceIfFalse "UTxO not consumed" hasUTxO &&
    nftPolicyTraceIfFalse "Invalid token name or amount" validMinting
  where
    refId :: BuiltinByteString
    refId = case intToBuiltinByteString $ txOutRefIdx oref of
        bbs | lengthOfByteString bbs == 1 -> "0" `appendByteString` bbs
            | lengthOfByteString bbs == 2 -> bbs
        _ -> nftPolicyTraceError "Invalid ref id"

    ...

    validTokenName :: TokenName -> Bool
    validTokenName (TokenName bs) = sliceByteString 0 (size + 2) bs == expected
      where
        expected :: BuiltinByteString
        expected = sliceByteString 0 size (getTxId $ txOutRefId oref) `appendByteString` refId
    ...

Thanks Mateus.  I was able to resolve the issue, I needed to convert (encode) the onchain reprentation proivded by getTxId into a hex format.   From there I was able to look at each of the hex digits.   I'll post the encodeHex function on the main thread.


text:
funding a wallet
I've created a wallet with create-wallet.sh and loaded it with load-wallet.sh, and its balance is 0:
"balance":{"total":{"quantity":0,"unit":"lovelace"},"available":{"quantity":0,"unit":"lovelace"},"reward":{"quantity":0,"unit":"lovelace"}}

Lars says in the video that we can connect this wallet to Daedalus or Yoroi and then use the Faucet to fund the wallet. Is there a way to fund the wallet directly, without Daedalus or Yoroi? I have already used Faucet at a previous step, the balance of the address I have used is 999.656267 ADA and I should be able to connect the wallet to these funds.

You might do as follows:

create-wallet.sh (create a new wallet)

load-wallet.sh (load new wallet into wallet-backend)

Take id value from load-wallet.sh result.

Set WALLETID=id in your env.sh

. env.sh (source env.sh)

get_address.sh  (get the address of the new wallet)

Use send.sh (week03) in order to transfer funds from your funded address to your new address.

cardano-cli transaction build \
    --alonzo-era \
    --testnet-magic 1097911063 \
    --change-address <address_with_funds> \
    --tx-in <an_utxo_id_with_funds> \
    --tx-out "<your_new_address> <ada_to_tranfer> lovelace" \
    --out-file tx.body

cardano-cli transaction sign \
    --tx-body-file tx.body \
    --signing-key-file <skey_of_address_with_funds> \
    --testnet-magic 1097911063 \
    --out-file tx.signed

cardano-cli transaction submit \
    --testnet-magic 1097911063 \
    --tx-file tx.signed

Hope this will be useful.

$ ./sendWallet.sh
Estimated transaction fee: Lovelace 166953
Transaction successfully submitted.
That's great, it worked, balance is also updated.


text:
Verifying policy id from pub key
Is there any way to verify a policy against a policy.vkey (or even policy.skey in my case).
Thing is we would prefer to not store on external backend all of our NFT policies.
Use case to fill would be: "I receive an NFT (a long time after his mint) and I really want to verify that I am the issuer".
Thanks!

Use case to fill would be: "I receive an NFT (a long time after his mint) and I really want to verify that I am the issuer".

This is not a realistic use case. If the policy ID listed when you query a Cardano wallet matches the string of a policy ID that you minted in the past, then it is verified. There's no way to send someone a token that has a policy ID without being signed by your skey, so there would be no possible way to spoof it, and therefore no need to 'verify' it using a key in the future.
EDIT: In re-reading your post, maybe I am misunderstanding.. Are you saying you'd prefer to not keep a record of the policy ID strings you've minted in the past? It seems like just creating a text file that stores all of your policy IDs would be the same effort as keeping the .vkey or .skey's from past policies..

Yes, your Edit is correct. we do not want to keep track of any policy ID we generated. In our mind, if our pub key was public anyone could verify the policy on their own without us involved. It is more for others than us. You know we had in mind the very similar way people are verifying today jwt with jwks/well-known open to anyone (oauth2). Anyway you seem to confirm that there is no way unfortunately to avoid storing them which is a bit sad. Thanks.


text:
Submitting a transaction from cardano-cli with Nami Wallet
I am aware that there is an issue regarding the fact that serialization-lib and cardano-cli are not compatible
Converting the array into a Map is not the solution because in my case I also have the datum (I am interacting with a smart contract)
How should I convert the cbor transaction
"86a60081825820007979b87e21ea3a346a25b73931ee718a78ee88ca4f43bf539fca9b939f7893000d800182825839011c471b31ea0b04c652bd8f76b239aea5f57139bdc5a2b28ab1e69175fd3a6bfce30d7744ac55e9cf9146d8a2a04ec7fb2ce2ee69862606531a001bc67f83581d71139f42bffba8ce2703dbaef06ce84d9817a7fd229c24aa0698c0dfb0821a001e8480a1581ccdf4f1a7ddaaaaaba5758cb192d17c9d93fc090e06be1861cdac5c55a15043727970746f447261676f6e3331313201582004e0be90602a4490137de24e0619a8d13e8800b84caeb99b0f6b413c0f804ebd021a0002be010e800b58207c34f5ad4773a076f154315cd9a6db89d1f1cfbc1e2bf2fd9f524a76b86d592c9fff81d8799f5839011c471b31ea0b04c652bd8f76b239aea5f57139bdc5a2b28ab1e69175fd3a6bfce30d7744ac55e9cf9146d8a2a04ec7fb2ce2ee69862606531a001e84800a025838636466346631613764646161616161626135373538636231393264313763396439336663303930653036626531383631636461633563353558203433373237393730373436663434373236313637366636653333333133313332d87a80d87a80ff80f5f6"
to be Nami compatible?
Thanks in advance

The solution remains the same. You must convert the array into the map, commonly done by signing it with throw away keys. Then you get the transaction with the serialization library, free the witness set then create and set new required signers and then reassemble the transaction while making sure to include the datum and redeemer (which can also be found in the map). Alternatively, you can use the --cddl-format in cardano-cli to yield the cbor encoding that is compatible with cardano-ledger (and thus nami).

"reassemble the transaction while making sure to include the datum and redeemer", can you expand on that? Do I need to send the tx back to the back-end after signing it with Nami?

--cddl-format worked almost fine but when I tried to submit adding the signature it fails :/


text:
How to recover a wallet in cardano-cli from a 24-word mnemonic
I have a wallet created with Daedalus and have the 24-word mnemonic available. I would like to use the same wallet with cardano-cli in order to build and submit more complicated transactions directly through the cardano-node. I need to get my hands on the signing (private) key and verification (public) key.
I found the old, now archived cardano-cli repo which actually describes the procedure. However, the wallet subcommand is no longer available in the latest cardano-cli.
https://github.com/input-output-hk/cardano-cli/blob/master/USAGE.md#recovering-a-wallet

cardano-cli does not support mnemonic derivation natively, so you'd have to use cardano-wallet software:

Install cardnao-wallet or cardano-addresses and put the executables in your $PATH. I will be using cardano-wallet for this demo, but cardano-address would work exactly the same.
Run the following:
<YOUR_24_WORD_MNEMONMIC> | cardano-wallet key from-recovery-phrase Shelley > root.xprv
This will create an extended root private key from the mnemonic under the name root.xprv
Run the following:
cat root.xprv | cardano-wallet key child 1852H/1815H/0H \
| tee acct.xprv | cardano-wallet key public --with-chain-code > acct.xpub
This will create two files: acct.xprv (your extended account private key - will be used to further derive your payment/staking private/public keys) and acct.xpub (your extended account public key - use this to verify that it is the same as the "wallet public key" in Daedalus in the next step)
Fire up Daedalus and go to More > Settings > Wallet Public Key. View your public key and ensure that it is the same as the acct.xpub you derived in the previous step:

If the keys match, you may now use the acct.xprv to further derive the address-specific payment/stake keypairs.
Run the following:
cat acct.xprv | cardano-wallet key child <DERIVATION_PATH>, where the DERIVATION_PATH is the following:

0/n for payment keypairs
1/n for change-address payment keypairs
2/0 for the account-level staking keypair

Running the above command will output the extended signing key for each address index (n). To convert these keys into cardano-cli compatible non-extended signing keys, refer to this Q/A. You can also use cardano-cli to derive non-extended verification keys from each non-extended signing key.
Note: If you've used this wallet on Daedalus frequently, you likely have UTXOs in a few payment and change addresses, so you would have to derive key-pairs for all addresses that UTXOs reside in. Alternatively, you can create a new wallet (new mnemonic) on Deadalus, transfer all the funds there, and then you'll have them all sitting at a single address, likely either at 0/0 or 0/1.
Comment if you have any questions or if you need any further clarification. Hope this helps!

If you're using CNtools, you can recover a deadalus wallet using your mnemonic seed phrase.
From the CNtools menu, you would select Wallet > Import > Mnemonic
then enter your seed phrase.  Your wallet will be restored and you can access your private keys in $CNODE_HOME/priv/wallet/[WALLET_NAME]


text:
Automatically "taxing" native token transactions
To fund the "commons" for some community with some token T, it might make sense to "tax" transactions within this community, similarly to how a gas fee funds the operations of the underlying blockchain, or how a town raises money for the fire department through a sales tax on retail transactions.
The idea is that if A sends 100 T tokens to B, say 1 of those gets sent to C (the commons) and only 99 arrive with B. I would want this to be automated, so that within that community, nobody can cheat.
Can I do this with a native token? If so, how?

I know that royalties can be set for NFT projects. I haven't yet seen royalties set for fungible tokens, but I don't see why it wouldn't be possible. What you're proposing sounds like a 1% royalty.  You may find some good information here: https://github.com/cardano-foundation/CIPs/pull/116/files

Ah, excellent, the ground work seems to come into existence then.


text:
How to combine or spend the rest of utxos
I have several utxos in my cardano wallet address created via the cardano-cli that have 1-4 ADA each. Some utxos have an NFT associated with them. Is there a way to spend the rest of several utxos in one transaction? Is there a way to combine several utxos?
I created the wallet using the cli using the following commands:
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

In your build command specify multiple txins and one txout with the sum of all the Ada and tokens from spent utxos.

I wanted to elaborate on Samuel's answer to be more details. Let's say you are building a transaction that looks like the following:
cardano-cli transaction build-raw \
--tx-in <TxHash>#<TxIx> \
--tx-out <payment.addr>+<change> \
--tx-out <destinationAddress>+0 \
--invalid-hereafter $(( ${currentSlot} + 10000)) \
--fee 0 \
--out-file tx.tmp

All you have to do is create more --tx-in options. Make sure you calculate the total ada in all --tx-in options to correctly calculate the change output for the single tx-out. Something of the pattern below would work using 3 --tx-in arguments.
cardano-cli transaction build-raw \
--tx-in <TxHash>#<TxIx> \
--tx-in <TxHash>#<TxIx> \
--tx-in <TxHash>#<TxIx> \
--tx-out <payment.addr>+<totalchange> \
--tx-out <destinationAddress>+0 \
--invalid-hereafter $(( ${currentSlot} + 10000)) \
--fee 0 \
--out-file tx.tmp

Lastly, remember that the utxo must balance out to zero so
all the utxos with ada your are using must equal the fee plus how much ada you are sending plus how much change you have in your one combined utxo left over


text:
What am i doing wrong while creating this staking transaction?
i am trying to create a staking transaction using cardano serialisation library and then use blockfrost/infinito to send the transaction.
I am using @emurgo/cardano-serialization-lib-nodejs: ^9.1.4,
Here's my code :
    createStakeTx(inputs, ttl, poolID, isFirstStake) {
        try {
            // let rootKey = Cardano.Bip32PrivateKey.from_bytes(Buffer.from(this.masterKey, 'hex'));
            console.log(
                'inside create stake tx ::::::::::::::'
            )
            console.log('inputs :', inputs);
            console.log('ttl :', ttl);
            console.log('poolId :', poolID);
            console.log('isFirstStake :', isFirstStake);

            // this.masterKey = Cardano.Bip32PrivateKey.from_bip39_entropy(Buffer.from(entropy, 'hex'), Buffer.from(''))
            let rootKey = this.masterKey
            let spend = rootKey
                .derive(harden(1852))
                .derive(harden(1815))
                .derive(harden(0))
                .derive(this.accountKey) // 1
                .derive(this.addressKey); // 34
            let spendPubKey = spend.to_public();

            let stake = rootKey
                .derive(harden(1852))
                .derive(harden(1815))
                .derive(harden(0))
                .derive(2)
                .derive(0);
            let stakePubkey = stake.to_public();
            let ed = stake.to_public().to_raw_key().hash();
            // console.log('ed :', ed);
            let spendCred = Cardano.StakeCredential.from_keyhash(spend.to_public().to_raw_key().hash());
            let stakeCred = Cardano.StakeCredential.from_keyhash(stake.to_public().to_raw_key().hash());

            // testnet: 0, mainnet: 1
            let address = Cardano.BaseAddress.new(1, spendCred, stakeCred).to_address().to_bech32();

            let linearFee = Cardano.LinearFee.new(
                Cardano.BigNum.from_str('44'),
                Cardano.BigNum.from_str('155381')
            );
            let txBuilder = Cardano.TransactionBuilder.new(
                linearFee,
                Cardano.BigNum.from_str('1000000'),
                Cardano.BigNum.from_str('500000000'),
                Cardano.BigNum.from_str('2000000'),
                16384,
                5000,
            );

            let sumInputs = bigNumber(0);
            inputs.forEach(element => {
                txBuilder.add_key_input(
                    spendPubKey.to_raw_key().hash(),
                    Cardano.TransactionInput.new(
                        Cardano.TransactionHash.from_bytes(Buffer.from(element.tx_id, 'hex')),
                        element.vout
                    ),
                    Cardano.Value.new(Cardano.BigNum.from_str(element.amount))
                );
                sumInputs = sumInputs.plus(element.amount);
            });

            txBuilder.set_ttl(ttl + 2000);

            let poolKeyHash = Cardano.Ed25519KeyHash.from_bytes(Buffer.from(poolID, 'hex'));
            let certs = Cardano.Certificates.new();

            if (isFirstStake == true) {
                certs.add(
                    Cardano.Certificate.new_stake_registration(
                        Cardano.StakeRegistration.new(
                            stakeCred
                        )
                    )
                );
            }

            certs.add(
                Cardano.Certificate.new_stake_delegation(
                    Cardano.StakeDelegation.new(
                        stakeCred,
                        poolKeyHash
                    )
                )
            );

            txBuilder.set_certs(certs);

            let estimate = this.estimateStakeTxFee(inputs, poolID, isFirstStake);
            txBuilder.set_fee(Cardano.BigNum.from_str(bigNumber(estimate.fee).toFixed()));

            let changeAmount = bigNumber(0);
            console.log('sumInputs :', sumInputs)
            if (isFirstStake == true) {
                changeAmount = sumInputs.minus(KEY_DEPOSIT).minus(estimate.fee);
            } else {
                changeAmount = sumInputs.minus(estimate.fee);
            }

            console.log('changeAmount :', changeAmount)
            txBuilder.add_output(
                Cardano.TransactionOutput.new(
                    Cardano.Address.from_bech32(address),
                    Cardano.Value.new(Cardano.BigNum.from_str(changeAmount.toFixed()))
                )
            );

            let txBody = txBuilder.build();

            const txHash = Cardano.hash_transaction(txBody);

            let witnesses = Cardano.TransactionWitnessSet.new();
            let vkeyWitnesses = Cardano.Vkeywitnesses.new();
            vkeyWitnesses.add(Cardano.make_vkey_witness(
                txHash,
                spend.to_raw_key(),
            ));

            vkeyWitnesses.add(Cardano.make_vkey_witness(
                 txHash,
                 stake.to_raw_key(),
            ));

            witnesses.set_vkeys(vkeyWitnesses);

            let tx = Cardano.Transaction.new(
                txBody,
                witnesses,
            );
            console.log('rawtx ::', Buffer.from(tx.to_bytes()).toString('hex'))
            const res = await client.txSubmit(Buffer.from(tx.to_bytes()).toString('hex'));
            return res;
        } catch (err) {
            console.log('err: ', err);
            return null;
        }
    }

// Error when i use blockfrost :
transaction submit error ShelleyTxValidationError ShelleyBasedEraAlonzo (ApplyTxError [UtxowFailure (WrappedShelleyEraFailure (MissingVKeyWitnessesUTXOW (WitHashes (fromList [KeyHash "some hash"])))),DelegsFailure (DelplFailure (DelegFailure (StakeDelegationImpossibleDELEG (KeyHashObj (KeyHash "somehash")))))])
//Error when i use infinito :
{"type":"jsonwsp/fault","version":"1.0","servicename":"ogmios","fault":{"code":"client","string":"Invalid request: DeserialiseFailure 539 "Size mismatch when decoding \nRecord RecD.\nExpected 4, but found 3."."},"reflection":{"requestId":"XEpib"}} is an unknown result
Maybe i am just creating the transaction in a wrong way or my keys might be messed up.
Open to any help and suggestions
Thanks

The error message "MissingVKeyWitnessesUTXOW" means you need to sign with the right key.
For delegation transaction, you need to sign with both your stake.skey and payment.skey.

It might be helpful to future readers if I clarify that contracts have types. You must specify that its a staking one or it will default to something else.

Hi @kawan,
I am a little new to this isn't this exactly what i am doing here :
let spendCred = Cardano.StakeCredential.from_keyhash(spend.to_public().to_raw_key().hash());

let stakeCred = Cardano.StakeCredential.from_keyhash(stake.to_public().to_raw_key().hash());

 vkeyWitnesses.add(Cardano.make_vkey_witness(
                txHash,
                spend.to_raw_key(),
            ));

            vkeyWitnesses.add(Cardano.make_vkey_witness(
                 txHash,
                 stake.to_raw_key(),
            ));

This is the code I use to submit a staking transaction:
export const createDelegationCertificate = (
  mnemonic
) => {

  const entropy = mnemonicToEntropy(mnemonic);

  const rootKey = CardanoWasm.Bip32PrivateKey.from_bip39_entropy(
    Buffer.from(entropy, 'hex'),
    Buffer.from(''),
  );

  const accountKey = rootKey
    .derive(harden(1852)) // purpose
    .derive(harden(1815)) // coin type
    .derive(harden(0)); // account #0

  const utxoPubKey = accountKey
    .derive(0) // external
    .derive(0)
    .to_public();

  const stakeKey = accountKey
    .derive(2) // chimeric
    .derive(0)
    .to_public();

  const operatorKeyHash = utxoPubKey.to_raw_key().hash().to_bech32('ed25519_pk');
  const poolKeyHash = CardanoWasm.Ed25519KeyHash.from_bech32(operatorKeyHash);

  const stakeCredential = CardanoWasm.StakeCredential.from_keyhash(stakeKey.to_raw_key().hash());

  const stakeDelegation = CardanoWasm.StakeDelegation.new(stakeCredential, poolKeyHash);

  // Generate Stake Certificate
  const delegationCertificate = CardanoWasm.Certificate.new_stake_delegation(stakeDelegation)

  return delegationCertificate;

}

After that, create the transaction using the delegation certificate from the previous step:
export const submitDelegationTransaction = async (
  mnemonic,
  delegationCertificate
) => {

  const entropy = mnemonicToEntropy(mnemonic);

  const rootKey = CardanoWasm.Bip32PrivateKey.from_bip39_entropy(
    Buffer.from(entropy, 'hex'),
    Buffer.from(''),
  );

  const accountKey = rootKey
    .derive(harden(1852)) // purpose
    .derive(harden(1815)) // coin type
    .derive(harden(0)); // account #0

  const utxoPubKey = accountKey
    .derive(0) // external
    .derive(0)
    .to_public();

  const stakeKey = accountKey
    .derive(2) // chimeric
    .derive(0)
    .to_public();

  const baseAddr = CardanoWasm.BaseAddress.new(
    CardanoWasm.NetworkInfo.testnet().network_id(),
    CardanoWasm.StakeCredential.from_keyhash(utxoPubKey.to_raw_key().hash()),
    CardanoWasm.StakeCredential.from_keyhash(stakeKey.to_raw_key().hash()),
  );

  const privateKey = deriveSpendPrivateKey(accountKey, 0).to_raw_key();
  const stakingPrivateKey = deriveStakePrivateKey(accountKey, 0).to_raw_key();
  const fromAddress = baseAddr.to_address().to_bech32("addr_test");

  const params = await getParameters();

  const linearFee = CardanoWasm.LinearFee.new(
    CardanoWasm.BigNum.from_str(params.data.genesis.shelley.protocolParams.minFeeA.toString()),
    CardanoWasm.BigNum.from_str(params.data.genesis.shelley.protocolParams.minFeeB.toString())
  );

  const txBuilderConfig = CardanoWasm.TransactionBuilderConfigBuilder.new()
    .fee_algo(linearFee)
    .pool_deposit(CardanoWasm.BigNum.from_str(params.data.genesis.shelley.protocolParams.poolDeposit.toString()))
    .key_deposit(CardanoWasm.BigNum.from_str(params.data.genesis.shelley.protocolParams.keyDeposit.toString()))
    .max_value_size(params.data.genesis.alonzo.maxValueSize)
    .max_tx_size(params.data.genesis.shelley.protocolParams.maxTxSize)
    .coins_per_utxo_word(CardanoWasm.BigNum.from_str(params.data.genesis.alonzo.lovelacePerUTxOWord.toString()))
    .build();

  // instantiate the tx builder with the Cardano protocol parameters - these may change later on
  const txBuilder = CardanoWasm.TransactionBuilder.new(txBuilderConfig);

  const unspentOutputs = await getTxUnspentOutputs(fromAddress);

  // pointer address
  const shelleyChangeAddress = CardanoWasm.Address.from_bech32(fromAddress);

  // set the time to live - the absolute slot value before the tx becomes invalid
  const slot = await getSlotNo();
  txBuilder.set_ttl(slot.data.cardano.tip.slotNo + 10000);

  const certificates = CardanoWasm.Certificates.new();
  certificates.add(delegationCertificate);
  txBuilder.set_certs(certificates);

  // add a keyhash input - for ADA held in a Shelley-era normal address (Base, Enterprise, Pointer)
  txBuilder.add_inputs_from(unspentOutputs, 2); // LargestFirstMultiAsset

  // calculate the min fee required and send any change to an address
  txBuilder.add_change_if_needed(shelleyChangeAddress)

  // once the transaction is ready, we build it to get the tx body without witnesses
  const txBody = txBuilder.build()
  const txHash = CardanoWasm.hash_transaction(txBody);
  const witnesses = CardanoWasm.TransactionWitnessSet.new();
  const vkeyWitnesses = CardanoWasm.Vkeywitnesses.new();
  const vkeyWitness1 = CardanoWasm.make_vkey_witness(txHash, privateKey);
  const vkeyWitness2 = CardanoWasm.make_vkey_witness(txHash, stakingPrivateKey);

  vkeyWitnesses.add(vkeyWitness1);
  vkeyWitnesses.add(vkeyWitness2);

  witnesses.set_vkeys(vkeyWitnesses);
  witnesses.set_native_scripts(CardanoWasm.NativeScripts.new());

  // create the finalized transaction with witnesses
  const transaction = CardanoWasm.Transaction.new(
    txBody,
    witnesses,
    undefined, // transaction metadata
  );

  return toHexString(transaction.to_bytes());

}


text:
How to know which module to import?
Let's say my smartcontract needs BuiltinData.
Quicksearch in documentation reveals that BuiltinData is in:

Plutus.V1.Ledger.Api
Plutus.V2.Ledger.Api
PlutusTx.Builtins.Internal
PlutusTx
PlutusTx.Builtins
PlutusTx.Prelude
...

How to know which include I should add? Which ones are preferred and why?

Some of these are reexported versions of others. This means some of them are not necessary. Also PlutusTx.Prelude should be included in all projects as it maps types into PlutusTx which complies with the bytecode that runs on the chain.
This means if your Data type is in PlutusTx.Prelude, you should not need the other modules in general. The exception is if other parts of your code use that module.


text:
Cardano dapp user authentication based on the wallet address
What are the best options to add user-authentication system based on the wallet address for my website? Thanks

There a few ways to do this- one way I've seen is to request a very specific (small) amount of ADA from that wallet, then send it back (minus TX fees).
Alternatively, you may ask the wallet holder to sign a message with their private key, as specified by CIP-8


text:
4 purchased CNFTs showing no asset image?
asset1w2pqwj7cnv0dw40rtgv5vuzwa7jswcl24lkyw6
a0e859a7b29dbfc2b798ed720802fff406fe09b8e3c9a6b3affb7320
asset19s8v6a43k4ngrmy6wvccxqm08kuae4hfftt0ah
a0e859a7b29dbfc2b798ed720802fff406fe09b8e3c9a6b3affb7320
asset1pe24aeqhr0z9d0cq6pgrjf7dzegrdkgf0dv9af
84c0acb101c14416ad92859c429058871e201804468d5f353be31d71
asset1v34sp6q60z2c2u8fy6gh0su8hc0frghmtr0n9g
a0e859a7b29dbfc2b798ed720802fff406fe09b8e3c9a6b3affb7320
Policy IDs and fingerprints of the 4 CNFTs
I have bought 11 altogether and all the rest have no issues.
Any help would be greatly appreciated.

where do you try to check and you find no asset image?
for all your assets i check on links below, using the asset ID next to pool.pm/asset_here :
https://pool.pm/asset1w2pqwj7cnv0dw40rtgv5vuzwa7jswcl24lkyw6
you can replace the "assetXXXX" with one of your address in your wallet, and you can see all your tokens in your wallet.
please let me know if you need something more,
TTS17


text:
How to Make a Successful CIP?
I am finding the current state of Plutus is not suitable for my purposes, as such I wish to make a CIP.
How do I make the CIP?
What should I do to optimise the CIP and maximise the chances of it being accepted?

So I managed to find a youtube Video by IOHK that describes everything in detail. This one video should be everything you need other than the GitHub repo it mentions.
IOHK Video: https://www.youtube.com/watch?v=q7U10EfqXJw
IOHK CIP Repo: https://github.com/cardano-foundation/CIPs

I have not gotten our CIP accepted (yet), but I suppose following the CIP process (CIP-1), being clear on the motivation, rationale, specification and rigorous in the overall analysis, plus laying out a plan should be a good start. From there, the CIP editors and others from the community would review & request clarifications.
There is even CIP-35 currently in flight, proposed by the plutus team  themselves, on how to evolve & propose changes to plutus in various dimensions!

To complete @Sebastian Nagel's answer, I would suggest to read CIP-0001 and in particular the section titled "How to champion a CIP beyond Draft / Progression to Active status".
Generally speaking, if you want a CIP to be accepted, it must obviously be well-written and contains sufficient details and justifications to be self-assessing. Yet, it must also demonstrate usefulness for the community and the best way to show this is to discuss the proposal (or the idea of it) in public forums upfront. Discussions also often happen on pull requests proposing new CIPs.
Finally, when a CIP refers to a protocol or an implementation change, it must be technically feasible, sound and secure. For Plutus, CIP-35 (tentatively) does already provides nice guidelines to drive this.


text:
Trying to understand import, browse, "as" and other terminology
I'm trying to understand at the lowest level exactly how Plutus/Haskell/Cabal works.
I executed the following in the repl (inside nix):
> import PlutusTx.Builtins.Internal as PTxBI

Doing this causes no error, and I see the Prelude prompt now includes "PTxBI".
Yet I cannot work with "PTxBI". I cannot browse it, get info, etc. The image shows some of my attempts (mostly to see what error messages get generated). I find the "not in scope" errors very curious.
If I enter
> :browse PlutusTx.Builtins.Internal

I do get meaningful, error-free output.
Why does the repl not recognize "PTxBI"? It obviously recognized it well enough to include it in the Prelude prompt. This feels like broken behavior.

browse: apparently you can't use the alias of an imported module when browsing

import Data.Maybe as DM
:browse Data.Maybe           ~> works
:browse DM                   ~> throws an error

info: according to the docs, :i gives you information about a name. The alias of a module is not a name, neither is the name of the module, i.e.

:i Data.Maybe   ~> throws an error
:i Maybe        ~> works

type: according to the docs, :t gives you the type of an expression. The alias/name of a module is not an expression, i.e.

:t Data.Maybe   ~> throws an error
:t Maybe        ~> throws an error, a type is not an expression
:t Just         ~> works

let m = PTxBI 17: you need a constructor after the equal sign, not the alias of a module. You could write PTxBI.BuiltinInteger.

Point #1 was the main thing, and you've basically confirmed my experience (2-4 were just doodles to see what error was produced). I suppose rather than "broken" behavior this is more properly viewed as "incomplete" behavior, but IMHO if you're going to specify an alias for something, that alias should work everywhere that the something works.

I couldn't tell you where ghci is maintained, but perhaps you could report this as an issue.


text:
How do you Connect ATALA to Plutus Smart Contracts
I think they use diffrent programming languages, but how can I use DID inside my Plutus contracts?

I do not have the answer for you but you are welcome to join the Atala PRISM Pioneer Program to find out how this can be done! https://atalaprism.io/app

In the current state of the two projects it is impossible to do so on the Plutus mainnet. The problem here is not that they use different languages (although that does make things a little trickier) its the fact that ATALA requires custom infrastructure (nodes) that do not currently exist in Plutus.


text:
mkSchemaDefinitions compilation error
Does someone know the what mkSchemaDefinitions accomplishes and how it accomplishes it? Lars calls it boilerplate code, but now that I'm having an issue with it I have no idea how to fix it. I'll attach the error message along with my relevant code.
 error:
    • No instance for (Schema.ToSchema MintParams)
        arising from a use of ‘Playground.Schema.endpointsToSchemas’
    • In the expression:
        Playground.Schema.endpointsToSchemas
          @((.\/) (Endpoint "mint" MintParams) (Endpoint "sell" SellParams))
      In an equation for ‘schemas’:
          schemas
            = Playground.Schema.endpointsToSchemas
                @((.\/) (Endpoint "mint" MintParams) (Endpoint "sell" SellParams))
    |
180 | mkSchemaDefinitions ''RoyaltySchema

type RoyaltySchema =
            Endpoint "mint" MintParams
        .\/ Endpoint "sell" SellParams

mkSchemaDefinitions ''RoyaltySchema
mkKnownCurrencies []

data MintParams = MintParams
    { name :: !TokenName
    , addr :: !Address
    } deriving (Generic, FromJSON, ToJSON, Show)

You should answer your own question rather than simply commenting that you fixed it.

I was able to fix this issue by adding ToSchema to the deriving statement

Would be good to add the actual statement change as code, not just describe it.


text:
How Do I Deploy a Plutus Contract From the Browser?
I want the user to go to my website and enter some details into a form. This data should then be converted into an input for my parameterised smart contract (written in Plutus).
I can do the website and JavaScript parts, but how do I then deploy the contract to the chain with the parameterisation?

This sounds similar to a project I'm working on. The links in your bio don't seem to be working, but if you're interested feel free to reach out to me


text:
How to convert a Stake Key Address from hash to BECH32?
I have this Stake Key:
https://testnet.cardanoscan.io/stakekey/7622b4611b15441e7e15cba128ff999ad72388aeb267adc6e70cc9bc?tab=stakehistory
I want to convert from 7622b4611b15441e7e15cba128ff999ad72388aeb267adc6e70cc9bc to stake_test1upmz9drprv25g8n7zh96z28lnxddwgug46ex0twxuuxvn0qp3cptz format.
How do I do it using this library https://github.com/Emurgo/cardano-serialization-lib?
Thanks

The beech32 representation is a bit tricky, but you can do it like this:
const stakeKey = StakeCredential.from_bytes(from_hex('7622b4611b15441e7e15cba128ff999ad72388aeb267adc6e70cc9bc'));
const networkId = 1; // testnet = 1, mainnet = 0
const beech32StakeKey = RewardAddress.new(networkId, stakeKey).to_address().to_bech32();
console.log(beech32StakeKey);

Hope this helps. The "from_hex" function is just a simple js function to convert the Hex string into an UInt8Array that is needed for the from_bytes function of StakeCredentials.


text:
How to make module Week07.EvenOdd fairer with player2 in case player2 wins the game
In week07 lecture Lars refers that Week07.EvenOdd contract is a bit unfair with player2 in the case of player2 wins .
Why  ?
Well, player2 has to pay minAdaTxOut (2 ADA) to player1 in order to send back the token to player1. (Remember: an UTXO must include a minimum value of 2 ADAs ) Therefore, player2 wins 2 ADAs less than he/she should.
Lars says that a possible solution is to create some kind of deposit from player1 locked in the validator.

Here, I've implemented a possible solution following Lars' approach.
Basically:

When player1 starts the contract, apart from locking the game stake value, player1 will lock a value player1Deposit consisting of 2 ADAs (minAdaTxOut).

Add extra constraints to the validator script, which will check that player1Deposit keeps locked into the contract until the contracts terminates.

This way, when the token gets sent back to player1 along with the mandatory minAdaTxOut, player2 won't have to pay minAdaTxOut because that value is already in the contract (the mentioned player1Deposit).
The evidence.

Here's the code.
{-# LANGUAGE DataKinds             #-}
{-# LANGUAGE DeriveAnyClass        #-}
{-# LANGUAGE DeriveGeneric         #-}
{-# LANGUAGE FlexibleContexts      #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE NoImplicitPrelude     #-}
{-# LANGUAGE NumericUnderscores    #-}
{-# LANGUAGE OverloadedStrings     #-}
{-# LANGUAGE ScopedTypeVariables   #-}
{-# LANGUAGE TemplateHaskell       #-}
{-# LANGUAGE TypeApplications      #-}
{-# LANGUAGE TypeFamilies          #-}
{-# LANGUAGE TypeOperators         #-}

module Week07.EvenOdd
    ( Game (..)
    , GameChoice (..)
    , FirstParams (..)
    , SecondParams (..)
    , GameSchema
    , endpoints
    ) where

import           Control.Monad        hiding (fmap)
import           Data.Aeson           (FromJSON, ToJSON)
import qualified Data.Map             as Map
import           Data.Text            (Text)
import           GHC.Generics         (Generic)
import           Ledger               hiding (singleton)
import           Ledger.Constraints   as Constraints
import qualified Ledger.Typed.Scripts as Scripts
import           Ledger.Ada           as Ada
import           Ledger.Value
import           Playground.Contract  (ToSchema)
import           Plutus.Contract      as Contract
import qualified PlutusTx
import           PlutusTx.Prelude     hiding (Semigroup(..), unless)
import           Prelude              (Semigroup (..), Show (..), String)
import qualified Prelude

data Game = Game
    { gFirst          :: !PaymentPubKeyHash
    , gSecond         :: !PaymentPubKeyHash
    , gStake          :: !Integer
    , gPlayDeadline   :: !POSIXTime
    , gRevealDeadline :: !POSIXTime
    , gToken          :: !AssetClass
    } deriving (Show, Generic, FromJSON, ToJSON, Prelude.Eq, Prelude.Ord)

PlutusTx.makeLift ''Game

data GameChoice = Zero | One
    deriving (Show, Generic, FromJSON, ToJSON, ToSchema, Prelude.Eq, Prelude.Ord)

instance Eq GameChoice where
    {-# INLINABLE (==) #-}
    Zero == Zero = True
    One  == One  = True
    _    == _    = False

PlutusTx.unstableMakeIsData ''GameChoice

data GameDatum = GameDatum BuiltinByteString (Maybe GameChoice)
    deriving Show

instance Eq GameDatum where
    {-# INLINABLE (==) #-}
    GameDatum bs mc == GameDatum bs' mc' = (bs == bs') && (mc == mc')

PlutusTx.unstableMakeIsData ''GameDatum

data GameRedeemer = Play GameChoice | Reveal BuiltinByteString | ClaimFirst | ClaimSecond
    deriving Show

PlutusTx.unstableMakeIsData ''GameRedeemer

{-# INLINABLE lovelaces #-}
lovelaces :: Value -> Integer
lovelaces = Ada.getLovelace . Ada.fromValue

{-# INLINABLE gameDatum #-}
gameDatum :: Maybe Datum -> Maybe GameDatum
gameDatum md = do
    Datum d <- md
    PlutusTx.fromBuiltinData d

{-# INLINABLE choiceToBuiltinByteString #-}
choiceToBuiltinByteString :: GameChoice -> BuiltinByteString
choiceToBuiltinByteString Zero = "0"
choiceToBuiltinByteString One  = "1"

{-# INLINABLE player1Deposit #-}
player1Deposit :: Integer
player1Deposit = Ada.getLovelace minAdaTxOut

{-# INLINABLE mkGameValidator #-}
mkGameValidator :: Game -> GameDatum -> GameRedeemer -> ScriptContext -> Bool
mkGameValidator game dat red ctx =
    traceIfFalse "token missing from input" (assetClassValueOf (txOutValue ownInput) (gToken game) == 1) &&
    case (dat, red) of
        (GameDatum bs Nothing, Play c) ->
            traceIfFalse "not signed by second player"       (txSignedBy info (unPaymentPubKeyHash $ gSecond game))                    &&
            traceIfFalse "first player's stake missing"      (lovelaces (txOutValue ownInput) == gStake game + player1Deposit)         &&
            traceIfFalse "second player's stake missing"     (lovelaces (txOutValue ownOutput) == (2 * gStake game + player1Deposit))  &&
            traceIfFalse "wrong output datum"                (outputDatum == GameDatum bs (Just c))                                    &&
            traceIfFalse "missed deadline"                   (to (gPlayDeadline game) `contains` txInfoValidRange info)                &&
            traceIfFalse "token missing from output"         (assetClassValueOf (txOutValue ownOutput) (gToken game) == 1)

        (GameDatum bs (Just c), Reveal nonce) ->
            traceIfFalse "not signed by first player"        (txSignedBy info (unPaymentPubKeyHash $ gFirst game))                     &&
            traceIfFalse "commit mismatch"                   (checkNonce bs nonce c)                                                   &&
            traceIfFalse "missed deadline"                   (to (gRevealDeadline game) `contains` txInfoValidRange info)              &&
            traceIfFalse "wrong stake"                       (lovelaces (txOutValue ownInput) == (2 * gStake game + player1Deposit))   &&
            traceIfFalse "NFT must go to first player"       nftToFirst                                                                &&
            traceIfFalse "Player1 must get back the deposit" player1DepositBack

        -- Here we mustn't set player1Deposit constraint.
        -- If we did it and player1 didn't put the deposit at the beginning, the funds would block forever in the validator.
        (GameDatum _ Nothing, ClaimFirst) ->
            traceIfFalse "not signed by first player"        (txSignedBy info (unPaymentPubKeyHash $ gFirst game))                     &&
            traceIfFalse "too early"                         (from (1 + gPlayDeadline game) `contains` txInfoValidRange info)          &&
            traceIfFalse "first player's stake missing"      (lovelaces (txOutValue ownInput) == gStake game)                          &&
            traceIfFalse "NFT must go to first player"       nftToFirst

        (GameDatum _ (Just _), ClaimSecond) ->
            traceIfFalse "not signed by second player"       (txSignedBy info (unPaymentPubKeyHash $ gSecond game))                    &&
            traceIfFalse "too early"                         (from (1 + gRevealDeadline game) `contains` txInfoValidRange info)        &&
            traceIfFalse "wrong stake"                       (lovelaces (txOutValue ownInput) == (2 * gStake game + player1Deposit))   &&
            traceIfFalse "NFT must go to first player"       nftToFirst                                                                &&
            traceIfFalse "Player1 must get back the deposit" player1DepositBack

        _ -> False
  where
    info :: TxInfo
    info = scriptContextTxInfo ctx

    ownInput :: TxOut
    ownInput = case findOwnInput ctx of
        Nothing -> traceError "game input missing"
        Just i  -> txInInfoResolved i

    ownOutput :: TxOut
    ownOutput = case getContinuingOutputs ctx of
        [o] -> o
        _   -> traceError "expected exactly one game output"

    outputDatum :: GameDatum
    outputDatum = case gameDatum $ txOutDatumHash ownOutput >>= flip findDatum info of
        Nothing -> traceError "game output datum not found"
        Just d  -> d

    checkNonce :: BuiltinByteString -> BuiltinByteString -> GameChoice -> Bool
    checkNonce bs nonce cSecond = sha2_256 (nonce `appendByteString` choiceToBuiltinByteString cSecond) == bs

    nftToFirst :: Bool
    nftToFirst = assetClassValueOf (valuePaidTo info $ unPaymentPubKeyHash $ gFirst game) (gToken game) == 1

    player1DepositBack :: Bool
    player1DepositBack = valuePaidTo info (unPaymentPubKeyHash $ gFirst game) `geq` Ada.lovelaceValueOf player1Deposit

data Gaming
instance Scripts.ValidatorTypes Gaming where
    type instance DatumType Gaming = GameDatum
    type instance RedeemerType Gaming = GameRedeemer

typedGameValidator :: Game -> Scripts.TypedValidator Gaming
typedGameValidator game = Scripts.mkTypedValidator @Gaming
    ($$(PlutusTx.compile [|| mkGameValidator ||])
        `PlutusTx.applyCode` PlutusTx.liftCode game)
    $$(PlutusTx.compile [|| wrap ||])
  where
    wrap = Scripts.wrapValidator @GameDatum @GameRedeemer

gameValidator :: Game -> Validator
gameValidator = Scripts.validatorScript . typedGameValidator

gameAddress :: Game -> Ledger.Address
gameAddress = scriptAddress . gameValidator

findGameOutput :: Game -> Contract w s Text (Maybe (TxOutRef, ChainIndexTxOut, GameDatum))
findGameOutput game = do
    utxos <- utxosAt $ gameAddress game
    return $ do
        (oref, o) <- find f $ Map.toList utxos
        dat       <- gameDatum $ either (const Nothing) Just $ _ciTxOutDatum o
        return (oref, o, dat)
  where
    f :: (TxOutRef, ChainIndexTxOut) -> Bool
    f (_, o) = assetClassValueOf (_ciTxOutValue o) (gToken game) == 1

waitUntilTimeHasPassed :: AsContractError e => POSIXTime -> Contract w s e ()
waitUntilTimeHasPassed t = do
    s1 <- currentSlot
    logInfo @String $ "current slot: " ++ show s1 ++ ", waiting until " ++ show t
    void $ awaitTime t >> waitNSlots 1
    s2 <- currentSlot
    logInfo @String $ "waited until: " ++ show s2

data FirstParams = FirstParams
    { fpSecond         :: !PaymentPubKeyHash
    , fpStake          :: !Integer
    , fpPlayDeadline   :: !POSIXTime
    , fpRevealDeadline :: !POSIXTime
    , fpNonce          :: !BuiltinByteString
    , fpCurrency       :: !CurrencySymbol
    , fpTokenName      :: !TokenName
    , fpChoice         :: !GameChoice
    } deriving (Show, Generic, FromJSON, ToJSON, ToSchema)

firstGame :: forall w s. FirstParams -> Contract w s Text ()
firstGame fp = do
    pkh <- Contract.ownPaymentPubKeyHash
    let game = Game
            { gFirst          = pkh
            , gSecond         = fpSecond fp
            , gStake          = fpStake fp
            , gPlayDeadline   = fpPlayDeadline fp
            , gRevealDeadline = fpRevealDeadline fp
            , gToken          = AssetClass (fpCurrency fp, fpTokenName fp)
            }
        v    = lovelaceValueOf (fpStake fp) <> assetClassValue (gToken game) 1 <> Ada.lovelaceValueOf player1Deposit
        c    = fpChoice fp
        bs   = sha2_256 $ fpNonce fp `appendByteString` choiceToBuiltinByteString c
        tx   = Constraints.mustPayToTheScript (GameDatum bs Nothing) v
    ledgerTx <- submitTxConstraints (typedGameValidator game) tx
    void $ awaitTxConfirmed $ getCardanoTxId ledgerTx
    logInfo @String $ "made first move: " ++ show (fpChoice fp)

    waitUntilTimeHasPassed $ fpPlayDeadline fp

    m   <- findGameOutput game
    now <- currentTime
    case m of
        Nothing             -> throwError "game output not found"
        Just (oref, o, dat) -> case dat of
            GameDatum _ Nothing -> do
                logInfo @String "second player did not play"
                let lookups = Constraints.unspentOutputs (Map.singleton oref o) <>
                              Constraints.otherScript (gameValidator game)
                    tx'     = Constraints.mustSpendScriptOutput oref (Redeemer $ PlutusTx.toBuiltinData ClaimFirst) <>
                              Constraints.mustValidateIn (from now)
                ledgerTx' <- submitTxConstraintsWith @Gaming lookups tx'
                void $ awaitTxConfirmed $ getCardanoTxId ledgerTx'
                logInfo @String "reclaimed stake"

            GameDatum _ (Just c') | c' == c -> do

                logInfo @String "second player played and lost"
                let lookups = Constraints.unspentOutputs (Map.singleton oref o) <>
                              Constraints.otherScript (gameValidator game)
                    tx'     = Constraints.mustSpendScriptOutput oref (Redeemer $ PlutusTx.toBuiltinData $ Reveal $ fpNonce fp) <>
                              Constraints.mustValidateIn (to $ now + 1000)
                ledgerTx' <- submitTxConstraintsWith @Gaming lookups tx'
                void $ awaitTxConfirmed $ getCardanoTxId ledgerTx'
                logInfo @String "victory"

            _ -> logInfo @String "second player played and won"

data SecondParams = SecondParams
    { spFirst          :: !PaymentPubKeyHash
    , spStake          :: !Integer
    , spPlayDeadline   :: !POSIXTime
    , spRevealDeadline :: !POSIXTime
    , spCurrency       :: !CurrencySymbol
    , spTokenName      :: !TokenName
    , spChoice         :: !GameChoice
    } deriving (Show, Generic, FromJSON, ToJSON, ToSchema)

secondGame :: forall w s. SecondParams -> Contract w s Text ()
secondGame sp = do
    pkh <- Contract.ownPaymentPubKeyHash
    let game = Game
            { gFirst          = spFirst sp
            , gSecond         = pkh
            , gStake          = spStake sp
            , gPlayDeadline   = spPlayDeadline sp
            , gRevealDeadline = spRevealDeadline sp
            , gToken          = AssetClass (spCurrency sp, spTokenName sp)
            }
    m <- findGameOutput game
    case m of
        Just (oref, o, GameDatum bs Nothing) -> do
            logInfo @String "running game found"
            now <- currentTime
            let token   = assetClassValue (gToken game) 1
            let v       = let x = lovelaceValueOf (spStake sp) in x <> x <> token <> Ada.lovelaceValueOf player1Deposit
                c       = spChoice sp
                lookups = Constraints.unspentOutputs (Map.singleton oref o)                                   <>
                          Constraints.otherScript (gameValidator game)                                        <>
                          Constraints.typedValidatorLookups (typedGameValidator game)
                tx      = Constraints.mustSpendScriptOutput oref (Redeemer $ PlutusTx.toBuiltinData $ Play c) <>
                          Constraints.mustPayToTheScript (GameDatum bs $ Just c) v                            <>
                          Constraints.mustValidateIn (to now)
            ledgerTx <- submitTxConstraintsWith @Gaming lookups tx
            let tid = getCardanoTxId ledgerTx
            void $ awaitTxConfirmed tid
            logInfo @String $ "made second move: " ++ show (spChoice sp)

            waitUntilTimeHasPassed $ spRevealDeadline sp

            m'   <- findGameOutput game
            now' <- currentTime
            case m' of
                Nothing             -> logInfo @String "first player won"
                Just (oref', o', _) -> do
                    logInfo @String "first player didn't reveal"
                    let lookups' = Constraints.unspentOutputs (Map.singleton oref' o')                                     <>
                                   Constraints.otherScript (gameValidator game)
                        tx'      = Constraints.mustSpendScriptOutput oref' (Redeemer $ PlutusTx.toBuiltinData ClaimSecond) <>
                                   Constraints.mustValidateIn (from now')                                                  <>
                                   Constraints.mustPayToPubKey (spFirst sp) (token <> Ada.lovelaceValueOf player1Deposit)
                    ledgerTx' <- submitTxConstraintsWith @Gaming lookups' tx'
                    void $ awaitTxConfirmed $ getCardanoTxId ledgerTx'
                    logInfo @String "second player won"

        _ -> logInfo @String "no running game found"

type GameSchema = Endpoint "first" FirstParams .\/ Endpoint "second" SecondParams

endpoints :: Contract () GameSchema Text ()
endpoints = awaitPromise (first `select` second) >> endpoints
  where
    first  = endpoint @"first"  firstGame
    second = endpoint @"second" secondGame


text:
Error querying protocol parameters in local network created from scratch
I'm creating a local testnet for development purposes with the following steps:
  # create genesis files:
  mkdir /tmp/cardano
  cd /tmp/cardano
  cardano-cli genesis create --testnet-magic 777 --gen-genesis-keys 1 --gen-utxo-keys 1 --supply 1000000000 --genesis-dir /tmp/cardano/

  # KES keys
  cardano-cli node key-gen-KES --verification-key-file /tmp/cardano/kes.vkey --signing-key-file /tmp/cardano/kes.skey

  # Operational certificate (VRF keys created automatically under /tmp/cardano/delegate-keys/)
    cardano-cli node issue-op-cert --kes-verification-key-file /tmp/cardano/kes.vkey --cold-signing-key-file /tmp/cardano/delegate-keys/delegate1.skey --operational-certificate-issue-counter /tmp/cardano/delegate-keys/delegate1.counter --kes-period 0 --out-file /tmp/cardano/op.cert

  # download & tweak node configuration
    wget https://raw.githubusercontent.com/input-output-hk/cardano-node/master/configuration/defaults/byron-mainnet/configuration.yaml
    sed -i 's/Protocol: RealPBFT/Protocol: TPraos/' configuration.yaml
    sed -i 's/minSeverity: Info/minSeverity: Debug/' configuration.yaml

   # create a topology file (empty because I'm not conneting to anyone)
    echo '{"Producers": []}' > node-topology.json

   # start the node:
     cardano-node run \
      --config configuration.yaml \
      --topology node-topology.json \
      --database-path /tmp/cardano/db \
      --socket-path /tmp/cardano/db/node.socket \
      --shelley-kes-key /tmp/cardano/kes.skey \
      --shelley-vrf-key /tmp/cardano/delegate-keys/delegate1.vrf.skey \
      --shelley-operational-certificate /tmp/cardano/op.cert \
      --port 7777

Everything seems to work  fine up until this point. However, when I try to query the protocol parameters:
   # Check node status
   export CARDANO_NODE_SOCKET_PATH=/tmp/cardano/db/node.socket
   cardano-cli query protocol-parameters --testnet-magic 777

I get this error:
cardano-cli: encodeFailure: local state query: using acquire without a Point must be conditional on negotiating v8 of the node-to-client protocol
CallStack (from HasCallStack):
  error, called at src/Ouroboros/Network/Protocol/LocalStateQuery/Codec.hs:80:7 in ouroboros-network-0.1.0.0-IeuFKu6VZwxK0UqIEQ0YeE:Ouroboros.Network.Protocol.LocalStateQuery.Codec[

Querying a UTxO also produces the same error:
cardano-cli query utxo --testnet-magic 777 --cardano-mode --address addr_test1vz9vqpp232vpgh9w7m86qwy48a0e2c99thvqkp6jvatutecfngfmt

cardano-cli: encodeFailure: local state query: using acquire without a Point must be conditional on negotiating v8 of the node-to-client protocol
CallStack (from HasCallStack):
  error, called at src/Ouroboros/Network/Protocol/LocalStateQuery/Codec.hs:80:7 in ouroboros-network-0.1.0.0-IeuFKu6VZwxK0UqIEQ0YeE:Ouroboros.Network.Protocol.LocalStateQuery.Codec

I'm not exactly sure what this error means and what can be done to make these commands work. It used to work fine with older cardano-node versions and I was able to execute local tests very efficiently with this. My current version is:
cardano-node 1.33.0 - linux-x86_64 - ghc-8.10
git rev 814df2c146f5d56f8c35a681fe75e85b905aed5d

Can anyone help me getting a local blockchain started from scratch? The only documentation I found seems to be outdated (here: https://cardano-foundation.gitbook.io/stake-pool-course/reference/shelley-genesis)

You might want to build your script using mkfiles.sh script instead.
While TPraos based networks will stand up and function for basic node/CLI commands, there are a lot of nuances and not all tools/components built around will support the network. Instead you can make use of config options to allow your nodes to fork into specific eras - important to note tho, that when using Cardano mode in config, your Shelley genesis should not include initialFunds - which would break support for that network for components like cardano-db-sync.

You could increase the node logging to 'debug' and restart it, then retry the CLI command while monitoring the log.
Could be some more detailed info in the node log.
As an FYI I get the same error if I try to force a different mode on my mainnet connection eg --shelley-mode addded:
$cardano-cli query protocol-parameters --shelley-mode --mainnet

cardano-cli: encodeFailure: local state query: using acquire without a Point must be conditional on negotiating v8 of the node-to-client protocol
CallStack (from HasCallStack):
  error, called at src/Ouroboros/Network/Protocol/LocalStateQuery/Codec.hs:80:7 in ouroboros-network-0.1.0.0-12...12:Ouroboros.Network.Protocol.LocalStateQuery.Codec

Your setup might need --shelley-mode rather than the default --cardano-mode .
eg

cardano-cli query protocol-parameters --shelley-mode --testnet-magic
777

I presume that cardano-cli is also version 1.33.0?

The guide that you followed is from 2020 and refers to cardano-cli version 1.11.0 - a lot has changed since then.


text:
Short address crashed blockfrost calls
Using blockfrost I have pulled a list of addresses of owners of a specific fungible token.
Some of the addresses are significantly smaller than the others (about  2/3 the length).
When querying blockfrost for stake keys (or pool.pm) with those addresses i get an error 504 after a long timeout, while all the others work smoothly.
An example of the syntax and function used with python is the following api.address(addr_str)
Here is the address causing me trouble addr1w999n67e86jn6xal07pzxtrmqynspgx0fwmcmpua4wc6yzsxpljz3
How should I handle those, what are they?

Those are called Enterprise addresses, originally intended for exchanges but everyday users have started to adopt them for various reasons. Unfortunately, I can't speak to why Blockfrost API chokes when it encounters one, but there are other APIs that support these. Try Koios for example.
https://api.koios.rest/#get-/address_assets
EDIT: Ah! Just noticed an important part of your message.. The reason you're getting the timeout error is because enterprise addresses do not have stake addresses as they were never meant to stake (again they are intended for exchanges). That's why this is timing out.

Wow, thanks for the great answer !! That makes perfect sense. Do you have any specific way to spot those addresses (length of the address?)

Yes, length of address would be a great way to go. As far as I know the enterprise addresses are all the same length. The reason they are shorter is because they lack the stake key hash.


text:
what info is in datum value and how can we extract it
In the case for spend purposes e.g.
Value: {"fields": [{"bytes": "10dc9481577ae0ac7a2b828bae9f2ba163b79ce73069d75fd609bc88"}, {"bytes": "a20a"}], "constructor": 0}

what kind of information is found in the first and second bytes field, and how does one extract this?


text:
passing the thread token
In the firstGame function, we use the "logging" component of the contract to tell the thread token. It's not obvious to me where this is needed: is there an internal check in the runStep function that this token matches the one in the parameter, i.e. SecondParams? I commented out the line where tt is told and that results in an endless loop, while I expected a failure.

Because firstGame is the contract that initialises the game, it needs to communicate somehow the generated threadToken to the external world (secondGame in this case). For this kind of communication Contract monad uses tell mechanism.
How does the info flow? You can see it in myTrace function in Week07.TestStateMachine.

(1) callEndpoint @"first" h1 fp - Initialise the game, and firstGame contract internally tells the generated threadToken to anyone interested in it.

(2) tt <- getTT h1 - This function uses observableState function, which "get the observable state w of a contract instance". In our case w in firstGame Contract is (Last ThreadToken).

   firstGame :: forall s. FirstParams -> Contract (Last ThreadToken) s Text ()

(3) let sp = SecondParams {...  spToken = tt ...} - Build params for secondGame using threadToken generated by firstGame contract, tt.

(4) callEndpoint @"second" h2 sp - secondGame plays.

Notice that communication is not direct Contract to Contract but through observableState function
myTrace :: GameChoice -> GameChoice -> EmulatorTrace ()
myTrace c1 c2 = do
    Extras.logInfo $ "first move: " ++ show c1 ++ ", second move: " ++ show c2

    let w1 = knownWallet 1
    let w2 = knownWallet 2

    h1 <- activateContractWallet w1 endpoints
    h2 <- activateContractWallet w2 endpoints

    let pkh1      = mockWalletPaymentPubKeyHash w1
        pkh2      = mockWalletPaymentPubKeyHash w2
        stake     = 5_000_000
        deadline1 = slotToEndPOSIXTime def 5
        deadline2 = slotToEndPOSIXTime def 10

        fp = FirstParams
                { fpSecond         = pkh2
                , fpStake          = stake
                , fpPlayDeadline   = deadline1
                , fpRevealDeadline = deadline2
                , fpNonce          = "SECRETNONCE"
                , fpChoice         = c1
                }

    callEndpoint @"first" h1 fp   -- (1)

    tt <- getTT                   -- (2)

    let sp = SecondParams         -- (3)
                { spFirst          = pkh1
                , spStake          = stake
                , spPlayDeadline   = deadline1
                , spRevealDeadline = deadline2
                , spChoice         = c2
                , spToken          = tt
                }

    void $ Emulator.waitNSlots 3  -- (4)

    callEndpoint @"second" h2 sp

    void $ Emulator.waitNSlots 10
  where
    getTT :: ContractHandle (Last ThreadToken) GameSchema Text -> EmulatorTrace ThreadToken
    getTT h = do
        void $ Emulator.waitNSlots 1
        Last m <- observableState      -- (2)
        case m of
            Nothing -> getTT h
            Just tt -> Extras.logInfo ("read thread token " ++ show tt) >> return tt

Ouch, my bad, I didn't look at the test. The getTT method also explains the loop when I comment out the tell.


text:
Logic behind Cardano master key generation from mnemonic
Could anyone clarify the logic  behind Cardano master key generation from mnemonic.
There is a specification BIP32-Ed25519 https://github.com/LedgerHQ/orakolo/blob/master/papers/Ed25519_BIP%20Final.pdf
But it seems that Cardano doesn't use that algorithm https://github.com/input-output-hk/cardano-addresses/blob/e3ce58addfeefccc16db888008d57fa9a732464d/core/lib/Cardano/Address/Style/Shelley.hs#L1047-L1060

The seed phrase is generated in cardano-addresses, briefly explained here. This is then used as entropy for private key generation, the logic for this is in cardano-crypto package


text:
How to generate TransactionBody in cardano-serialization lib from cardano-cli's TxBodyAlonzo cborHex
I want to get cborHex from cardano-cli transaction build output and use it with cardano-serialization-lib to recreate the transaction body. I tried the following:
cborHex = '86a80081825820b9f5091d866b60db8ea3548d987fc237e5d89c8159aa6ddcee28fcf98b93860e000d80018282583900c19efef37292ee5b59ec5683ed52b537f43b1763f48469760affda73d6587eb03872ccf2ea313c55a5e6cfee9a409541dfa9b61fe35dfb921a3ab510f983581d70d5fa699784d82763328fbaee27412967a95f3371dfd69df3ceece8e71a004c4b405820851fe9c7b4b2e760c8b5f77a10963ea75a989f9285dcf988f637b814fd89946b021a0002c699031a03162a4508000e80075820f02f7b2a5ec946db2417a9afd42e27528763d39c3bf758fff7e9871230212c8e9fff8080f5d90103a100a1190cffa365646174756da26b636f6e7374727563746f7200666669656c647382a165627974657378386331396566656633373239326565356235396563353638336564353262353337663433623137363366343834363937363061666664613733a163696e741b000000075140a9da6b7573657241646472657373827840616464725f746573743171727165616c686e77326677756b366561337467386d326a6b356d6c67776368763036676736746b70746c613575376b74706c747177782c726a656e657735766675326b6a37646e6c776e6671663273776c34786d706c6336616c7766716e78306466326c77616e746564416d6f756e741b00000007b3d84700'
bytes = Buffer.from(cborHex, 'hex')
CardanoWasm.TransactionBody.from_bytes(bytes)

I am getting error
Uncaught Deserialization failed in TransactionBody because: Invalid cbor: not the right type, expected `Map' byte received `Array'

Is it possible to do this, and if yes what I am doing wrong?

In the new version of cardano-cli which is shipped with cardano-node 1.34 there is a new flag for transaction build --cddl-format which creates the same cbor like it is used in ledger https://github.com/input-output-hk/cardano-node/pull/3505. With this flag results cborHex is compatible with cardano-serialization-lib.
  const txBytes = Buffer.from(cborHex, 'hex')
  const tx = S.Transaction.from_bytes(txBytes)
  const txBody = tx.body()
  const txAuxilaryData = tx.auxiliary_data()
  const txHash = S.hash_transaction(txBody)

  const witnesses = S.TransactionWitnessSet.new()
  const vkeyWitnesses = S.Vkeywitnesses.new()
  vkeyWitnesses.add(S.make_vkey_witness(txHash, signKey))
  witnesses.set_vkeys(vkeyWitnesses)

  const transaction = S.Transaction.new(txBody, witnesses, txAuxilaryData)
  const cborSignedHex = Buffer.from(transaction.to_bytes()).toString('hex')

This solves the problem in the topic but I have currently another problem that auxilary_data is not the same and I got an error on submit ConflictingMetadataHash. Looks like an issue with cardano-serialization-lib https://github.com/Emurgo/cardano-serialization-lib/issues/396

How to get signKey at frontend from nami wallet?


text:
What are the block heights of the different eras of cardano?
According to the roadmap Cardano has (or will have) five eras. Byron, Shelley, Goguen, Basho and Voltaire. What block height did Cardano change from one era to the next?

This is the best resource I've found online.

Source

Byron (Genesis) (09/27/2017) - Epoch 1, Block 1?
Shelley (07/29/2020) - Epoch 208, Block 4490511
Goguen (if you consider Alonzo HFC the start of Goguen) (09/12/2021) - Epoch 290, Block 6236060
Basho and Voltaire are currently in development.
Important to note: the Cardano eras are rough pictures of where development is focused during that era, not hard dates. Parts of Shelley and Goguen are still being worked (decentralization parameters and smart contract optimizations, respectively). It is not clear cut whether something like the integrations of CIP 31, 32, and 33 should be considered part of Goguen or Basho. Also, project Catalyst is technically part of Voltaire and has been around for over a year at this point.

Is there a website you got the data from? I am asking so that I can look it up when the next era rolls out.

No, tbh I just remembered

damn that's a good memory

On mainnet:

Byron started at epoch 0.
Shelley started at epoch 208.

Hopefully someone else can fill in the rest.

You are looking for the /network/eras Blockfrost endpoint.