If you recall, a RedeemerScript is a piece of data that is sent along with a collectFromScript
call. It ends up being used in the ValidatorScript as the first input. We will be writing our own in this section.
Similar to the DataScript, creating a RedeemerScript is nearly identical. Let’s look at our current withdraw function.
1 2 | withdrawADA :: MockWallet () withdrawADA = collectFromScript myFirstValidator unitRedeemer |
First, let’s add the ability to input a PIN number when calling withdrawADA via the Plutus Playground.
1 2 | withdrawADA :: Int -> MockWallet () withdrawADA pin = collectFromScript myFirstValidator unitRedeemer |
Now we’ll build the RedeemerScript using the submitted PIN number and the RedeemerScript
constructor.
1 2 | withdrawADA :: Int -> MockWallet () withdrawADA pin = collectFromScript myFirstValidator (RedeemerScript (lifted pin) ) |
The whole process is pretty much the same as building our DataScript in the previous section.
Continuing, we will also add the submitted PIN number as input to our ValidatorScript.
1 2 3 | myFirstValidator :: ValidatorScript myFirstValidator = ValidatorScript (fromCompiledCode $$(PlutusTx.compile [|| \(submittedPIN :: Int) (myPIN :: Int) (c :: ()) -> () ||])) |
And that concludes implementing our RedeemerScript.
But we are not done yet. To end this section off, we will also specify the final input to our smart contract. However, we must add one more import before we get there.
1 | import Ledger.Validation |
Now we can specify the input.
1 2 3 | myFirstValidator :: ValidatorScript myFirstValidator = ValidatorScript (fromCompiledCode $$(PlutusTx.compile [|| \(submittedPIN :: Int) (myPIN :: Int) (p :: PendingTx') -> () ||])) |
As you can see, the final input is of the type PendingTx'
. This is the pending transaction tied to the running of the smart contract. It contains various pieces of data including block height, transaction fee, inputs, outputs, etc. In this current lesson we won’t be using any of it, however it is good to know that it is available for you to use and play around with in the future.
Here is the compilation of what we’ve done so far.
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 28 | module MyFirstPlutusSmartContract where import qualified Language.PlutusTx as PlutusTx import Ledger import Wallet import Ledger.Validation import Playground.Contract myFirstValidator :: ValidatorScript myFirstValidator = ValidatorScript (fromCompiledCode $$(PlutusTx.compile [|| \(submittedPIN :: Int) (myPIN :: Int) (p :: PendingTx') -> () ||])) smartContractAddress :: Address' smartContractAddress = scriptAddress myFirstValidator watchSmartContract :: MockWallet () watchSmartContract = startWatching smartContractAddress depositADA :: Int -> Value -> MockWallet () depositADA pin val = payToScript_ smartContractAddress val (DataScript (lifted pin)) withdrawADA :: Int -> MockWallet () withdrawADA pin = collectFromScript myFirstValidator (RedeemerScript (lifted pin)) $(mkFunction 'watchSmartContract) $(mkFunction 'depositADA) $(mkFunction 'withdrawADA) |
Test it out for yourself, make sure it compiles, and try using the new withdrawADA
UI. In the next section, we will finally be writing our smart contract logic and locking deposited ada with a PIN number.