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.