Writing Your First Plutus Smart Contract

img

7) Writing Your First DataScript

The DataScript, as mentioned before, is any data which you wish to send to the smart contract which will be tied to your ada. In our case, it will be used to store a PIN number which will need to be verified in order to call collectFromScript successfully. In this section we will cover how to add the pin to the DataScript and send it with our payToScript_ call.

Let’s look back to what we currently have in our depositAda function.

1
2
depositADA :: Value -> MockWallet ()
depositADA val = payToScript_ smartContractAddress val unitData

As you can recall, we provided unitData as the DataScript, which is an empty one. To continue with our plan, we will construct a function that takes a PIN number from the user via the Plutus Playground UI.

1
2
depositADA :: Int -> Value -> MockWallet ()
depositADA pin val = payToScript_ smartContractAddress val unitData

We have now added an input to our function of the type Int and gave it the variable name pin. Thanks to how easy-to-use the Plutus Playground is, what we have written above will already cause the UI to change and add an extra input box for the PIN. (Note that you will have to delete your old depositADA Actions in your Action Sequence and replace them in order to have the new updated UI/function)

1
2
depositADA :: Int -> Value -> MockWallet ()
depositADA pin val = payToScript_ smartContractAddress val (DataScript (...) )

Continuing, we now are beginning to construct our DataScript which will replace the empty one we originally provided. We do this by using the DataScript constructor.

Next we need to feed the PIN number obtained from the UI to the constructor.

1
2
depositADA :: Int -> Value -> MockWallet ()
depositADA pin val = payToScript_ smartContractAddress val (DataScript (lifted pin) )

We have used the function lifted on the PIN in order to make the Int into a value of type Script. The constructor DataScript is now able to take our lifted PIN number as input. If this is a bit too complicated for you then you can ignore the specifics. All you need to remember is that when supplying data to a DataScript or RedeemerScript constructor, you first need to call lifted on the data you are providing (though you do need to make sure the data has an instance of the typeclass Lift).

The DataScript is now implemented. However there is one last addition we need to add to the ValidatorScript.

1
2
3
myFirstValidator :: ValidatorScript
myFirstValidator = ValidatorScript (fromCompiledCode $$(PlutusTx.compile
    [|| \(a :: ()) (myPIN :: Int) (c :: ()) -> ()  ||]))

The placeholder variable b has now had it’s name changed to our data, myPIN, and it’s type to Int. In our ValidatorScript, the DataScript is the 2nd input.

And with that, we have finished implementing our DataScript and taken it as input in our smart contract.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
module MyFirstPlutusSmartContract where

import qualified Language.PlutusTx            as PlutusTx
import           Ledger
import           Wallet
import           Playground.Contract


myFirstValidator :: ValidatorScript
myFirstValidator = ValidatorScript (fromCompiledCode $$(PlutusTx.compile
    [|| \(a :: ()) (myPIN :: Int) (c :: ()) -> ()  ||]))
   
smartContractAddress :: Address'
smartContractAddress = scriptAddress myFirstValidator

watchSmartContract :: MockWallet ()
watchSmartContract = startWatching smartContractAddress

depositADA :: Int -> Value -> MockWallet ()
depositADA pin val = payToScript_ smartContractAddress val (DataScript (lifted pin))

withdrawADA :: MockWallet ()
withdrawADA = collectFromScript myFirstValidator unitRedeemer

$(mkFunction 'watchSmartContract)
$(mkFunction 'depositADA)
$(mkFunction 'withdrawADA)

Try this code out for yourself in the Plutus Playground along with using the new depositADA function and the new UI that comes with it. In the next section we are going to write our first RedeemerScript.