7

Question for Plutus Pioneer cohort 3 Q&A week 1

I'm new to Plutus dev and trying to work out where the datum value is actually stored in a typical Plutus application.

From various sources (docs/blogs/videos) it seems that the value can be stored in the EUTxO or provided in the Tx (from the off-chain Tx creation code)?

I understand that initially the datum is provided in the Tx when the first script EUTxO is created, but when the datum is updated after the mechanics of querying/updating the datum are confusing/unclear. Some of the sources I've looked at use code to explain what's happening, but I'm not yet that skilled with Haskell so they don't help.

Can someone walk through an example or two and clarify where the data value comes from and where it is stored?

For example (with my limited understanding), it seems like in the EnglishAuction example the datum could be actually stored in the EUTxO (with the first Tx) - not just a hash of the datum - and then when future Tx's are created (by off-chain code) the Plutus app code would read this datum value from the EUTxO, update it and pass it with the new Tx.

First, is this correct? Or does it work differently?

This interpretation sort of makes sense, but how does this relate/work with the Datum hash that people/docs say is stored in the EUTxO?

Also the EnglishAuction example seems to make sense where there's only one script EUTxO at any time (for a script instance), but how does this work in applications where the applications state is split across multiple EUTxOs (multiple datums - fragmented state)?

1 Answer 1

3

This was Lars response to this question in the ppp Q&A on 25/Jan/22. Recording timestamp 0:53:57

The datum is not stored in UTxO but in the transaction. Even if the datum was included in the transaction it is not completely trivial to get your hands on it. The Cardano node, for example, does not know it, the Cardano node sees it during validation but then sort of forgets about it, so you can't ask the node what's the datum for a transaction or a UTxO.

There are tools such as DbSync, which scans and writes all your blockchain transaction to a database, including the datum, so there is one way to get to the datum by hand.

Also the Plutus apps team has come up with a lightweight option of DbSync called chainindex, so that's exactly for that reason, also keeps track of all the datums.

There also 3rd party providers, blockfrost, a website where they run dbSync for you, you just do REST calls to their server, give a TX ID, or some reference UTxO and they give you the datum. It is stored in the transaction and somehow it disappears in the wherever the blockchain stores it on the machine.

If the datum was not stored with the transaction, then people that don't know it have no way of consuming this UTxO, if the person that created this UTxO, the default is to include just the hash of the datum then other people normally wouldn't be able to spend the UTxO, because in order to spend it you have to provide the Datum, in this case there must be another channel to communicate the datum. Maybe by design you don't want people to spend your UTxO, but if do you want them to spend it and you don't include the Datum just the datum hash, then you must put the datum on your website or something, so people is able to spend the UTxO.

Last question, I'm not too sure if I understand the question, if there are more than one instances:

Yes it can happen or also it should happen, that's one way of handling concurrency in Plutus, to do this: that you don't just rely only in one specific UTxO that carries all the state, you fragment the state and then you can achieve massive concurrency, but I'm not really sure of what the question is about how does it work? The stated is fragmented.

It depends on the specific example: in the auction example in the first iteration, there was a question of what happens if it is a popular auction and lots of people want to bid, in the way the example is written, there can only be one bid per block, so basically 3 bits per minute. Small auctions should be fine, but if it is highly contentious then maybe that's too slow and then you will have this concurrency issue because only one bid can successfully consume the current UTxO and produce a new one, so you can only have one bid per block in this setup.

One way to sort this issue is to split the auction into several, for example ten auction UTxOs, and if you want to make a bid you can do that on each of those, but then you wont know globally what's the highest bidder, each of the 10 could keep track of the highest bid that that one has seen, but it is not aware of the other, in that specific example, in the end, in the close, you would combine all of them and find out which one is the highest bid and then reimburse the others. but it is a specific example. It depends on your business case.

In the auction example you achieve concurrency but you need to recombine again. For a DEX for example, on a decentralized exchange, in Uniswap in Ethereum for one token pair they have one pool normally, and that would be horrible on Cardano because it would mean one swap per pair per block, so one idea would be to split the liquidity pools into several UTxOs and you may not need to recombine, they could happily coexist, each pool doing their own thing, it could be one option.

But it always depends on your use case, what fragmented state even means and whether it is feasible.

1
  • Thanks, this was helpful in understanding where ChainIndex comes from. It's not used in PPP iteration 2 (the code I'm referencing) but is used in the Plutus Starter project (what I'm using as a template for my projects). The plutus branch with ChainIndex is also not included in main yet, so it took me a while to find the right plutus commit to match my Plutus repo with the plutus-starter set up.
    – marcel_g
    Commented Apr 6, 2022 at 4:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.