Newbie questions about Plutus development

Hello everyone,
I’m a University student and I’m studying Haskell and Plutus in order to develop Smart Contracts for Cardano.

I’m trying to develop a smart contract similar to the Marlowe example but in Plutus: Bob sells a product, Alice wants to buy it and Carol decides who’s right between Bob and Alice if they don’t agree.

I understand that the Data Script (datum) is sent when the user pays to the contract and that the Redeemer Script is used by the user who tries to collect the money.

In this case, Alice starts with paying to the script the amount of money needed for buying the product. Then in any moment before the deadline she can say that she has received the product. In any moment Bob can say he has sent the product. If both agree, after the deadline Bob can collect the money.

I don’t understand how Alice could set the varibiable productReceived to True, ie. adding the variable to the data script belonging to the smart contract. Same problem with Bob setting the variable productSent to True.
Any explanation would be really appreciated!

1 Like

Update: my current idea to solve this situation is to create some endpoints that pay 0 money and send a custom datum from Alice and from Bob. Then to check if they agree, in the “collect” endpoint I check if these 2 transaction have the data set both to True.

How can I get the datum of an unspent output from inside a wallet endpoint?

Thank you!

I’m still not sure where I can find the information I’m looking for.

Is there any contract example or documentation that I can follow for retrieving the Datum of a transaction from a wallet?

Or maybe there’s a better way for handling this situation?

Thank you

@Lethal_Axel Great to see more people are exploring into UTXO-based contracts/Plutus. I don’t have too much time to spare, but I’ll try to help clarify how you would go about implementing your idea/how these contracts are supposed to work.

The datum is the on-chain data which stores the state of your smart contract. As such, whenever you wish to update the state, you need to allow the user to issue a tx which changes the datum. As such in your datum you would need productReceived and productSent values encoded in the data type.

For UTXO-based contracts, all changing of state data (therefore the datum) happens in your off-chain when you construct the tx. In the on-chain code, you simply check that the tx is valid. Thus your smart contract may have multiple “spending path” which are paths of logic which allow for the UTXO locked under said contract to perform an action/be spent.

Thus you would write in your ValidatorScript logic that checks to make sure that only Bob (his publickey) can change the productSent value in the datum, and only Alice can change productReceived. Each by spending the UTXO into the same contract address and writing their off-chain datum creation logic in endpoints.

4 Likes

Thank you @bobert for the insightful reply. [Name tag fixed by @RobJF]

I understood most of your answer, but 2 questions come from it:

  1. Is the datum only one for the whole smart contract or can you have one different datum for each transaction that puts coins into the contract?
  2. To update the datum you use transactions that pay to the script, but to use the Validator you can only do transactions that collect from the script (as the validator is called only when you try to collect). How can I change the datum and use the validator to be sure that only Bob can set productSent?

Thank you in advance!

EDIT: For the question number 2, are you suggesting that Bob should collect the money from the contract and spend them to the same contract address so he can be validated by the Validator and he can update the Data Script setting productSent to True?

  1. There will only be one definition of a datum per contract. Meaning that the values can change in the datum, but the type of the datum itself won’t. That said, for more complex UTXO-based dApps, you may even have multiple contracts working together, which is why some of us have begun using the term “smart contract protocols” to reference one or more contracts which spend into each other which define the protocol behind a given dApp.

  2. Your edit is correct. The way that more complex actions work in UTXO-based smart contract protocols is that you spend the utxo from address X back to address X again so the ValidatorScript (logic) can be evaluated and the Datum (state) can be updated as you described.

With the version of Plutus currently on the playground, I believe this isn’t very easy to do. In more recent versions of Plutus IOHK has created a better way to encode such smart contract protocols via state machines which build off of the building blocks you are working with right now. Essentially you write the state transitions (txs) of moving from one stage/state in the protocol to another (or back to the same state with just an updated datum for example).

Unfortunately I think if you’re interested in trying out the latest and greatest features of Plutus like this then you’ll have to clone the Plutus github repo and write Plutus code on the bleeding edge commits locally on your pc with a Haskell environment. Hopefully with Gougen nearing this will be soon made a lot easier, but nonetheless that is the situation at hand currently.

Hope that helped, and hope to keep seeing more from you in regards to Plutus especially as we get closer to mainnet launch :+1:

2 Likes

Thank you again for the reply @bobert .
I’m currently working only on the playground but I’ll surely play with the new features in a later time.

Regarding the point (2): the ValidatorScript has the form DataScript -> RedeemerScript -> PendigTx -> Bool. In this form DataScript is the Datum already contained in the contract, but for validating Bob’s action in the Validator I also need to check the new DataScript that Bob is trying to send, how can I check that from the Validator? I need to be sure Bob is not trying to change other variables…

Finally, how can I check the current Datum of a contract from a wallet?

I promise these are the last questions and thank you as always for your time and help!