CSK #009


Back to CSK List

Cardano Starter Kit #009

IOHK's Lobster Challenge - The "Hard Way"

I was playing with the Lobster Challenge on Friday, and as nice as it is to have a bash script that can do everything for us, I prefer to understand what's going on when we build the transaction. So in this Cardano Starter Kit, I'm going to look at what's included in the Lobster Challenge repository, and then build my own transaction by hand to complete the challenge.

Click here to see the accompanying video on YouTube

Video Outline

  1. Review the Lobster Challenge repository on GitHub
  2. Take a look at the UTxO's at the script address addr1w8433zk2shufk42hn4x7zznjjuqwwyfmxffcjszw5l2ulesdt3jff
  3. Review the transactions we built in the last two starter kits
  4. Clone the Lobster Challenge repository from GitHub and take a look around.
  5. Create a working transaction so that we can complete the Lobster Challenge!

Let's look at some UTxOs:

LOBSTER="addr1w8433zk2shufk42hn4x7zznjjuqwwyfmxffcjszw5l2ulesdt3jff"
SENDER="addr1qygsn6p33aq936phlrx6usd7mguqnnfea9s9ruwuhqcvlhsdu706suvddaa3zf095hfjgnxfex3xuwut8m4nshyjmxfsjcfewq"
cardano-cli query utxo --mainnet --address $SENDER
cardano-cli query utxo --mainnet --address $LOBSTER

Review simple transaction from CSK #007

In CSK #007, we looked at basic transactions. They look like this:

cardano-cli transaction build-raw \
--tx-in $MYTXIN \
--tx-out $RECEIVER+$SEND \
--tx-out $SENDER+$CHANGE \
--invalid-hereafter $EXPIRE \
--fee $FEE \
--out-file tx.raw

Where:

  • MYTXIN is the hash of a UTxO with sufficient funds to complete the transaction.
  • RECEIVER and SENDER are Cardano addresses.
  • SEND is the number of Lovelace we'd like to send.
  • FEE is the transaction fee, expressed as a number of Lovelace.
  • CHANGE is the number of Lovelace we'll need to give back to the Sender. We started with the total amount of Lovelace in the original UTxO and subtracted the fee and sending amount.
  • EXPIRE is the slot number after which this transaction will no longer be valid.

Review a minting transaction from CSK #008

Then, in CSK# 008, we looked at minting and metadata. I didn't cover everything about minting, but you should recognize how, compared to the basic transaction above, this one has a bit more going on:

cardano-cli transaction build-raw \
--tx-in $TXIN \
--tx-out $SENDER+$CHANGE+"1 YOUR_POLICY_ID_HERE.TOKEN_NAME_A + 1 YOUR_POLICY_ID_HERE.TOKEN_NAME_B" \
--mint="1 YOUR_POLICY_ID_HERE.TOKEN_NAME_A + 1 YOUR_POLICY_ID_HERE.TOKEN_NAME_B" \
--mint-script-file policy/policy.script \
--metadata-json-file metadata.json \
--invalid-hereafter EXPIRATION_SLOT \
--fee $FEE \
--out-file tx.raw

A quick word on minting policies:

Let's look at how to create a minting policy. When we create a minting policy, we are actually following the same steps as when we create a Cardano key pair. Then, we use this policy pair to create a Policy hash (fix wording) that can be signed only if that Policy is met. I recommend reading the official Cardano documentation, linked here.

For quick reference, here is how we create a minting policy:

mkdir policy

cardano-cli address key-gen \
    --verification-key-file policy/policy.vkey \
    --signing-key-file policy/policy.skey

cardano-cli address key-hash --payment-verification-key-file policy/policy.vkey

And here's an example of the policy script for minting:

{
  "scripts": [
    {
      "keyHash": "6ba62524671701f79a1404768dae533f94585173cb671be0e25480e6",
      "type": "sig"
    },
    {
      "slot": 40285765,
      "type": "before"
    }
  ],
  "type": "all"
}

Once a script is written, we can use it to create a new asset:

cardano-cli transaction policyid --script-file ./policy/policy.script 

The output of cardano-cli transaction policyid is the Policy ID that we use when minting new tokens. In order for it to work, any minting transaction using it must be "signed" using the accompanying policy.skey that we created above.

Notice how we're using the same underlying tools in both scenarios. This is a key point as we start to think about contracts.

The Lobster Challenge: Introducing new tools!

On Cardano, Contract addresses look just like Wallet addresses. We can query both of them the same way.

In a similar way, we can create general-purpose Plutus scripts that we reference much like the minting policy for a native asset.

With all of this in mind, let's take a look at how we build the transaction for the Lobster Challenge. This is the code I used in the video to build an acceptable transaction.

cardano-cli transaction build \
    --alonzo-era \
    --mainnet \
    --tx-in $TXIN \
    --tx-in $TXLOB \
    --tx-in-script-file lobster.plutus \
    --tx-in-datum-value [] \
    --tx-in-redeemer-value [] \
    --tx-in-collateral $TXIN \
    --tx-out "$LOBSTER + 2034438 lovelace + 1 cc7888851f0f5aa64c136e0c8fb251e9702f3f6c9efcf3a60a54f419.LobsterNFT + 14191 fda1b6b487bee2e7f64ecf24d24b1224342484c0195ee1b7b943db50.LobsterCounter + 340 fda1b6b487bee2e7f64ecf24d24b1224342484c0195ee1b7b943db50.LobsterVotes" \
    --tx-out-datum-hash 45b0cfc220ceec5b7c1c62c4d4193d38e4eba48e8815729ce75f9c0ab0e4c1c0 \
    --mint "25 fda1b6b487bee2e7f64ecf24d24b1224342484c0195ee1b7b943db50.LobsterCounter + 1 fda1b6b487bee2e7f64ecf24d24b1224342484c0195ee1b7b943db50.LobsterVotes" \
    --mint-script-file other-mint-policy.plutus \
    --mint-redeemer-value [] \
    --change-address $SENDER \
    --protocol-params-file protocol.json \
    --out-file tx.draft

Remember that I had to set the following environment variables in order for this to work:

  • TXIN identifies the UToO in my wallet that I'm using as collateral and to cover fees.
  • TXLOB is the current existing UTxO at the script address of the Lobster Challenge.
  • LOBSTER is the script address.
  • SENDER is my address.
  • For convenience, I could have made additional variables for Policy ID's, for example, and if I wanted to re-use this code, that's probably a good idea.

One more note:

Above, we are using the cardano-cli transaction build function, which is different from cardano-cli transaction build-raw. Notice how build allows us to skip the fee: now fees are calculated automatically. We'll need to dig into this a bit more in the coming weeks, but for now, I just want you to see it. Where we used to have to get the fee and then calculate the "change" by hand, with cardano-cli transaction build-raw, now cardano-cli transaction build takes care of some of that for us.

For more information, you can review the Release Notes for Cardano Node 1.29.0